| OLD | NEW |
| 1 /* | 1 /* |
| 2 * GAS-compatible re2c lexer | 2 * GAS-compatible re2c lexer |
| 3 * | 3 * |
| 4 * Copyright (C) 2005-2007 Peter Johnson | 4 * Copyright (C) 2005-2007 Peter Johnson |
| 5 * | 5 * |
| 6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
| 7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
| 8 * are met: | 8 * are met: |
| 9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
| 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 28 * POSSIBILITY OF SUCH DAMAGE. | 28 * POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 #include <util.h> | 30 #include <util.h> |
| 31 RCSID("$Id: gas-token.re 2166 2009-01-02 08:33:21Z peter $"); | 31 RCSID("$Id: gas-token.re 2266 2010-01-03 22:02:30Z peter $"); |
| 32 | 32 |
| 33 #include <libyasm.h> | 33 #include <libyasm.h> |
| 34 | 34 |
| 35 #include "modules/parsers/gas/gas-parser.h" | 35 #include "modules/parsers/gas/gas-parser.h" |
| 36 | 36 |
| 37 | 37 |
| 38 #define BSIZE 8192 | 38 #define BSIZE 8192 |
| 39 | 39 |
| 40 #define YYCURSOR cursor | 40 #define YYCURSOR cursor |
| 41 #define YYLIMIT (s->lim) | 41 #define YYLIMIT (s->lim) |
| 42 #define YYMARKER (s->ptr) | 42 #define YYMARKER (s->ptr) |
| 43 #define YYFILL(n) {cursor = fill(parser_gas, cursor);} | 43 #define YYFILL(n) {cursor = fill(parser_gas, cursor);} |
| 44 | 44 |
| 45 #define RETURN(i) do {s->cur = cursor; parser_gas->tokch = s->tok[0]; \ | 45 #define RETURN(i) do {s->cur = cursor; parser_gas->tokch = s->tok[0]; \ |
| 46 return i;} while (0) | 46 return i;} while (0) |
| 47 | 47 |
| 48 #define SCANINIT() {s->tok = cursor;} | 48 #define SCANINIT() {s->tok = cursor;} |
| 49 | 49 |
| 50 #define TOK ((char *)s->tok) | 50 #define TOK ((char *)s->tok) |
| 51 #define TOKLEN (size_t)(cursor-s->tok) | 51 #define TOKLEN (size_t)(cursor-s->tok) |
| 52 | 52 |
| 53 static size_t | |
| 54 rept_input(yasm_parser_gas *parser_gas, /*@out@*/ YYCTYPE *buf, | |
| 55 size_t max_size) | |
| 56 { | |
| 57 gas_rept *rept = parser_gas->rept; | |
| 58 size_t numleft = max_size; | |
| 59 YYCTYPE *bufp = buf; | |
| 60 | |
| 61 /* If numrept is 0, copy out just the line end characters */ | |
| 62 if (rept->numrept == 0) { | |
| 63 /* Skip first line, which contains .line */ | |
| 64 rept->line = STAILQ_NEXT(rept->line, link); | |
| 65 if (!rept->line) { | |
| 66 rept->numrept = 1; | |
| 67 rept->numdone = 1; | |
| 68 } | |
| 69 while (rept->numrept == 0 && numleft > 0) { | |
| 70 *bufp++ = rept->line->data[rept->line->len-1]; | |
| 71 rept->line = STAILQ_NEXT(rept->line, link); | |
| 72 if (!rept->line) { | |
| 73 rept->numrept = 1; | |
| 74 rept->numdone = 1; | |
| 75 } | |
| 76 } | |
| 77 } | |
| 78 | |
| 79 /* Copy out the previous fill buffer until we're *really* done */ | |
| 80 if (rept->numdone == rept->numrept) { | |
| 81 size_t numcopy = rept->oldbuflen - rept->oldbufpos; | |
| 82 if (numcopy > numleft) | |
| 83 numcopy = numleft; | |
| 84 memcpy(bufp, &rept->oldbuf[rept->oldbufpos], numcopy); | |
| 85 numleft -= numcopy; | |
| 86 bufp += numcopy; | |
| 87 rept->oldbufpos += numcopy; | |
| 88 | |
| 89 if (rept->oldbufpos == rept->oldbuflen) { | |
| 90 /* Delete lines, then delete rept and clear rept state */ | |
| 91 gas_rept_line *cur, *next; | |
| 92 cur = STAILQ_FIRST(&rept->lines); | |
| 93 while (cur) { | |
| 94 next = STAILQ_NEXT(cur, link); | |
| 95 yasm_xfree(cur->data); | |
| 96 yasm_xfree(cur); | |
| 97 cur = next; | |
| 98 } | |
| 99 yasm_xfree(rept->oldbuf); | |
| 100 yasm_xfree(rept); | |
| 101 parser_gas->rept = NULL; | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 while (numleft > 0 && rept->numdone < rept->numrept) { | |
| 106 /* Copy from line data to buf */ | |
| 107 size_t numcopy = rept->line->len - rept->linepos; | |
| 108 if (numcopy > numleft) | |
| 109 numcopy = numleft; | |
| 110 memcpy(bufp, &rept->line->data[rept->linepos], numcopy); | |
| 111 numleft -= numcopy; | |
| 112 bufp += numcopy; | |
| 113 rept->linepos += numcopy; | |
| 114 | |
| 115 /* Update locations if needed */ | |
| 116 if (rept->linepos == rept->line->len) { | |
| 117 rept->line = STAILQ_NEXT(rept->line, link); | |
| 118 rept->linepos = 0; | |
| 119 } | |
| 120 if (rept->line == NULL) { | |
| 121 rept->numdone++; | |
| 122 rept->line = STAILQ_FIRST(&rept->lines); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 return (max_size-numleft); | |
| 127 } | |
| 128 | |
| 129 /* Bridge function to convert byte-oriented parser with line-oriented | 53 /* Bridge function to convert byte-oriented parser with line-oriented |
| 130 * preprocessor. | 54 * preprocessor. |
| 131 */ | 55 */ |
| 132 static size_t | 56 static size_t |
| 133 preproc_input(yasm_parser_gas *parser_gas, /*@out@*/ YYCTYPE *buf, | 57 preproc_input(yasm_parser_gas *parser_gas, /*@out@*/ YYCTYPE *buf, |
| 134 size_t max_size) | 58 size_t max_size) |
| 135 { | 59 { |
| 136 size_t tot=0; | 60 size_t tot=0; |
| 137 while (max_size > 0) { | 61 while (max_size > 0) { |
| 138 size_t n; | 62 size_t n; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 memcpy(buf, s->tok, (size_t)(s->lim - s->tok)); | 114 memcpy(buf, s->tok, (size_t)(s->lim - s->tok)); |
| 191 s->tok = buf; | 115 s->tok = buf; |
| 192 s->ptr = &buf[s->ptr - s->bot]; | 116 s->ptr = &buf[s->ptr - s->bot]; |
| 193 cursor = &buf[cursor - s->bot]; | 117 cursor = &buf[cursor - s->bot]; |
| 194 s->lim = &buf[s->lim - s->bot]; | 118 s->lim = &buf[s->lim - s->bot]; |
| 195 s->top = &s->lim[BSIZE]; | 119 s->top = &s->lim[BSIZE]; |
| 196 if (s->bot) | 120 if (s->bot) |
| 197 yasm_xfree(s->bot); | 121 yasm_xfree(s->bot); |
| 198 s->bot = buf; | 122 s->bot = buf; |
| 199 } | 123 } |
| 200 if (parser_gas->rept && parser_gas->rept->ended) { | 124 if((cnt = preproc_input(parser_gas, s->lim, BSIZE)) == 0) { |
| 201 /* Pull from rept lines instead of preproc */ | |
| 202 cnt = rept_input(parser_gas, s->lim, BSIZE); | |
| 203 } else if((cnt = preproc_input(parser_gas, s->lim, BSIZE)) == 0) { | |
| 204 s->eof = &s->lim[cnt]; *s->eof++ = '\n'; | 125 s->eof = &s->lim[cnt]; *s->eof++ = '\n'; |
| 205 } | 126 } |
| 206 s->lim += cnt; | 127 s->lim += cnt; |
| 207 if (first && parser_gas->save_input) { | 128 if (first && parser_gas->save_input) { |
| 208 int i; | 129 int i; |
| 209 YYCTYPE *saveline; | 130 YYCTYPE *saveline; |
| 210 parser_gas->save_last ^= 1; | 131 parser_gas->save_last ^= 1; |
| 211 saveline = parser_gas->save_line[parser_gas->save_last]; | 132 saveline = parser_gas->save_line[parser_gas->save_last]; |
| 212 /* save next line into cur_line */ | 133 /* save next line into cur_line */ |
| 213 for (i=0; i<79 && &s->tok[i] < s->lim && s->tok[i] != '\n'; i++) | 134 for (i=0; i<79 && &s->tok[i] < s->lim && s->tok[i] != '\n'; i++) |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 octdigit = [0-7]; | 185 octdigit = [0-7]; |
| 265 hexdigit = [0-9a-fA-F]; | 186 hexdigit = [0-9a-fA-F]; |
| 266 ws = [ \t\r]; | 187 ws = [ \t\r]; |
| 267 dquot = ["]; | 188 dquot = ["]; |
| 268 */ | 189 */ |
| 269 | 190 |
| 270 | 191 |
| 271 int | 192 int |
| 272 gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas) | 193 gas_parser_lex(YYSTYPE *lvalp, yasm_parser_gas *parser_gas) |
| 273 { | 194 { |
| 274 /*@null@*/ gas_rept *rept = parser_gas->rept; | |
| 275 yasm_scanner *s = &parser_gas->s; | 195 yasm_scanner *s = &parser_gas->s; |
| 276 YYCTYPE *cursor = s->cur; | 196 YYCTYPE *cursor = s->cur; |
| 277 size_t count; | 197 size_t count; |
| 278 YYCTYPE savech; | 198 YYCTYPE savech; |
| 279 int linestart; | |
| 280 gas_rept_line *new_line; | |
| 281 | 199 |
| 282 /* Handle one token of lookahead */ | 200 /* Handle one token of lookahead */ |
| 283 if (parser_gas->peek_token != NONE) { | 201 if (parser_gas->peek_token != NONE) { |
| 284 int tok = parser_gas->peek_token; | 202 int tok = parser_gas->peek_token; |
| 285 *lvalp = parser_gas->peek_tokval; /* structure copy */ | 203 *lvalp = parser_gas->peek_tokval; /* structure copy */ |
| 286 parser_gas->tokch = parser_gas->peek_tokch; | 204 parser_gas->tokch = parser_gas->peek_tokch; |
| 287 parser_gas->peek_token = NONE; | 205 parser_gas->peek_token = NONE; |
| 288 return tok; | 206 return tok; |
| 289 } | 207 } |
| 290 | 208 |
| 291 /* Catch EOF */ | 209 /* Catch EOF */ |
| 292 if (s->eof && cursor == s->eof) | 210 if (s->eof && cursor == s->eof) |
| 293 return 0; | 211 return 0; |
| 294 | 212 |
| 295 /* Handle rept */ | |
| 296 if (rept && !rept->ended) | |
| 297 goto rept_directive; | |
| 298 | |
| 299 /* Jump to proper "exclusive" states */ | 213 /* Jump to proper "exclusive" states */ |
| 300 switch (parser_gas->state) { | 214 switch (parser_gas->state) { |
| 301 case COMMENT: | 215 case COMMENT: |
| 302 goto comment; | 216 goto comment; |
| 303 case SECTION_DIRECTIVE: | 217 case SECTION_DIRECTIVE: |
| 304 goto section_directive; | 218 goto section_directive; |
| 305 case NASM_FILENAME: | 219 case NASM_FILENAME: |
| 306 goto nasm_filename; | 220 goto nasm_filename; |
| 307 default: | 221 default: |
| 308 break; | 222 break; |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 } | 387 } |
| 474 | 388 |
| 475 "/*" { parser_gas->state = COMMENT; goto comment; } | 389 "/*" { parser_gas->state = COMMENT; goto comment; } |
| 476 "#" { | 390 "#" { |
| 477 if (parser_gas->is_cpp_preproc) | 391 if (parser_gas->is_cpp_preproc) |
| 478 { | 392 { |
| 479 RETURN(CPP_LINE_MARKER); | 393 RETURN(CPP_LINE_MARKER); |
| 480 } else | 394 } else |
| 481 goto line_comment; | 395 goto line_comment; |
| 482 } | 396 } |
| 397 "//" { goto line_comment; } |
| 483 | 398 |
| 484 ws+ { goto scan; } | 399 ws+ { goto scan; } |
| 485 | 400 |
| 486 "\n" { | 401 "\n" { |
| 487 if (parser_gas->save_input) | 402 if (parser_gas->save_input) |
| 488 cursor = save_line(parser_gas, cursor); | 403 cursor = save_line(parser_gas, cursor); |
| 489 parser_gas->state = INITIAL; | 404 parser_gas->state = INITIAL; |
| 490 RETURN(s->tok[0]); | 405 RETURN(s->tok[0]); |
| 491 } | 406 } |
| 492 | 407 |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 yasm_error_set(YASM_ERROR_SYNTAX, | 549 yasm_error_set(YASM_ERROR_SYNTAX, |
| 635 N_("unexpected end of file in string")); | 550 N_("unexpected end of file in string")); |
| 636 lvalp->str.contents = (char *)strbuf; | 551 lvalp->str.contents = (char *)strbuf; |
| 637 lvalp->str.len = count; | 552 lvalp->str.len = count; |
| 638 RETURN(STRING); | 553 RETURN(STRING); |
| 639 } | 554 } |
| 640 strbuf_append(count++, cursor, s, s->tok[0]); | 555 strbuf_append(count++, cursor, s, s->tok[0]); |
| 641 goto stringconst_scan; | 556 goto stringconst_scan; |
| 642 } | 557 } |
| 643 */ | 558 */ |
| 644 | |
| 645 rept_directive: | |
| 646 strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE); | |
| 647 strbuf_size = STRBUF_ALLOC_SIZE; | |
| 648 count = 0; | |
| 649 linestart = 1; | |
| 650 | |
| 651 | |
| 652 rept_scan: | |
| 653 SCANINIT(); | |
| 654 | |
| 655 /*!re2c | |
| 656 [\n;] { | |
| 657 /* Line ending, save in lines */ | |
| 658 new_line = yasm_xmalloc(sizeof(gas_rept_line)); | |
| 659 if (cursor == s->eof) { | |
| 660 yasm_xfree(strbuf); | |
| 661 return 0; | |
| 662 } | |
| 663 strbuf_append(count++, cursor, s, s->tok[0]); | |
| 664 new_line->data = strbuf; | |
| 665 new_line->len = count; | |
| 666 STAILQ_INSERT_TAIL(&rept->lines, new_line, link); | |
| 667 /* Allocate new strbuf */ | |
| 668 strbuf = yasm_xmalloc(STRBUF_ALLOC_SIZE); | |
| 669 strbuf_size = STRBUF_ALLOC_SIZE; | |
| 670 count = 0; | |
| 671 /* Mark start of line */ | |
| 672 linestart = 1; | |
| 673 goto rept_scan; | |
| 674 } | |
| 675 '.rept' { | |
| 676 int i; | |
| 677 if (linestart) { | |
| 678 /* We don't support nested right now, error */ | |
| 679 yasm_error_set(YASM_ERROR_GENERAL, | |
| 680 N_("nested rept not supported")); | |
| 681 yasm_errwarn_propagate(parser_gas->errwarns, cur_line); | |
| 682 } | |
| 683 for (i=0; i<6; i++) | |
| 684 strbuf_append(count++, cursor, s, s->tok[i]); | |
| 685 goto rept_scan; | |
| 686 } | |
| 687 '.endr' { | |
| 688 if (linestart) { | |
| 689 /* We're done, kick off the main lexer */ | |
| 690 rept->line = STAILQ_FIRST(&rept->lines); | |
| 691 if (!rept->line) { | |
| 692 /* Didn't get any intervening data? Empty repeat, so | |
| 693 * don't even bother. | |
| 694 */ | |
| 695 yasm_xfree(strbuf); | |
| 696 yasm_xfree(rept); | |
| 697 parser_gas->rept = NULL; | |
| 698 } else { | |
| 699 rept->ended = 1; | |
| 700 | |
| 701 /* Add .line as first line to get line numbers correct */ | |
| 702 new_line = yasm_xmalloc(sizeof(gas_rept_line)); | |
| 703 new_line->data = yasm_xmalloc(40); | |
| 704 sprintf((char *)new_line->data, ".line %lu;", | |
| 705 rept->startline+1); | |
| 706 new_line->len = strlen((char *)new_line->data); | |
| 707 STAILQ_INSERT_HEAD(&rept->lines, new_line, link); | |
| 708 | |
| 709 /* Save previous fill buffer */ | |
| 710 rept->oldbuf = parser_gas->s.bot; | |
| 711 rept->oldbuflen = s->lim - s->bot; | |
| 712 rept->oldbufpos = cursor - s->bot; | |
| 713 | |
| 714 /* Reset fill */ | |
| 715 s->bot = NULL; | |
| 716 s->tok = NULL; | |
| 717 s->ptr = NULL; | |
| 718 s->cur = NULL; | |
| 719 s->lim = NULL; | |
| 720 s->top = NULL; | |
| 721 s->eof = NULL; | |
| 722 cursor = NULL; | |
| 723 YYFILL(1); | |
| 724 } | |
| 725 | |
| 726 goto scan; | |
| 727 } else { | |
| 728 int i; | |
| 729 for (i=0; i<6; i++) | |
| 730 strbuf_append(count++, cursor, s, s->tok[i]); | |
| 731 goto rept_scan; | |
| 732 } | |
| 733 } | |
| 734 | |
| 735 any { | |
| 736 if (cursor == s->eof) { | |
| 737 yasm_xfree(strbuf); | |
| 738 return 0; | |
| 739 } | |
| 740 strbuf_append(count++, cursor, s, s->tok[0]); | |
| 741 linestart = 0; | |
| 742 goto rept_scan; | |
| 743 } | |
| 744 */ | |
| 745 | |
| 746 } | 559 } |
| OLD | NEW |