Home | History | Annotate | Download | only in nasm
      1 /*
      2  * NASM-compatible re2c lexer
      3  *
      4  *  Copyright (C) 2001-2007  Peter Johnson
      5  *
      6  *  Portions based on re2c's example code.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 #include <util.h>
     30 
     31 #include <libyasm.h>
     32 
     33 #include "modules/parsers/nasm/nasm-parser.h"
     34 #include "modules/preprocs/nasm/nasm.h"
     35 
     36 
     37 #define YYCURSOR        cursor
     38 #define YYLIMIT         (s->lim)
     39 #define YYMARKER        (s->ptr)
     40 #define YYFILL(n)       {}
     41 
     42 #define RETURN(i)       {s->cur = cursor; parser_nasm->tokch = s->tok[0]; \
     43                          return i;}
     44 
     45 #define SCANINIT()      {s->tok = cursor;}
     46 
     47 #define TOK             ((char *)s->tok)
     48 #define TOKLEN          (size_t)(cursor-s->tok)
     49 
     50 
     51 /* starting size of string buffer */
     52 #define STRBUF_ALLOC_SIZE       128
     53 
     54 /* string buffer used when parsing strings/character constants */
     55 static YYCTYPE *strbuf = NULL;
     56 
     57 /* length of strbuf (including terminating NULL character) */
     58 static size_t strbuf_size = 0;
     59 
     60 static int linechg_numcount;
     61 
     62 /*!re2c
     63   any = [\001-\377];
     64   digit = [0-9];
     65   iletter = [a-zA-Z];
     66   bindigit = [01_];
     67   octdigit = [0-7_];
     68   hexdigit = [0-9a-fA-F_];
     69   ws = [ \t\r];
     70   quot = ["'];
     71 */
     72 
     73 static int
     74 handle_dot_label(YYSTYPE *lvalp, char *tok, size_t toklen, size_t zeropos,
     75                  yasm_parser_nasm *parser_nasm)
     76 {
     77     /* check for special non-local labels like ..start */
     78     if (tok[zeropos+1] == '.') {
     79         lvalp->str_val = yasm__xstrndup(tok+zeropos+(parser_nasm->tasm?2:0),
     80             toklen-zeropos-(parser_nasm->tasm?2:0));
     81         /* check for special non-local ..@label */
     82         if (lvalp->str_val[zeropos+2] == '@')
     83             return NONLOCAL_ID;
     84         return SPECIAL_ID;
     85     }
     86     if (parser_nasm->masm && tok[zeropos] == '.') {
     87         lvalp->str_val = yasm__xstrndup(tok + zeropos, toklen - zeropos);
     88         return SPECIAL_ID;
     89     }
     90     if (parser_nasm->tasm && (!tasm_locals ||
     91                 (tok[zeropos] == '.' &&
     92                  tok[zeropos+1] != '@' && tok[zeropos+2] != '@'))) {
     93         /* no locals on Tasm without the 'locals' directive */
     94         /* .foo is never local either, but .@@foo may be (local structure
     95          * members) */
     96         lvalp->str_val = yasm__xstrndup(tok + zeropos, toklen - zeropos);
     97         return SPECIAL_ID;
     98     }
     99     if (!parser_nasm->locallabel_base) {
    100         lvalp->str_val = yasm__xstrndup(tok+zeropos, toklen-zeropos);
    101         yasm_warn_set(YASM_WARN_GENERAL,
    102                       N_("no non-local label before `%s'"),
    103                       lvalp->str_val);
    104     } else {
    105         size_t len = toklen - zeropos + parser_nasm->locallabel_base_len;
    106         lvalp->str_val = yasm_xmalloc(len + 1);
    107         strcpy(lvalp->str_val, parser_nasm->locallabel_base);
    108         strncat(lvalp->str_val, tok+zeropos, toklen-zeropos);
    109         lvalp->str_val[len] = '\0';
    110     }
    111 
    112     return LOCAL_ID;
    113 }
    114 
    115 int
    116 nasm_parser_lex(YYSTYPE *lvalp, yasm_parser_nasm *parser_nasm)
    117 {
    118     yasm_scanner *s = &parser_nasm->s;
    119     YYCTYPE *cursor = s->cur;
    120     YYCTYPE endch;
    121     size_t count;
    122     YYCTYPE savech;
    123 
    124     /* Handle one token of lookahead */
    125     if (parser_nasm->peek_token != NONE) {
    126         int tok = parser_nasm->peek_token;
    127         *lvalp = parser_nasm->peek_tokval;  /* structure copy */
    128         parser_nasm->tokch = parser_nasm->peek_tokch;
    129         parser_nasm->peek_token = NONE;
    130         return tok;
    131     }
    132 
    133     /* Catch EOL (EOF from the scanner perspective) */
    134     if (s->eof && cursor == s->eof)
    135         return 0;
    136 
    137     /* Jump to proper "exclusive" states */
    138     switch (parser_nasm->state) {
    139         case DIRECTIVE:
    140             goto directive;
    141         case SECTION_DIRECTIVE:
    142             goto section_directive;
    143         case DIRECTIVE2:
    144             goto directive2;
    145         case LINECHG:
    146             goto linechg;
    147         case LINECHG2:
    148             goto linechg2;
    149         default:
    150             break;
    151     }
    152 
    153 scan:
    154     SCANINIT();
    155     if (*cursor == '\0')
    156         goto endofinput;
    157 
    158     /*!re2c
    159         /* standard decimal integer */
    160         digit+ {
    161             savech = s->tok[TOKLEN];
    162             s->tok[TOKLEN] = '\0';
    163             lvalp->intn = yasm_intnum_create_dec(TOK);
    164             s->tok[TOKLEN] = savech;
    165             RETURN(INTNUM);
    166         }
    167         /* 10010011b - binary number */
    168 
    169         [01] bindigit* 'b' {
    170             s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
    171             lvalp->intn = yasm_intnum_create_bin(TOK);
    172             RETURN(INTNUM);
    173         }
    174 
    175         /* 777q or 777o - octal number */
    176         [0-7] octdigit* [qQoO] {
    177             s->tok[TOKLEN-1] = '\0'; /* strip off 'q' or 'o' */
    178             lvalp->intn = yasm_intnum_create_oct(TOK);
    179             RETURN(INTNUM);
    180         }
    181 
    182         /* 0AAh form of hexidecimal number */
    183         digit hexdigit* 'h' {
    184             s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
    185             lvalp->intn = yasm_intnum_create_hex(TOK);
    186             RETURN(INTNUM);
    187         }
    188 
    189         /* $0AA and 0xAA forms of hexidecimal number */
    190         (("$" digit) | '0x') hexdigit+ {
    191             savech = s->tok[TOKLEN];
    192             s->tok[TOKLEN] = '\0';
    193             if (s->tok[1] == 'x' || s->tok[1] == 'X')
    194                 /* skip 0 and x */
    195                 lvalp->intn = yasm_intnum_create_hex(TOK+2);
    196             else
    197                 /* don't skip 0 */
    198                 lvalp->intn = yasm_intnum_create_hex(TOK+1);
    199             s->tok[TOKLEN] = savech;
    200             RETURN(INTNUM);
    201         }
    202 
    203         /* floating point value */
    204         digit+ "." digit* ('e' [-+]? digit+)? {
    205             savech = s->tok[TOKLEN];
    206             s->tok[TOKLEN] = '\0';
    207             lvalp->flt = yasm_floatnum_create(TOK);
    208             s->tok[TOKLEN] = savech;
    209             RETURN(FLTNUM);
    210         }
    211 
    212         /* string/character constant values */
    213         quot {
    214             endch = s->tok[0];
    215             goto stringconst;
    216         }
    217 
    218         /* %line linenum+lineinc filename */
    219         "%line" {
    220             parser_nasm->state = LINECHG;
    221             linechg_numcount = 0;
    222             RETURN(LINE);
    223         }
    224 
    225         /* size specifiers */
    226         'byte'          { lvalp->int_info = 8; RETURN(SIZE_OVERRIDE); }
    227         'hword'         {
    228             lvalp->int_info = yasm_arch_wordsize(p_object->arch)/2;
    229             RETURN(SIZE_OVERRIDE);
    230         }
    231         'word'          {
    232             lvalp->int_info = yasm_arch_wordsize(p_object->arch);
    233             RETURN(SIZE_OVERRIDE);
    234         }
    235         'dword' | 'long'        {
    236             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
    237             RETURN(SIZE_OVERRIDE);
    238         }
    239         'qword'         {
    240             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*4;
    241             RETURN(SIZE_OVERRIDE);
    242         }
    243         'tword'         { lvalp->int_info = 80; RETURN(SIZE_OVERRIDE); }
    244         'dqword'        {
    245             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    246             RETURN(SIZE_OVERRIDE);
    247         }
    248         'oword'        {
    249             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    250             RETURN(SIZE_OVERRIDE);
    251         }
    252         'yword'        {
    253             lvalp->int_info = 256;
    254             RETURN(SIZE_OVERRIDE);
    255         }
    256 
    257         /* pseudo-instructions */
    258         'db'            {
    259             lvalp->int_info = 8;
    260             parser_nasm->state = INSTRUCTION;
    261             RETURN(DECLARE_DATA);
    262         }
    263         'dhw'           {
    264             lvalp->int_info = yasm_arch_wordsize(p_object->arch)/2;
    265             parser_nasm->state = INSTRUCTION;
    266             RETURN(DECLARE_DATA);
    267         }
    268         'dw'            {
    269             lvalp->int_info = yasm_arch_wordsize(p_object->arch);
    270             parser_nasm->state = INSTRUCTION;
    271             RETURN(DECLARE_DATA);
    272         }
    273         'dd'            {
    274             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
    275             parser_nasm->state = INSTRUCTION;
    276             RETURN(DECLARE_DATA);
    277         }
    278         'dq'            {
    279             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*4;
    280             parser_nasm->state = INSTRUCTION;
    281             RETURN(DECLARE_DATA);
    282         }
    283         'dt'            {
    284             lvalp->int_info = 80;
    285             parser_nasm->state = INSTRUCTION;
    286             RETURN(DECLARE_DATA);
    287         }
    288         'ddq'           {
    289             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    290             parser_nasm->state = INSTRUCTION;
    291             RETURN(DECLARE_DATA);
    292         }
    293         'do'           {
    294             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    295             parser_nasm->state = INSTRUCTION;
    296             RETURN(DECLARE_DATA);
    297         }
    298         'dy'           {
    299             lvalp->int_info = 256;
    300             parser_nasm->state = INSTRUCTION;
    301             RETURN(DECLARE_DATA);
    302         }
    303 
    304         'resb'          {
    305             lvalp->int_info = 8;
    306             parser_nasm->state = INSTRUCTION;
    307             RETURN(RESERVE_SPACE);
    308         }
    309         'reshw'         {
    310             lvalp->int_info = yasm_arch_wordsize(p_object->arch)/2;
    311             parser_nasm->state = INSTRUCTION;
    312             RETURN(RESERVE_SPACE);
    313         }
    314         'resw'          {
    315             lvalp->int_info = yasm_arch_wordsize(p_object->arch);
    316             parser_nasm->state = INSTRUCTION;
    317             RETURN(RESERVE_SPACE);
    318         }
    319         'resd'          {
    320             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
    321             parser_nasm->state = INSTRUCTION;
    322             RETURN(RESERVE_SPACE);
    323         }
    324         'resq'          {
    325             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*4;
    326             parser_nasm->state = INSTRUCTION;
    327             RETURN(RESERVE_SPACE);
    328         }
    329         'rest'          {
    330             lvalp->int_info = 80;
    331             parser_nasm->state = INSTRUCTION;
    332             RETURN(RESERVE_SPACE);
    333         }
    334         'resdq'         {
    335             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    336             parser_nasm->state = INSTRUCTION;
    337             RETURN(RESERVE_SPACE);
    338         }
    339         'reso'         {
    340             lvalp->int_info = yasm_arch_wordsize(p_object->arch)*8;
    341             parser_nasm->state = INSTRUCTION;
    342             RETURN(RESERVE_SPACE);
    343         }
    344         'resy'         {
    345             lvalp->int_info = 256;
    346             parser_nasm->state = INSTRUCTION;
    347             RETURN(RESERVE_SPACE);
    348         }
    349 
    350         'incbin'        { RETURN(INCBIN); }
    351 
    352         'equ'           { RETURN(EQU); }
    353 
    354         'times'         { RETURN(TIMES); }
    355 
    356         'seg'           { RETURN(SEG); }
    357         'wrt'           { RETURN(WRT); }
    358 
    359         'abs'           { RETURN(ABS); }
    360         'rel'           { RETURN(REL); }
    361 
    362         'nosplit'       { RETURN(NOSPLIT); }
    363         'strict'        { RETURN(STRICT); }
    364 
    365         /* operators */
    366         "<<"                    { RETURN(LEFT_OP); }
    367         ">>"                    { RETURN(RIGHT_OP); }
    368         "//"                    { RETURN(SIGNDIV); }
    369         "%%"                    { RETURN(SIGNMOD); }
    370         "$$"                    { RETURN(START_SECTION_ID); }
    371         [-+|^*&/%~$():=,\[?]    { RETURN(s->tok[0]); }
    372         "]"                     { RETURN(s->tok[0]); }
    373 
    374         /* local label (.label) */
    375         ("." | "@@") [a-zA-Z0-9_$#@~.?]+ {
    376             RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 0, parser_nasm));
    377         }
    378 
    379         /* forced identifier */
    380         "$" [a-zA-Z0-9_$#@~.?]+ {
    381             if (TOK[1] == '.' ||
    382                     (parser_nasm->tasm && TOK[1] == '@' && TOK[2] == '@')) {
    383                 /* handle like .label */
    384                 RETURN(handle_dot_label(lvalp, TOK, TOKLEN, 1, parser_nasm));
    385             }
    386             lvalp->str_val = yasm__xstrndup(TOK+1, TOKLEN-1);
    387             RETURN(ID);
    388         }
    389 
    390         /* identifier that may be a register, instruction, etc. */
    391         [a-zA-Z_?@][a-zA-Z0-9_$#@~.?]* {
    392             savech = s->tok[TOKLEN];
    393             s->tok[TOKLEN] = '\0';
    394             if (parser_nasm->state != INSTRUCTION) {
    395                 uintptr_t prefix;
    396                 switch (yasm_arch_parse_check_insnprefix
    397                         (p_object->arch, TOK, TOKLEN, cur_line, &lvalp->bc,
    398                          &prefix)) {
    399                     case YASM_ARCH_INSN:
    400                         parser_nasm->state = INSTRUCTION;
    401                         s->tok[TOKLEN] = savech;
    402                         RETURN(INSN);
    403                     case YASM_ARCH_PREFIX:
    404                         lvalp->arch_data = prefix;
    405                         s->tok[TOKLEN] = savech;
    406                         RETURN(PREFIX);
    407                     default:
    408                         break;
    409                 }
    410             }
    411             switch (yasm_arch_parse_check_regtmod
    412                     (p_object->arch, TOK, TOKLEN, &lvalp->arch_data)) {
    413                 case YASM_ARCH_REG:
    414                     s->tok[TOKLEN] = savech;
    415                     RETURN(REG);
    416                 case YASM_ARCH_SEGREG:
    417                     s->tok[TOKLEN] = savech;
    418                     RETURN(SEGREG);
    419                 case YASM_ARCH_TARGETMOD:
    420                     s->tok[TOKLEN] = savech;
    421                     RETURN(TARGETMOD);
    422                 case YASM_ARCH_REGGROUP:
    423                     if (parser_nasm->masm) {
    424                         s->tok[TOKLEN] = savech;
    425                         RETURN(REGGROUP);
    426                     }
    427                 default:
    428                     break;
    429             }
    430             if (parser_nasm->masm) {
    431                if (!yasm__strcasecmp(TOK, "offset")) {
    432                     s->tok[TOKLEN] = savech;
    433                     RETURN(OFFSET);
    434                 }
    435             } else if (parser_nasm->tasm) {
    436                 if (!yasm__strcasecmp(TOK, "shl")) {
    437                     s->tok[TOKLEN] = savech;
    438                     RETURN(LEFT_OP);
    439                 }
    440                 if (!yasm__strcasecmp(TOK, "shr")) {
    441                     s->tok[TOKLEN] = savech;
    442                     RETURN(RIGHT_OP);
    443                 }
    444                 if (!yasm__strcasecmp(TOK, "and")) {
    445                     s->tok[TOKLEN] = savech;
    446                     RETURN('&');
    447                 }
    448                 if (!yasm__strcasecmp(TOK, "or")) {
    449                     s->tok[TOKLEN] = savech;
    450                     RETURN('|');
    451                 }
    452                 if (!yasm__strcasecmp(TOK, "not")) {
    453                     s->tok[TOKLEN] = savech;
    454                     RETURN('~');
    455                 }
    456                 if (!yasm__strcasecmp(TOK, "low")) {
    457                     s->tok[TOKLEN] = savech;
    458                     RETURN(LOW);
    459                 }
    460                 if (!yasm__strcasecmp(TOK, "high")) {
    461                     s->tok[TOKLEN] = savech;
    462                     RETURN(HIGH);
    463                 }
    464                 if (!yasm__strcasecmp(TOK, "offset")) {
    465                     s->tok[TOKLEN] = savech;
    466                     RETURN(OFFSET);
    467                 }
    468                 if (!yasm__strcasecmp(TOK, "fword")) {
    469                     s->tok[TOKLEN] = savech;
    470                     lvalp->int_info = yasm_arch_wordsize(p_object->arch)*2;
    471                     RETURN(SIZE_OVERRIDE);
    472                 }
    473                 if (!yasm__strcasecmp(TOK, "df")) {
    474                     s->tok[TOKLEN] = savech;
    475                     lvalp->int_info = yasm_arch_wordsize(p_object->arch)*3;
    476                     parser_nasm->state = INSTRUCTION;
    477                     RETURN(DECLARE_DATA);
    478                 }
    479                 if (!yasm__strcasecmp(TOK, "label")) {
    480                     s->tok[TOKLEN] = savech;
    481                     RETURN(LABEL);
    482                 }
    483                 if (!yasm__strcasecmp(TOK, "dup")) {
    484                     s->tok[TOKLEN] = savech;
    485                     RETURN(DUP);
    486                 }
    487             }
    488             /* Propagate errors in case we got a warning from the arch */
    489             yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
    490             /* Just an identifier, return as such. */
    491             s->tok[TOKLEN] = savech;
    492             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
    493             RETURN(ID);
    494         }
    495 
    496         ";" (any \ [\000])*     { goto scan; }
    497 
    498         ws+                     { goto scan; }
    499 
    500         [\000]                  { goto endofinput; }
    501 
    502         any {
    503             yasm_warn_set(YASM_WARN_UNREC_CHAR,
    504                           N_("ignoring unrecognized character `%s'"),
    505                           yasm__conv_unprint(s->tok[0]));
    506             goto scan;
    507         }
    508     */
    509 
    510     /* %line linenum+lineinc filename */
    511 linechg:
    512     SCANINIT();
    513     if (*cursor == '\0')
    514         goto endofinput;
    515 
    516     /*!re2c
    517         digit+ {
    518             linechg_numcount++;
    519             savech = s->tok[TOKLEN];
    520             s->tok[TOKLEN] = '\0';
    521             lvalp->intn = yasm_intnum_create_dec(TOK);
    522             s->tok[TOKLEN] = savech;
    523             RETURN(INTNUM);
    524         }
    525 
    526         [\000] { goto endofinput; }
    527 
    528         "+" {
    529             RETURN(s->tok[0]);
    530         }
    531 
    532         ws+ {
    533             if (linechg_numcount == 2) {
    534                 parser_nasm->state = LINECHG2;
    535                 goto linechg2;
    536             }
    537             goto linechg;
    538         }
    539 
    540         any {
    541             yasm_warn_set(YASM_WARN_UNREC_CHAR,
    542                           N_("ignoring unrecognized character `%s'"),
    543                           yasm__conv_unprint(s->tok[0]));
    544             goto linechg;
    545         }
    546     */
    547 
    548 linechg2:
    549     SCANINIT();
    550     if (*cursor == '\0')
    551         goto endofinput;
    552 
    553     /*!re2c
    554         [\000] { goto endofinput; }
    555 
    556         "\r" { goto linechg2; }
    557 
    558         (any \ [\000])+ {
    559             parser_nasm->state = LINECHG;
    560             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
    561             RETURN(FILENAME);
    562         }
    563     */
    564 
    565     /* directive: [name value] */
    566 directive:
    567     SCANINIT();
    568     if (*cursor == '\0')
    569         goto endofinput;
    570 
    571     /*!re2c
    572         [\]\000] { goto endofinput; }
    573 
    574         [a-zA-Z_][a-zA-Z_0-9]* {
    575             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
    576             if (yasm__strcasecmp(lvalp->str_val, "section") == 0 ||
    577                 yasm__strcasecmp(lvalp->str_val, "segment") == 0)
    578                 parser_nasm->state = SECTION_DIRECTIVE;
    579             else
    580                 parser_nasm->state = DIRECTIVE2;
    581             RETURN(DIRECTIVE_NAME);
    582         }
    583 
    584         any {
    585             yasm_warn_set(YASM_WARN_UNREC_CHAR,
    586                           N_("ignoring unrecognized character `%s'"),
    587                           yasm__conv_unprint(s->tok[0]));
    588             goto directive;
    589         }
    590     */
    591 
    592     /* section directive (the section name portion thereof) */
    593 section_directive:
    594     SCANINIT();
    595     if (*cursor == '\0')
    596         goto endofinput;
    597 
    598     /*!re2c
    599         [a-zA-Z0-9_$#@~.?-]+ {
    600             lvalp->str.contents = yasm__xstrndup(TOK, TOKLEN);
    601             lvalp->str.len = TOKLEN;
    602             parser_nasm->state = DIRECTIVE2;
    603             RETURN(STRING);
    604         }
    605 
    606         quot            {
    607             parser_nasm->state = DIRECTIVE2;
    608             endch = s->tok[0];
    609             goto stringconst;
    610         }
    611 
    612         ws+             {
    613             parser_nasm->state = DIRECTIVE2;
    614             goto section_directive;
    615         }
    616 
    617         [\]\000]        { goto endofinput; }
    618 
    619         any {
    620             yasm_warn_set(YASM_WARN_UNREC_CHAR,
    621                           N_("ignoring unrecognized character `%s'"),
    622                           yasm__conv_unprint(s->tok[0]));
    623             goto section_directive;
    624         }
    625     */
    626 
    627     /* inner part of directive */
    628 directive2:
    629     SCANINIT();
    630     if (*cursor == '\0')
    631         goto endofinput;
    632 
    633     /*!re2c
    634         /* standard decimal integer */
    635         digit+ {
    636             savech = s->tok[TOKLEN];
    637             s->tok[TOKLEN] = '\0';
    638             lvalp->intn = yasm_intnum_create_dec(TOK);
    639             s->tok[TOKLEN] = savech;
    640             RETURN(INTNUM);
    641         }
    642         /* 10010011b - binary number */
    643 
    644         [01] bindigit* 'b' {
    645             s->tok[TOKLEN-1] = '\0'; /* strip off 'b' */
    646             lvalp->intn = yasm_intnum_create_bin(TOK);
    647             RETURN(INTNUM);
    648         }
    649 
    650         /* 777q or 777o - octal number */
    651         [0-7] octdigit* [qQoO] {
    652             s->tok[TOKLEN-1] = '\0'; /* strip off 'q' or 'o' */
    653             lvalp->intn = yasm_intnum_create_oct(TOK);
    654             RETURN(INTNUM);
    655         }
    656 
    657         /* 0AAh form of hexidecimal number */
    658         digit hexdigit* 'h' {
    659             s->tok[TOKLEN-1] = '\0'; /* strip off 'h' */
    660             lvalp->intn = yasm_intnum_create_hex(TOK);
    661             RETURN(INTNUM);
    662         }
    663 
    664         /* $0AA and 0xAA forms of hexidecimal number */
    665         (("$" digit) | '0x') hexdigit+ {
    666             savech = s->tok[TOKLEN];
    667             s->tok[TOKLEN] = '\0';
    668             if (s->tok[1] == 'x' || s->tok[1] == 'X')
    669                 /* skip 0 and x */
    670                 lvalp->intn = yasm_intnum_create_hex(TOK+2);
    671             else
    672                 /* don't skip 0 */
    673                 lvalp->intn = yasm_intnum_create_hex(TOK+1);
    674             s->tok[TOKLEN] = savech;
    675             RETURN(INTNUM);
    676         }
    677 
    678         /* string/character constant values */
    679         quot {
    680             endch = s->tok[0];
    681             goto stringconst;
    682         }
    683 
    684         /* operators */
    685         "<<"                    { RETURN(LEFT_OP); }
    686         ">>"                    { RETURN(RIGHT_OP); }
    687         "//"                    { RETURN(SIGNDIV); }
    688         "%%"                    { RETURN(SIGNMOD); }
    689         [-+|^*&/%~$():=,\[]     { RETURN(s->tok[0]); }
    690 
    691         /* handle ] for directives */
    692         "]"                     { goto endofinput; }
    693 
    694         /* forced identifier; within directive, don't strip '$', this is
    695          * handled later.
    696          */
    697         "$" [a-zA-Z0-9_$#@~.?]+ {
    698             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
    699             RETURN(ID);
    700         }
    701 
    702         /* identifier; within directive, no local label mechanism */
    703         [a-zA-Z_.?][a-zA-Z0-9_$#@~.?]* {
    704             savech = s->tok[TOKLEN];
    705             s->tok[TOKLEN] = '\0';
    706             switch (yasm_arch_parse_check_regtmod
    707                     (p_object->arch, TOK, TOKLEN, &lvalp->arch_data)) {
    708                 case YASM_ARCH_REG:
    709                     s->tok[TOKLEN] = savech;
    710                     RETURN(REG);
    711                 default:
    712                     s->tok[TOKLEN] = savech;
    713             }
    714             /* Propagate errors in case we got a warning from the arch */
    715             yasm_errwarn_propagate(parser_nasm->errwarns, cur_line);
    716             /* Just an identifier, return as such. */
    717             lvalp->str_val = yasm__xstrndup(TOK, TOKLEN);
    718             RETURN(ID);
    719         }
    720 
    721         ";" (any \ [\000])*     { goto directive2; }
    722 
    723         ws+                     { goto directive2; }
    724 
    725         [\000]                  { goto endofinput; }
    726 
    727         any {
    728             yasm_warn_set(YASM_WARN_UNREC_CHAR,
    729                           N_("ignoring unrecognized character `%s'"),
    730                           yasm__conv_unprint(s->tok[0]));
    731             goto scan;
    732         }
    733      */
    734 
    735     /* string/character constant values */
    736 stringconst:
    737     strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE);
    738     strbuf_size = STRBUF_ALLOC_SIZE;
    739     count = 0;
    740 
    741 stringconst_scan:
    742     SCANINIT();
    743     if (*cursor == '\0')
    744         goto stringconst_error;
    745 
    746     /*!re2c
    747         [\000]  { goto stringconst_error; }
    748 
    749         "''" | '""'     {
    750             if (endch != s->tok[0]) {
    751                 strbuf[count++] = s->tok[0];
    752                 if (count >= strbuf_size) {
    753                     strbuf = yasm_xrealloc(strbuf,
    754                                            strbuf_size + STRBUF_ALLOC_SIZE);
    755                     strbuf_size += STRBUF_ALLOC_SIZE;
    756                 }
    757             } else if (!parser_nasm->tasm) {
    758                 YYCURSOR--;
    759                 goto stringconst_end;
    760             }
    761             strbuf[count++] = s->tok[0];
    762             if (count >= strbuf_size) {
    763                 strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
    764                 strbuf_size += STRBUF_ALLOC_SIZE;
    765             }
    766             goto stringconst_scan;
    767         }
    768 
    769         any     {
    770             if (s->tok[0] == endch)
    771                 goto stringconst_end;
    772 
    773             strbuf[count++] = s->tok[0];
    774             if (count >= strbuf_size) {
    775                 strbuf = yasm_xrealloc(strbuf, strbuf_size + STRBUF_ALLOC_SIZE);
    776                 strbuf_size += STRBUF_ALLOC_SIZE;
    777             }
    778 
    779             goto stringconst_scan;
    780         }
    781     */
    782 
    783 stringconst_error:
    784     yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string"));
    785 
    786 stringconst_end:
    787     strbuf[count] = '\0';
    788     lvalp->str.contents = (char *)strbuf;
    789     lvalp->str.len = count;
    790     RETURN(STRING);
    791 
    792 endofinput:
    793     parser_nasm->state = INITIAL;
    794     RETURN(s->tok[0]);
    795 }
    796