]> granicus.if.org Git - re2c/commitdiff
- Added -t switch to force two pass generation.
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 16 Apr 2006 18:04:39 +0000 (18:04 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Sun, 16 Apr 2006 18:04:39 +0000 (18:04 +0000)
17 files changed:
CHANGELOG
bootstrap/scanner.cc
code.cc
globals.h
htdocs/index.html
htdocs/manual.html
main.cc
re2c.1.in
scanner.re
test/error13.c [new file with mode: 0755]
test/error13.re [new file with mode: 0755]
test/error13.t.c [new file with mode: 0755]
test/error13.t.re [new file with mode: 0755]
test/error14.c [new file with mode: 0755]
test/error14.re [new file with mode: 0755]
test/error14.t.c [new file with mode: 0755]
test/error14.t.re [new file with mode: 0755]

index 6852abfae7482e3b0cbb8c8dfb946f9528c0790c..7ba148578ede0f82fbb14876a14b86dcf02ae181 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,7 @@
 Version 0.10.2 (2006-??-??)
 ---------------------------
+- Added -t switch to force two pass generation.
+- Changed to not generate YYMARKER unless needed.
 - Fixed -i switch.
 - Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
 - Added tutorial like lessons to re2c.
index 8aa1b0550ec5d7f16403b342be0c162fd0f7b4ea..2e180c99d9efa0eda35bf9fba7380e578203b58c 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.10.2.dev on Sat Apr 15 08:54:49 2006 */
+/* Generated by re2c 0.10.2.dev on Sun Apr 16 13:38:11 2006 */
 #line 1 "scanner.re"
 /* $Id$ */
 #include <stdlib.h>
@@ -111,7 +111,7 @@ echo:
        yych = *(YYMARKER = ++YYCURSOR);
        if(yych == '*') goto yy16;
 yy3:
-#line 165 "scanner.re"
+#line 172 "scanner.re"
        {
                                        goto echo;
                                }
@@ -122,7 +122,7 @@ yy4:
        goto yy3;
 yy5:
        ++YYCURSOR;
-#line 150 "scanner.re"
+#line 157 "scanner.re"
        {
                                        if (!ignore_eoc) {
                                                out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
@@ -133,7 +133,7 @@ yy5:
 #line 134 "scanner.cc"
 yy7:
        ++YYCURSOR;
-#line 157 "scanner.re"
+#line 164 "scanner.re"
        {
                                        if (!ignore_eoc) {
                                                out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
@@ -152,7 +152,7 @@ yy10:
        if(yych == 0x0A) goto yy14;
        if(yych == 0x0D) goto yy12;
 yy11:
-#line 141 "scanner.re"
+#line 148 "scanner.re"
        {
                                        if (ignore_eoc) {
                                                ignore_eoc = false;
@@ -174,7 +174,7 @@ yy13:
        }
 yy14:
        ++YYCURSOR;
-#line 132 "scanner.re"
+#line 139 "scanner.re"
        {
                                        if (ignore_eoc) {
                                                ignore_eoc = false;
@@ -217,12 +217,15 @@ yy21:
        if(yych != 'c') goto yy13;
        ++YYCURSOR;
 #line 110 "scanner.re"
-       { 
+       {
+                                       if (bUsedYYMaxFill && bLastPass && !tFlag) {
+                                               fatal("found scanner block after YYMAXFILL declaration");
+                                       }
                                        out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
                                        tok = cursor;
                                        RETURN(1);
                                }
-#line 226 "scanner.cc"
+#line 229 "scanner.cc"
 yy26:
        yych = *++YYCURSOR;
        if(yych != 'x') goto yy13;
@@ -237,14 +240,18 @@ yy26:
        yych = *++YYCURSOR;
        if(yych != 'c') goto yy13;
        ++YYCURSOR;
-#line 115 "scanner.re"
+#line 118 "scanner.re"
        {
+                                       if (bUsedYYMaxFill) {
+                                               fatal("cannot generate YYMAXFILL twice");
+                                       }
                                        out << "#define YYMAXFILL " << maxFill << std::endl;
                                        tok = pos = cursor;
                                        ignore_eoc = true;
+                                       bUsedYYMaxFill = true;
                                        goto echo;
                                }
-#line 248 "scanner.cc"
+#line 255 "scanner.cc"
 yy34:
        yych = *++YYCURSOR;
        if(yych != 't') goto yy13;
@@ -269,14 +276,14 @@ yy34:
        yych = *++YYCURSOR;
        if(yych != 'c') goto yy13;
        ++YYCURSOR;
-#line 121 "scanner.re"
+#line 128 "scanner.re"
        {
                                        tok = pos = cursor;
                                        genGetState(out, topIndent, 0);
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 280 "scanner.cc"
+#line 287 "scanner.cc"
 yy47:
        yych = *++YYCURSOR;
        if(yych != 'n') goto yy13;
@@ -297,15 +304,15 @@ yy47:
        yych = *++YYCURSOR;
        if(yych != 'c') goto yy13;
        ++YYCURSOR;
-#line 127 "scanner.re"
+#line 134 "scanner.re"
        {
                                        tok = pos = cursor;
                                        ignore_eoc = true;
                                        goto echo;
                                }
-#line 307 "scanner.cc"
+#line 314 "scanner.cc"
 }
-#line 168 "scanner.re"
+#line 175 "scanner.re"
 
 }
 
@@ -328,7 +335,7 @@ scan:
                goto value;
     }
 
-#line 332 "scanner.cc"
+#line 339 "scanner.cc"
 {
        YYCTYPE yych;
        unsigned int yyaccept = 0;
@@ -402,42 +409,42 @@ yy60:
                if(yych <= '9') goto yy124;
        }
 yy61:
-#line 190 "scanner.re"
+#line 197 "scanner.re"
        { depth = 1;
                                  goto code;
                                }
-#line 410 "scanner.cc"
+#line 417 "scanner.cc"
 yy62:
        ++YYCURSOR;
        if((yych = *YYCURSOR) == '*') goto yy121;
 yy63:
-#line 220 "scanner.re"
+#line 227 "scanner.re"
        { RETURN(*tok); }
-#line 417 "scanner.cc"
+#line 424 "scanner.cc"
 yy64:
        ++YYCURSOR;
        if((yych = *YYCURSOR) == '/') goto yy119;
 yy65:
-#line 222 "scanner.re"
+#line 229 "scanner.re"
        { yylval.op = *tok;
                                  RETURN(CLOSE); }
-#line 425 "scanner.cc"
+#line 432 "scanner.cc"
 yy66:
        yyaccept = 1;
        yych = *(YYMARKER = ++YYCURSOR);
        if(yych != 0x0A) goto yy115;
 yy67:
-#line 207 "scanner.re"
+#line 214 "scanner.re"
        { fatal("unterminated string constant (missing \")"); }
-#line 433 "scanner.cc"
+#line 440 "scanner.cc"
 yy68:
        yyaccept = 2;
        yych = *(YYMARKER = ++YYCURSOR);
        if(yych != 0x0A) goto yy110;
 yy69:
-#line 208 "scanner.re"
+#line 215 "scanner.re"
        { fatal("unterminated string constant (missing ')"); }
-#line 441 "scanner.cc"
+#line 448 "scanner.cc"
 yy70:
        yyaccept = 3;
        yych = *(YYMARKER = ++YYCURSOR);
@@ -445,9 +452,9 @@ yy70:
        if(yych == '^') goto yy101;
        goto yy100;
 yy71:
-#line 218 "scanner.re"
+#line 225 "scanner.re"
        { fatal("unterminated range (missing ])"); }
-#line 451 "scanner.cc"
+#line 458 "scanner.cc"
 yy72:
        yych = *++YYCURSOR;
        goto yy63;
@@ -459,51 +466,51 @@ yy74:
        if((yych = *YYCURSOR) == 'e') goto yy91;
        goto yy90;
 yy75:
-#line 249 "scanner.re"
+#line 256 "scanner.re"
        { cur = cursor;
                                  yylval.symbol = Symbol::find(token());
                                  return ID; }
-#line 467 "scanner.cc"
+#line 474 "scanner.cc"
 yy76:
        yych = *++YYCURSOR;
        goto yy90;
 yy77:
        ++YYCURSOR;
-#line 253 "scanner.re"
+#line 260 "scanner.re"
        { cur = cursor;
                                  yylval.regexp = mkDot();
                                  return RANGE;
                                }
-#line 478 "scanner.cc"
+#line 485 "scanner.cc"
 yy79:
        ++YYCURSOR;
        yych = *YYCURSOR;
        goto yy88;
 yy80:
-#line 258 "scanner.re"
+#line 265 "scanner.re"
        { goto scan; }
-#line 486 "scanner.cc"
+#line 493 "scanner.cc"
 yy81:
        ++YYCURSOR;
 yy82:
-#line 260 "scanner.re"
+#line 267 "scanner.re"
        { if(cursor == eof) RETURN(0);
                                  pos = cursor; cline++;
                                  goto scan;
                                }
-#line 495 "scanner.cc"
+#line 502 "scanner.cc"
 yy83:
        ++YYCURSOR;
        if((yych = *YYCURSOR) == 0x0A) goto yy86;
 yy84:
-#line 265 "scanner.re"
+#line 272 "scanner.re"
        { std::ostringstream msg;
                                  msg << "unexpected character: ";
                                  prtChOrHex(msg, *tok);
                                  fatal(msg.str().c_str());
                                  goto scan;
                                }
-#line 507 "scanner.cc"
+#line 514 "scanner.cc"
 yy85:
        yych = *++YYCURSOR;
        goto yy84;
@@ -581,14 +588,14 @@ yy96:
                }
        }
 yy98:
-#line 242 "scanner.re"
+#line 249 "scanner.re"
        { cur = cursor;
                                  tok+= 5; /* skip "re2c:" */
                                  iscfg = 1;
                                  yylval.str = new Str(token());
                                  return CONFIG;
                                }
-#line 592 "scanner.cc"
+#line 599 "scanner.cc"
 yy99:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -622,11 +629,11 @@ yy103:
        goto yy99;
 yy104:
        ++YYCURSOR;
-#line 214 "scanner.re"
+#line 221 "scanner.re"
        { cur = cursor;
                                  yylval.regexp = ranToRE(token());
                                  return RANGE; }
-#line 630 "scanner.cc"
+#line 637 "scanner.cc"
 yy106:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -635,11 +642,11 @@ yy106:
        goto yy101;
 yy107:
        ++YYCURSOR;
-#line 210 "scanner.re"
+#line 217 "scanner.re"
        { cur = cursor;
                                  yylval.regexp = invToRE(token());
                                  return RANGE; }
-#line 643 "scanner.cc"
+#line 650 "scanner.cc"
 yy109:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -659,11 +666,11 @@ yy110:
        goto yy109;
 yy112:
        ++YYCURSOR;
-#line 203 "scanner.re"
+#line 210 "scanner.re"
        { cur = cursor;
                                  yylval.regexp = strToCaseInsensitiveRE(token());
                                  return STRING; }
-#line 667 "scanner.cc"
+#line 674 "scanner.cc"
 yy114:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -683,23 +690,23 @@ yy115:
        goto yy114;
 yy117:
        ++YYCURSOR;
-#line 199 "scanner.re"
+#line 206 "scanner.re"
        { cur = cursor;
                                  yylval.regexp = strToRE(token());
                                  return STRING; }
-#line 691 "scanner.cc"
+#line 698 "scanner.cc"
 yy119:
        ++YYCURSOR;
-#line 196 "scanner.re"
+#line 203 "scanner.re"
        { tok = cursor;
                                  RETURN(0); }
-#line 697 "scanner.cc"
+#line 704 "scanner.cc"
 yy121:
        ++YYCURSOR;
-#line 193 "scanner.re"
+#line 200 "scanner.re"
        { depth = 1;
                                  goto comment; }
-#line 703 "scanner.cc"
+#line 710 "scanner.cc"
 yy123:
        yych = *++YYCURSOR;
        if(yych == ',') goto yy137;
@@ -720,16 +727,16 @@ yy125:
 yy126:
        ++YYCURSOR;
 yy127:
-#line 240 "scanner.re"
+#line 247 "scanner.re"
        { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
-#line 726 "scanner.cc"
+#line 733 "scanner.cc"
 yy128:
        ++YYCURSOR;
-#line 228 "scanner.re"
+#line 235 "scanner.re"
        { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = atoi((char *)tok+1);
                                  RETURN(CLOSESIZE); }
-#line 733 "scanner.cc"
+#line 740 "scanner.cc"
 yy130:
        yyaccept = 6;
        yych = *(YYMARKER = ++YYCURSOR);
@@ -737,11 +744,11 @@ yy130:
        if(yych <= '9') goto yy133;
        if(yych != '}') goto yy127;
        ++YYCURSOR;
-#line 236 "scanner.re"
+#line 243 "scanner.re"
        { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = -1;
                                  RETURN(CLOSESIZE); }
-#line 745 "scanner.cc"
+#line 752 "scanner.cc"
 yy133:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -750,11 +757,11 @@ yy133:
        if(yych <= '9') goto yy133;
        if(yych != '}') goto yy95;
        ++YYCURSOR;
-#line 232 "scanner.re"
+#line 239 "scanner.re"
        { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
                                  RETURN(CLOSESIZE); }
-#line 758 "scanner.cc"
+#line 765 "scanner.cc"
 yy137:
        yyaccept = 6;
        yych = *(YYMARKER = ++YYCURSOR);
@@ -762,17 +769,17 @@ yy137:
        if(yych <= '9') goto yy133;
        if(yych != '}') goto yy127;
        ++YYCURSOR;
-#line 225 "scanner.re"
+#line 232 "scanner.re"
        { yylval.op = '*';
                                  RETURN(CLOSE); }
-#line 769 "scanner.cc"
+#line 776 "scanner.cc"
 }
-#line 271 "scanner.re"
+#line 278 "scanner.re"
 
 
 code:
 
-#line 776 "scanner.cc"
+#line 783 "scanner.cc"
 {
        YYCTYPE yych;
        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
@@ -795,34 +802,34 @@ code:
                }
        }
        ++YYCURSOR;
-#line 275 "scanner.re"
+#line 282 "scanner.re"
        { if(--depth == 0){
                                        cur = cursor;
                                        yylval.token = new Token(token(), tline);
                                        return CODE;
                                  }
                                  goto code; }
-#line 806 "scanner.cc"
+#line 813 "scanner.cc"
 yy144:
        ++YYCURSOR;
-#line 281 "scanner.re"
+#line 288 "scanner.re"
        { ++depth;
                                  goto code; }
-#line 812 "scanner.cc"
+#line 819 "scanner.cc"
 yy146:
        ++YYCURSOR;
-#line 283 "scanner.re"
+#line 290 "scanner.re"
        { if(cursor == eof) fatal("missing '}'");
                                  pos = cursor; cline++;
                                  goto code;
                                }
-#line 820 "scanner.cc"
+#line 827 "scanner.cc"
 yy148:
        ++YYCURSOR;
 yy149:
-#line 287 "scanner.re"
+#line 294 "scanner.re"
        { goto code; }
-#line 826 "scanner.cc"
+#line 833 "scanner.cc"
 yy150:
        yych = *(YYMARKER = ++YYCURSOR);
        if(yych == 0x0A) goto yy149;
@@ -870,12 +877,12 @@ yy157:
        if(yych == 0x0A) goto yy154;
        goto yy156;
 }
-#line 288 "scanner.re"
+#line 295 "scanner.re"
 
 
 comment:
 
-#line 879 "scanner.cc"
+#line 886 "scanner.cc"
 {
        YYCTYPE yych;
        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
@@ -892,47 +899,47 @@ yy161:
        ++YYCURSOR;
        if((yych = *YYCURSOR) == '/') goto yy169;
 yy162:
-#line 303 "scanner.re"
+#line 310 "scanner.re"
        { if(cursor == eof) RETURN(0);
                                  goto comment; }
-#line 899 "scanner.cc"
+#line 906 "scanner.cc"
 yy163:
        yych = *++YYCURSOR;
        if(yych == '*') goto yy167;
        goto yy162;
 yy164:
        ++YYCURSOR;
-#line 299 "scanner.re"
+#line 306 "scanner.re"
        { if(cursor == eof) RETURN(0);
                                  tok = pos = cursor; cline++;
                                  goto comment;
                                }
-#line 911 "scanner.cc"
+#line 918 "scanner.cc"
 yy166:
        yych = *++YYCURSOR;
        goto yy162;
 yy167:
        ++YYCURSOR;
-#line 296 "scanner.re"
+#line 303 "scanner.re"
        { ++depth;
                                  fatal("ambiguous /* found");
                                  goto comment; }
-#line 921 "scanner.cc"
+#line 928 "scanner.cc"
 yy169:
        ++YYCURSOR;
-#line 292 "scanner.re"
+#line 299 "scanner.re"
        { if(--depth == 0)
                                        goto scan;
                                    else
                                        goto comment; }
-#line 929 "scanner.cc"
+#line 936 "scanner.cc"
 }
-#line 305 "scanner.re"
+#line 312 "scanner.re"
 
 
 config:
 
-#line 936 "scanner.cc"
+#line 943 "scanner.cc"
 {
        YYCTYPE yych;
        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
@@ -949,25 +956,25 @@ yy173:
        yych = *YYCURSOR;
        goto yy182;
 yy174:
-#line 309 "scanner.re"
+#line 316 "scanner.re"
        { goto config; }
-#line 955 "scanner.cc"
+#line 962 "scanner.cc"
 yy175:
        ++YYCURSOR;
        yych = *YYCURSOR;
        goto yy180;
 yy176:
-#line 310 "scanner.re"
+#line 317 "scanner.re"
        { iscfg = 2;
                                  cur = cursor;
                                  RETURN('='); 
                                }
-#line 966 "scanner.cc"
+#line 973 "scanner.cc"
 yy177:
        ++YYCURSOR;
-#line 314 "scanner.re"
+#line 321 "scanner.re"
        { fatal("missing '='"); }
-#line 971 "scanner.cc"
+#line 978 "scanner.cc"
 yy179:
        ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
@@ -985,12 +992,12 @@ yy182:
        if(yych == ' ') goto yy181;
        goto yy174;
 }
-#line 315 "scanner.re"
+#line 322 "scanner.re"
 
 
 value:
 
-#line 994 "scanner.cc"
+#line 1001 "scanner.cc"
 {
        YYCTYPE yych;
        if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
@@ -1023,13 +1030,13 @@ value:
                }
        }
 yy185:
-#line 324 "scanner.re"
+#line 331 "scanner.re"
        { cur = cursor;
                                  yylval.str = new Str(token());
                                  iscfg = 0;
                                  return VALUE;
                                }
-#line 1033 "scanner.cc"
+#line 1040 "scanner.cc"
 yy186:
        ++YYCURSOR;
        if((yych = *YYCURSOR) <= 0x0D) {
@@ -1044,13 +1051,13 @@ yy186:
                }
        }
 yy187:
-#line 319 "scanner.re"
+#line 326 "scanner.re"
        { cur = cursor;
                                  yylval.number = atoi(token().to_string().c_str());
                                  iscfg = 0;
                                  return NUMBER;
                                }
-#line 1054 "scanner.cc"
+#line 1061 "scanner.cc"
 yy188:
        yych = *++YYCURSOR;
        if(yych <= '0') goto yy192;
@@ -1224,7 +1231,7 @@ yy206:
        if(yych == 0x0A) goto yy199;
        goto yy203;
 }
