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 */ 55static YYCTYPE *strbuf = NULL; 56 57/* length of strbuf (including terminating NULL character) */ 58static size_t strbuf_size = 0; 59 60static 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 73static int 74handle_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 115int 116nasm_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 153scan: 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 */ 511linechg: 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 548linechg2: 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] */ 566directive: 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) */ 593section_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 */ 628directive2: 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 */ 736stringconst: 737 strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE); 738 strbuf_size = STRBUF_ALLOC_SIZE; 739 count = 0; 740 741stringconst_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 783stringconst_error: 784 yasm_error_set(YASM_ERROR_SYNTAX, N_("unterminated string")); 785 786stringconst_end: 787 strbuf[count] = '\0'; 788 lvalp->str.contents = (char *)strbuf; 789 lvalp->str.len = count; 790 RETURN(STRING); 791 792endofinput: 793 parser_nasm->state = INITIAL; 794 RETURN(s->tok[0]); 795} 796