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 |