-#line 329 "scanner.re"
+#line 336 "scanner.re"
 
 }
 
diff --git a/code.cc b/code.cc
index f75830e3cff8662c8bcbb61db241bfef28f43df6..25ea82e270ff6db2b4f5e11e58098973aae13b4b 100644 (file)
--- a/code.cc
+++ b/code.cc
@@ -396,11 +396,11 @@ void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
        }
        if (state->link)
        {
-               need(o, ind, state->depth, readCh, setMarker && bUseYYMarker);
+               need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker);
        }
        else
        {
-               if (setMarker && bUseYYMarker)
+               if (setMarker && bUsedYYMarker)
                {
                        o << indent(ind) << "YYMARKER = YYCURSOR;\n";
                }
@@ -417,7 +417,7 @@ void Save::emit(std::ostream &o, uint ind, bool &readCh) const
 
        if (state->link)
        {
-               if (bUseYYMarker)
+               if (bUsedYYMarker)
                {
                        o << indent(ind) << "YYMARKER = ++YYCURSOR;\n";
                }
@@ -425,7 +425,7 @@ void Save::emit(std::ostream &o, uint ind, bool &readCh) const
        }
        else
        {
-               if (bUseYYMarker)
+               if (bUsedYYMarker)
                {
                        o << indent(ind) << "yych = *(YYMARKER = ++YYCURSOR);\n";
                }
@@ -474,7 +474,7 @@ void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
                        if (first)
                        {
                                first = false;
-                               bUseYYMarker = true;
+                               bUsedYYMarker = true;
                                o << indent(ind) << "YYCURSOR = YYMARKER;\n";
                                if (bUsedYYAccept && cases > 1)
                                {
@@ -1234,7 +1234,6 @@ void DFA::emit(std::ostream &o, uint ind)
 
        uint nRules = 0;
 
-       maxFill = 1;
        for (s = head; s; s = s->next)
        {
                s->depth = maxDist(s);
index 323d1c7055a305dcbac80ec16f5f65e4d424f0c0..8c74f719edac5d3d93f950afd7bb60ff0b0e7fe2 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -21,8 +21,14 @@ extern bool fFlag;
 extern bool iFlag;
 extern bool sFlag;
 extern bool wFlag;
+extern bool tFlag;
+
+extern bool bLastPass;
 
 extern bool bUsedYYAccept;
+extern bool bUsedYYMaxFill;
+extern bool bUsedYYMarker;
+
 extern bool bUseStartLabel;
 extern std::string startLabelName;
 extern uint maxFill;
@@ -36,7 +42,6 @@ extern bool bUseStateAbort;
 extern bool bUseStateNext;
 extern bool bWroteGetState;
 extern bool bUseYYFill;
-extern bool bUseYYMarker;
 
 extern uint asc2ebc[256];
 extern uint ebc2asc[256];
index ca954398e65b7aff1a232390b82edd6c7b00debd..71289dbe1346fea48257211ba22a8da576aa774a 100755 (executable)
@@ -78,6 +78,8 @@ provide re2c packages.</li>
 <h1>Changelog</h1>
 <h2>2006-??-??: 0.10.2</h2>
 <ul>
+<li>Added -t switch to force two pass generation.</li>
+<li>Changed to not generate YYMARKER unless needed.</li>
 <li>Fixed -i switch.</li>
 <li>Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.</li>
 <li>Added tutorial like lessons to re2c.</li>
index 7d8c85c144d965aee819c0340b816ebac1e70ac7..e56d78383f61511c966e96b3686b99c9cca7e490 100755 (executable)
@@ -15,7 +15,7 @@ Updated: 8 April 2006<br />
 <p>re2c - convert regular expressions to C/C++</p>
 <a name="lbAC" id="lbAC">&nbsp;</a>
 <h2>SYNOPSIS</h2>
-<p><b>re2c</b> [<b>-bdefhisvVw</b>] [<b>-o output</b>] file</p>
+<p><b>re2c</b> [<b>-bdefhistvVw</b>] [<b>-o output</b>] file</p>
 <a name="lbAD" id="lbAD">&nbsp;</a>
 <h2>DESCRIPTION</h2>
 <p><b>re2c</b> is a preprocessor that generates C-based recognizers from
@@ -82,9 +82,11 @@ yy7:    if(yych &lt;= '/') goto yy3;
 </pre>
 <br />
 <br />
-<p>After the /*!re2c */ blocks you can place a /*!max:re2c */ block that will
-output a define (YYMAXFILL) that holds the maximum number of characters required to parse
-the input. That is the maximum value YYFILL(n) will receive.</p>
+<p>After the /*!re2c */ blocks you can place one /*!max:re2c */ comment 
+that will output a define (YYMAXFILL) that holds the maximum number of 
+characters required to parse the input. That is the maximum value YYFILL(n)
+will receive. If -t is in effect then YYMAXFILL can be triggered once anywhere
+in the code.</p>
 <p>You can also use /*!ignore:re2c */ blocks that allows to document the
 scanner code and will not be part of the output.</p>
 <a name="lbAE" id="lbAE"> </a>
@@ -107,7 +109,7 @@ YYDEBUG(int state, char current)</i>. The first parameter receives the state or
 <dt><b>-e</b></dt>
 <dd>Cross-compile from an ASCII platform to an EBCDIC one.<br /><br /></dd>
 <dt><b>-f</b></dt>
-<dd>Generate a scanner with support for storable state. For details see below
+<dd>Implies -t. Generate a scanner with support for storable state. For details see below
 at <b>SCANNER WITH STORABLE STATES</b>.<br /><br /></dd>
 <dt><b>-i</b></dt>
 <dd>Do not output #line information. This is usefull when you want use a CMS
@@ -117,6 +119,9 @@ Specify the output file.<br /><br /></dd>
 <dt><b>-s</b></dt>
 <dd>Generate nested ifs for some switches. Many compilers need this assist to
 generate better code.<br /><br /></dd>
+<dt><b>-t</b></dt>
+<dd>Force two pass generation, allows YYMAXFILL generation prior to last re2c 
+block.<br /><br /></dd>
 <dt><b>-v</b></dt>
 <dd>Show version information.<br /><br /></dd>
 <dt><b>-V</b></dt>
@@ -157,9 +162,10 @@ regular expressions.<br /><br /></dd>
 least <i>n</i> additional characters should be provided. YYFILL(n) should adjust
 YYCURSOR, YYLIMIT, YYMARKER and YYCTXMARKER as needed. Note that for typical 
 programming languages <i>n</i> will be the length of the longest keyword plus 
-one. The user can place a comment of the form /*!max:re2c */ after the 
+one. The user can place a comment of the form /*!max:re2c */ once after the 
 end of the last scanner block to insert a YYMAXFILL definition that is 
-set to the maximum length value.<br /><br /></dd>
+set to the maximum length value. If -t switch is used then YYMAXFILL can be 
+triggered once anywhere in the code.<br /><br /></dd>
 <dt>YYGETSTATE()</dt>
 <dd>The user only needs to define this macro if the <b>-f</b> flag was
 specified. In that case, the generated code "calls" YYGETSTATE at the very
diff --git a/main.cc b/main.cc
index ddbe917d6b1979afc972e80a0f51ce2cbe076c03..5a5549723a8af361ca0ebbc24e37411cbe623ea3 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -28,12 +28,17 @@ bool fFlag = false;
 bool iFlag = false;
 bool sFlag = false;
 bool wFlag = false;
+bool tFlag = false;
+
+bool bLastPass = false;
+
+bool bUsedYYAccept  = false;
+bool bUsedYYMaxFill = false;
+bool bUsedYYMarker  = false;
 
-bool bUsedYYAccept = false;
 bool bUseStartLabel= false;
 bool bUseStateNext = false;
 bool bUseYYFill    = true;
-bool bUseYYMarker  = false;
 
 std::string startLabelName;
 uint maxFill = 1;
@@ -67,6 +72,7 @@ static const mbo_opt_struct OPTIONS[] =
        mbo_opt_struct('i', 0, "no-debug-info"),
        mbo_opt_struct('o', 1, "output"),
        mbo_opt_struct('s', 0, "nested-ifs"),
+       mbo_opt_struct('t', 0, "two-pass"),
        mbo_opt_struct('v', 0, "version"),
        mbo_opt_struct('V', 0, "vernum"),
        mbo_opt_struct('w', 0, "wide-chars"),      
@@ -91,7 +97,8 @@ static void usage()
        "-e     --ecb            Cross-compile from an ASCII platform to\n"
        "                        an EBCDIC one.\n"
        "\n"
-       "-f     --storable-state Generate a scanner with support for storable state\n"
+       "-f     --storable-state Implies -t. Generate a scanner that supports storable\n"
+       "                        states.\n"
        "\n"
        "-i     --no-debug-info  Do not generate '#line' info (usefull for versioning).\n"
        "\n"
@@ -101,6 +108,9 @@ static void usage()
        "-s     --nested-ifs     Generate nested ifs for some switches. Many compilers\n"
        "                        need this assist to generate better code.\n"
        "\n"
+       "-t     --two-pass       Force two pass generation, allows YYMAXFILL generation\n"
+       "                        prior to last re2c block.\n"
+       "\n"
        "-v     --version        Show version information.\n"
        "-V     --vernum         Show version as one number.\n"
        "\n"
@@ -141,16 +151,13 @@ int main(int argc, char *argv[])
                        eFlag = true;
                        break;
 
-                       case 's':
-                       sFlag = true;
-                       break;
-
                        case 'd':
                        dFlag = true;
                        break;
 
                        case 'f':
                        fFlag = true;
+                       tFlag = true;
                        break;
 
                        case 'i':
@@ -161,6 +168,14 @@ int main(int argc, char *argv[])
                        outputFileName = opt_arg;
                        break;
 
+                       case 's':
+                       sFlag = true;
+                       break;
+                       
+                       case 't':
+                       tFlag = true;
+                       break;
+
                        case 'v':
                        cout << "re2c " << PACKAGE_VERSION << "\n";
                        return 2;
@@ -252,10 +267,10 @@ int main(int argc, char *argv[])
        sourceFileInfo = file_info(sourceFileName, &scanner);
        outputFileInfo = file_info(outputFileName, &output);
 
-       if (fFlag)
+       if (tFlag)
        {
                re2c::ifstream_lc null_source;
-
+               
                if (!null_source.open(sourceFileName).is_open())
                {
                        cerr << "re2c: error: cannot re-open " << sourceFileName << "\n";
@@ -269,8 +284,10 @@ int main(int argc, char *argv[])
                next_fill_index = 0;
                Symbol::ClearTable();
                bWroteGetState = false;
+               bUsedYYMaxFill = false;
        }
 
+       bLastPass = true;
        parse(scanner, output);
        return 0;
 }
index b960f276de22acc963b7fdd6351a83731e9018a6..f12575c1faca84a321ae7bf64558d4509159843a 100644 (file)
--- a/re2c.1.in
+++ b/re2c.1.in
@@ -10,7 +10,7 @@
 re2c \- convert regular expressions to C/C++
 
 .SH SYNOPSIS
-\*(re [\fB-bdefhisvVw\fP] [\fB-o output\fP] file\fP
+\*(re [\fB-bdefhistvVw\fP] [\fB-o output\fP] file\fP
 
 .SH DESCRIPTION
 \*(re is a preprocessor that generates C-based recognizers from regular
@@ -86,10 +86,11 @@ yy7:    if(yych <= '/') goto yy3;
 .fi
 .in -3
 
-After the \fC/*!re2c */\fP blocks you can place a \fC/*!max:re2c */\fP block
+After the \fC/*!re2c */\fP blocks you can place one \fC/*!max:re2c */\fP comment
 that will output a define (\fCYYMAXFILL\fP) that holds the maximum number of 
 characters required to parse the input. That is the maximum value \fCYYFILL\fP(n)
-will receive.
+will receive. If -t is in effect then YYMAXFILL can be triggered once anywhere 
+in the code.
 
 You can also use \fC/*!ignore:re2c */\fP blocks that allows to document the
 scanner code and will not be part of the output.
@@ -118,7 +119,7 @@ state or -1 and the second parameter receives the input at the current cursor.
 Cross-compile from an ASCII platform to an EBCDIC one. 
 .TP
 \fB-f\fP
-Generate a scanner with support for storable state.
+Implies \fB-t\fP. Generate a scanner with support for storable state.
 For details see below at \fBSCANNER WITH STORABLE STATES\fP.
 .TP
 \fB-i\fP
@@ -132,6 +133,9 @@ Specify the output file.
 Generate nested \fCif\fPs for some \fCswitch\fPes.  Many compilers need this
 assist to generate better code.
 .TP
+\fB-t\fP
+Force two pass generation, allows YYMAXFILL generation prior to last re2c block.
+.TP
 \fB-v\fP
 Show version information.
 .TP
@@ -180,9 +184,10 @@ The generated code "calls" \fCYYFILL\fP(n) when the buffer needs
 be provided.  \fCYYFILL\fP(n) should adjust \fCYYCURSOR\fP, \fCYYLIMIT\fP,
 \fCYYMARKER\fP and \fCYYCTXMARKER\fP as needed.  Note that for typical 
 programming languages \fIn\fP will be the length of the longest keyword plus one.
-The user can place a comment of the form \fC/*!max:re2c */\fP after the end of
-the last scanner block to insert a \fCYYMAXFILL\fP definition that is set to 
-the maximum length value.
+The user can place a comment of the form \fC/*!max:re2c */\fP once after the 
+end of the last scanner block to insert a \fCYYMAXFILL\fP definition that is 
+set to the maximum length value. If -t switch is used then YYMAXFILL can be 
+triggered once anywhere in the code.
 .TP
 \fCYYGETSTATE()\fP
 The user only needs to define this macro if the \fB-f\fP flag was specified.
index f9d4c5ecad9634d584cc7003d48f177e0e692df9..9886b179ea3d357711dafb64bb9519b44e24a07e 100644 (file)
@@ -107,15 +107,22 @@ int Scanner::echo()
     tok = cursor;
 echo:
 /*!re2c
-       "/*!re2c"       { 
+       "/*!re2c"       {
+                                       if (bUsedYYMaxFill && bLastPass && !tFlag) {
+                                               fatal("found scanner block after YYMAXFILL declaration");
+                                       }
                                        out.write((const char*)(tok), (const char*)(&cursor[-7]) - (const char*)(tok));
                                        tok = cursor;
                                        RETURN(1);
                                }
        "/*!max:re2c" {
+                                       if (bUsedYYMaxFill) {
+                                               fatal("cannot generate YYMAXFILL twice");
+                                       }
                                        out << "#define YYMAXFILL " << maxFill << std::endl;
                                        tok = pos = cursor;
                                        ignore_eoc = true;
+                                       bUsedYYMaxFill = true;
                                        goto echo;
                                }
        "/*!getstate:re2c" {
diff --git a/test/error13.c b/test/error13.c
new file mode 100755 (executable)
index 0000000..7d60a11
--- /dev/null
@@ -0,0 +1,5 @@
+/* Generated by re2c */
+#line 1 "error13.re"
+#define YYMAXFILL 1
+
+re2c: error: line 0, column 1: found scanner block after YYMAXFILL declaration
diff --git a/test/error13.re b/test/error13.re
new file mode 100755 (executable)
index 0000000..9ec0aa5
--- /dev/null
@@ -0,0 +1,7 @@
+/*!max:re2c */
+
+/*!re2c
+       "ABC"           { return 1; }
+       "ABD"           { return 2; }
+       [^]                     { return 0; }
+*/
diff --git a/test/error13.t.c b/test/error13.t.c
new file mode 100755 (executable)
index 0000000..3a434ef
--- /dev/null
@@ -0,0 +1,51 @@
+/* Generated by re2c */
+#line 1 "error13.t.re"
+#define YYMAXFILL 3
+
+
+#line 7 "<stdout>"
+{
+       YYCTYPE yych;
+
+       if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch(yych){
+       case 'A':       goto yy2;
+       default:        goto yy4;
+       }
+yy2:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch(yych){
+       case 'B':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+#line 6 "error13.t.re"
+       { return 0; }
+#line 26 "<stdout>"
+yy4:
+       yych = *++YYCURSOR;
+       goto yy3;
+yy5:
+       yych = *++YYCURSOR;
+       switch(yych){
+       case 'C':       goto yy7;
+       case 'D':       goto yy9;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy7:
+       ++YYCURSOR;
+#line 4 "error13.t.re"
+       { return 1; }
+#line 44 "<stdout>"
+yy9:
+       ++YYCURSOR;
+#line 5 "error13.t.re"
+       { return 2; }
+#line 49 "<stdout>"
+}
+#line 7 "error13.t.re"
+
diff --git a/test/error13.t.re b/test/error13.t.re
new file mode 100755 (executable)
index 0000000..9ec0aa5
--- /dev/null
@@ -0,0 +1,7 @@
+/*!max:re2c */
+
+/*!re2c
+       "ABC"           { return 1; }
+       "ABD"           { return 2; }
+       [^]                     { return 0; }
+*/
diff --git a/test/error14.c b/test/error14.c
new file mode 100755 (executable)
index 0000000..dbddeed
--- /dev/null
@@ -0,0 +1,53 @@
+/* Generated by re2c */
+#line 1 "error14.re"
+
+#line 5 "<stdout>"
+{
+       YYCTYPE yych;
+
+       if((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       switch(yych){
+       case 'A':       goto yy2;
+       default:        goto yy4;
+       }
+yy2:
+       yych = *(YYMARKER = ++YYCURSOR);
+       switch(yych){
+       case 'B':       goto yy5;
+       default:        goto yy3;
+       }
+yy3:
+#line 4 "error14.re"
+       { return 0; }
+#line 24 "<stdout>"
+yy4:
+       yych = *++YYCURSOR;
+       goto yy3;
+yy5:
+       yych = *++YYCURSOR;
+       switch(yych){
+       case 'C':       goto yy7;
+       case 'D':       goto yy9;
+       default:        goto yy6;
+       }
+yy6:
+       YYCURSOR = YYMARKER;
+       goto yy3;
+yy7:
+       ++YYCURSOR;
+#line 2 "error14.re"
+       { return 1; }
+#line 42 "<stdout>"
+yy9:
+       ++YYCURSOR;
+#line 3 "error14.re"
+       { return 2; }
+#line 47 "<stdout>"
+}
+#line 5 "error14.re"
+
+
+#define YYMAXFILL 3
+
+re2c: error: line 5, column 1: cannot generate YYMAXFILL twice
diff --git a/test/error14.re b/test/error14.re
new file mode 100755 (executable)
index 0000000..1b1757c
--- /dev/null
@@ -0,0 +1,9 @@
+/*!re2c
+       "ABC"           { return 1; }
+       "ABD"           { return 2; }
+       [^]                     { return 0; }
+*/
+
+/*!max:re2c */
+
+/*!max:re2c */
diff --git a/test/error14.t.c b/test/error14.t.c
new file mode 100755 (executable)
index 0000000..7235d52
--- /dev/null
@@ -0,0 +1 @@
+re2c: error: line 5, column 1: cannot generate YYMAXFILL twice
diff --git a/test/error14.t.re b/test/error14.t.re
new file mode 100755 (executable)
index 0000000..1b1757c
--- /dev/null
@@ -0,0 +1,9 @@
+/*!re2c
+       "ABC"           { return 1; }
+       "ABD"           { return 2; }
+       [^]                     { return 0; }
+*/
+
+/*!max:re2c */
+
+/*!max:re2c */