]> granicus.if.org Git - re2c/commitdiff
Bugfix 869297
authorhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Wed, 21 Apr 2004 08:49:44 +0000 (08:49 +0000)
committerhelly <helly@642ea486-5414-0410-9d7f-a0204ed87703>
Wed, 21 Apr 2004 08:49:44 +0000 (08:49 +0000)
bootstrap/scanner.cc
code.cc
dfa.h
re2c.spec.in

index 29fd5cb8e34120b621424c9f2b65d6da3f5f3abd..783f46711e5eb6aeb0d58ae890d1ce2eeae8137f 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.9.2 on Mon Apr 19 04:31:02 2004 */
+/* Generated by re2c 0.9.2 on Wed Apr 21 10:37:57 2004 */
 #line 1 "scanner.re"
 /* $Id$ */
 #include <stdlib.h>
@@ -96,7 +96,7 @@ yy3:
 #line 92 "scanner.re"
 { goto echo; }
 #line 26 "re2c-output.c"
-yy4:   yych = *++YYCURSOR;
+yy4:   ++YYCURSOR;
        goto yy5;
 yy5:
 #line 88 "scanner.re"
@@ -126,7 +126,7 @@ yy11:       yych = *++YYCURSOR;
 yy12:  yych = *++YYCURSOR;
        if(yych != 'c') goto yy8;
        goto yy13;
-yy13:  yych = *++YYCURSOR;
+yy13:  ++YYCURSOR;
        goto yy14;
 yy14:
 #line 85 "scanner.re"
@@ -216,15 +216,15 @@ yy18:
                                  goto code;
                                }
 #line 134 "re2c-output.c"
-yy19:  yych = *++YYCURSOR;
-       if(yych == '*') goto yy61;
+yy19:  ++YYCURSOR;
+       if((yych = *YYCURSOR) == '*')   goto yy61;
        goto yy20;
 yy20:
 #line 132 "scanner.re"
 { RETURN(*tok); }
 #line 141 "re2c-output.c"
-yy21:  yych = *++YYCURSOR;
-       if(yych == '/') goto yy59;
+yy21:  ++YYCURSOR;
+       if((yych = *YYCURSOR) == '/')   goto yy59;
        goto yy22;
 yy22:
 #line 134 "scanner.re"
@@ -259,7 +259,8 @@ yy29:       yych = *++YYCURSOR;
        goto yy20;
 yy30:  yych = *++YYCURSOR;
        goto yy22;
-yy31:  yych = *++YYCURSOR;
+yy31:  ++YYCURSOR;
+       yych = *YYCURSOR;
        goto yy42;
 yy32:
 #line 149 "scanner.re"
@@ -267,13 +268,14 @@ yy32:
                                  yylval.symbol = Symbol::find(token());
                                  return ID; }
 #line 185 "re2c-output.c"
-yy33:  yych = *++YYCURSOR;
+yy33:  ++YYCURSOR;
+       yych = *YYCURSOR;
        goto yy40;
 yy34:
 #line 153 "scanner.re"
 { goto scan; }
 #line 191 "re2c-output.c"
-yy35:  yych = *++YYCURSOR;
+yy35:  ++YYCURSOR;
        goto yy36;
 yy36:
 #line 155 "scanner.re"
@@ -282,7 +284,7 @@ yy36:
                                  goto scan;
                                }
 #line 200 "re2c-output.c"
-yy37:  yych = *++YYCURSOR;
+yy37:  ++YYCURSOR;
        goto yy38;
 yy38:
 #line 160 "scanner.re"
@@ -335,14 +337,14 @@ yy46:     ++YYCURSOR;
        yych = *YYCURSOR;
        if(yych == '\n')        goto yy45;
        goto yy43;
-yy47:  yych = *++YYCURSOR;
+yy47:  ++YYCURSOR;
        goto yy48;
 yy48:
 #line 126 "scanner.re"
 { cur = cursor;
                                  yylval.regexp = ranToRE(token());
                                  return RANGE; }
-#line 261 "re2c-output.c"
+#line 265 "re2c-output.c"
 yy49:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -360,14 +362,14 @@ yy51:     ++YYCURSOR;
        yych = *YYCURSOR;
        if(yych == '\n')        goto yy45;
        goto yy49;
-yy52:  yych = *++YYCURSOR;
+yy52:  ++YYCURSOR;
        goto yy53;
 yy53:
 #line 119 "scanner.re"
 { cur = cursor;
                                  yylval.regexp = strToCaseInsensitiveRE(token());
                                  return STRING; }
-#line 286 "re2c-output.c"
+#line 292 "re2c-output.c"
 yy54:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -385,28 +387,28 @@ yy56:     ++YYCURSOR;
        yych = *YYCURSOR;
        if(yych == '\n')        goto yy45;
        goto yy54;
-yy57:  yych = *++YYCURSOR;
+yy57:  ++YYCURSOR;
        goto yy58;
 yy58:
 #line 115 "scanner.re"
 { cur = cursor;
                                  yylval.regexp = strToRE(token());
                                  return STRING; }
-#line 311 "re2c-output.c"
-yy59:  yych = *++YYCURSOR;
+#line 319 "re2c-output.c"
+yy59:  ++YYCURSOR;
        goto yy60;
 yy60:
 #line 112 "scanner.re"
 { tok = cursor;
                                  RETURN(0); }
-#line 318 "re2c-output.c"
-yy61:  yych = *++YYCURSOR;
+#line 326 "re2c-output.c"
+yy61:  ++YYCURSOR;
        goto yy62;
 yy62:
 #line 109 "scanner.re"
 { depth = 1;
                                  goto comment; }
-#line 325 "re2c-output.c"
+#line 333 "re2c-output.c"
 yy63:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -419,25 +421,25 @@ yy64:     if(yych <= '/'){
                if(yych != '}') goto yy45;
                goto yy65;
        }
-yy65:  yych = *++YYCURSOR;
+yy65:  ++YYCURSOR;
        goto yy66;
 yy66:
 #line 137 "scanner.re"
 { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = atoi((char *)tok+1);
                                  RETURN(CLOSESIZE); }
-#line 345 "re2c-output.c"
+#line 354 "re2c-output.c"
 yy67:  yych = *++YYCURSOR;
        if(yych != '}') goto yy71;
        goto yy68;
-yy68:  yych = *++YYCURSOR;
+yy68:  ++YYCURSOR;
        goto yy69;
 yy69:
 #line 145 "scanner.re"
 { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = -1;
                                  RETURN(CLOSESIZE); }
-#line 356 "re2c-output.c"
+#line 365 "re2c-output.c"
 yy70:  ++YYCURSOR;
        if(YYLIMIT == YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
@@ -446,21 +448,21 @@ yy71:     if(yych <= '/') goto yy45;
        if(yych <= '9') goto yy70;
        if(yych != '}') goto yy45;
        goto yy72;
-yy72:  yych = *++YYCURSOR;
+yy72:  ++YYCURSOR;
        goto yy73;
 yy73:
 #line 141 "scanner.re"
 { yylval.extop.minsize = atoi((char *)tok+1);
                                  yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
                                  RETURN(CLOSESIZE); }
-#line 372 "re2c-output.c"
+#line 382 "re2c-output.c"
 }
 #line 163 "scanner.re"
 
 
 code:
 
-#line 376 "re2c-output.c"
+#line 386 "re2c-output.c"
 {
        YYCTYPE yych;
        unsigned int yyaccept;
@@ -487,7 +489,7 @@ yy74:
                        goto yy76;
                }
        }
-yy76:  yych = *++YYCURSOR;
+yy76:  ++YYCURSOR;
        goto yy77;
 yy77:
 #line 167 "scanner.re"
@@ -497,15 +499,15 @@ yy77:
                                        return CODE;
                                  }
                                  goto code; }
-#line 413 "re2c-output.c"
-yy78:  yych = *++YYCURSOR;
+#line 423 "re2c-output.c"
+yy78:  ++YYCURSOR;
        goto yy79;
 yy79:
 #line 173 "scanner.re"
 { ++depth;
                                  goto code; }
-#line 420 "re2c-output.c"
-yy80:  yych = *++YYCURSOR;
+#line 430 "re2c-output.c"
+yy80:  ++YYCURSOR;
        goto yy81;
 yy81:
 #line 175 "scanner.re"
@@ -513,13 +515,13 @@ yy81:
                                  pos = cursor; cline++;
                                  goto code;
                                }
-#line 429 "re2c-output.c"
-yy82:  yych = *++YYCURSOR;
+#line 439 "re2c-output.c"
+yy82:  ++YYCURSOR;
        goto yy83;
 yy83:
 #line 179 "scanner.re"
 { goto code; }
-#line 435 "re2c-output.c"
+#line 445 "re2c-output.c"
 yy84:  yyaccept = 0;
        yych = *(YYMARKER = ++YYCURSOR);
        if(yych == '\n')        goto yy83;
@@ -572,7 +574,7 @@ yy92:       ++YYCURSOR;
 
 comment:
 
-#line 485 "re2c-output.c"
+#line 499 "re2c-output.c"
 {
        YYCTYPE yych;
        unsigned int yyaccept;
@@ -589,17 +591,17 @@ yy93:
                if(yych == '/') goto yy97;
                goto yy100;
        }
-yy95:  yych = *++YYCURSOR;
-       if(yych == '/') goto yy103;
+yy95:  ++YYCURSOR;
+       if((yych = *YYCURSOR) == '/')   goto yy103;
        goto yy96;
 yy96:
 #line 194 "scanner.re"
 { goto comment; }
-#line 508 "re2c-output.c"
+#line 522 "re2c-output.c"
 yy97:  yych = *++YYCURSOR;
        if(yych == '*') goto yy101;
        goto yy96;
-yy98:  yych = *++YYCURSOR;
+yy98:  ++YYCURSOR;
        goto yy99;
 yy99:
 #line 190 "scanner.re"
@@ -607,17 +609,17 @@ yy99:
                                  tok = pos = cursor; cline++;
                                  goto comment;
                                }
-#line 520 "re2c-output.c"
+#line 534 "re2c-output.c"
 yy100: yych = *++YYCURSOR;
        goto yy96;
-yy101: yych = *++YYCURSOR;
+yy101: ++YYCURSOR;
        goto yy102;
 yy102:
 #line 188 "scanner.re"
 { ++depth;
                                  goto comment; }
-#line 529 "re2c-output.c"
-yy103: yych = *++YYCURSOR;
+#line 543 "re2c-output.c"
+yy103: ++YYCURSOR;
        goto yy104;
 yy104:
 #line 184 "scanner.re"
@@ -625,7 +627,7 @@ yy104:
                                        goto scan;
                                    else
                                        goto comment; }
-#line 538 "re2c-output.c"
+#line 552 "re2c-output.c"
 }
 #line 195 "scanner.re"
 
diff --git a/code.cc b/code.cc
index b6331d18d6a7972c7bea3f885f4fdd4e3eb556aa..c106131e0e81963545f4afb2604208f2d2517a61 100644 (file)
--- a/code.cc
+++ b/code.cc
@@ -151,79 +151,115 @@ prt(cerr, b->go, b->on); cerr << endl;
     first = NULL;
 }
 
-void genGoTo(ostream &o, State *to){
-    o  << "\tgoto yy" << to->label << ";\n";
-    ++oline;
+void genGoTo(ostream &o, State *from, State *to, bool & readCh)
+{
+       if (readCh && from->label + 1 != to->label)
+       {
+               o << "\tyych = *YYCURSOR;\n";
+               readCh = false;
+       }
+       o  << "\tgoto yy" << to->label << ";\n";
+       ++oline;
 }
 
-void genIf(ostream &o, char *cmp, uint v){
-    o << "\tif(yych " << cmp << " '";
-    prtCh(o, v);
-    o << "')";
+void genIf(ostream &o, char *cmp, uint v, bool &readCh)
+{
+       if (readCh)
+       {
+               o << "\tif((yych = *YYCURSOR) ";
+               readCh = false;
+       }
+       else
+       {
+               o << "\tif(yych ";
+       }
+       o << cmp << " '";
+       prtCh(o, v);
+       o << "')";
 }
 
-void indent(ostream &o, uint i){
-    while(i-- > 0)
-       o << "\t";
+void indent(ostream &o, uint i)
+{
+       while(i-- > 0)
+       {
+               o << "\t";
+       }
 }
 
-static void need(ostream &o, uint n){
-    if(n == 1)
-    {
-       o << "\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n";
-       ++oline;
-    }
-    else
-    {
-       o << "\tif((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
+static void need(ostream &o, uint n, bool & readCh)
+{
+       if(n == 1)
+       {
+               o << "\tif(YYLIMIT == YYCURSOR) YYFILL(1);\n";
+               ++oline;
+       }
+       else
+       {
+               o << "\tif((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
+               ++oline;
+       }
+       o << "\tyych = *YYCURSOR;\n";
+       readCh = false;
        ++oline;
-    }
-    o << "\tyych = *YYCURSOR;\n";
-    ++oline;
 }
 
-void Match::emit(ostream &o){
-    if(state->link){
-       o << "\t++YYCURSOR;\n";
-       ++oline;
-       need(o, state->depth);
-    } else {
-       o << "\tyych = *++YYCURSOR;\n";
+void Match::emit(ostream &o, bool &readCh)
+{
+       if (state->link || !readAhead())
+       {
+               /* do not read next char if match */
+               o << "\t++YYCURSOR;\n";
+               readCh = true;
+       }
+       else
+       {
+               o << "\tyych = *++YYCURSOR;\n";
+               readCh = false;
+       }
        ++oline;
-    }
+       if(state->link)
+       {
+               ++oline;
+               need(o, state->depth, readCh);
+       }
 }
 
-void Enter::emit(ostream &o){
-    if(state->link){
-       o << "\t++YYCURSOR;\n";
-       o << "yy" << label << ":\n";
-       oline += 2;
-       need(o, state->depth);
-    } else {
-       o << "\tyych = *++YYCURSOR;\n";
-       o << "yy" << label << ":\n";
-       oline += 2;
-    }
+void Enter::emit(ostream &o, bool &readCh)
+{
+       if(state->link){
+               o << "\t++YYCURSOR;\n";
+               o << "yy" << label << ":\n";
+               oline += 2;
+               need(o, state->depth, readCh);
+       } else {
+               /* we shouldn't need 'rule-following' protection here */
+               o << "\tyych = *++YYCURSOR;\n";
+               o << "yy" << label << ":\n";
+               oline += 2;
+               readCh = false;
+       }
 }
 
-void Save::emit(ostream &o){
-    o << "\tyyaccept = " << selector << ";\n";
-    ++oline;
-    if(state->link){
-       o << "\tYYMARKER = ++YYCURSOR;\n";
+void Save::emit(ostream &o, bool &readCh)
+{
+       o << "\tyyaccept = " << selector << ";\n";
        ++oline;
-       need(o, state->depth);
-    } else {
-       o << "\tyych = *(YYMARKER = ++YYCURSOR);\n";
-       ++oline;
-    }
+       if(state->link){
+               o << "\tYYMARKER = ++YYCURSOR;\n";
+               ++oline;
+               need(o, state->depth, readCh);
+       } else {
+               o << "\tyych = *(YYMARKER = ++YYCURSOR);\n";
+               ++oline;
+               readCh = false;
+       }
 }
 
 Move::Move(State *s) : Action(s) {
     ;
 }
 
-void Move::emit(ostream &o){
+void Move::emit(ostream &o, bool &readCh){
     ;
 }
 
@@ -232,79 +268,96 @@ Accept::Accept(State *x, uint n, uint *s, State **r)
     ;
 }
 
-void Accept::emit(ostream &o){
-    bool first = true;
-    for(uint i = 0; i < nRules; ++i)
-       if(saves[i] != ~0u){
-           if(first){
-               first = false;
-               o << "\tYYCURSOR = YYMARKER;\n";
-               o << "\tswitch(yyaccept){\n";
-               oline += 2;
-           }
-           o << "\tcase " << saves[i] << ":";
-           genGoTo(o, rules[i]);
+void Accept::emit(ostream &o, bool &readCh)
+{
+       bool first = true;
+       for(uint i = 0; i < nRules; ++i)
+       if(saves[i] != ~0u)
+       {
+               if(first)
+               {
+                       first = false;
+                       o << "\tYYCURSOR = YYMARKER;\n";
+                       o << "\tswitch(yyaccept){\n";
+                       oline += 2;
+               }
+               o << "\tcase " << saves[i] << ":";
+               genGoTo(o, state, rules[i], readCh);
+       }
+       if(!first)
+       {
+               o << "\t}\n";
+               ++oline;
        }
-    if(!first)
-    {
-       o << "\t}\n";
-       ++oline;
-    }
 }
 
 Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r) {
     ;
 }
 
-void Rule::emit(ostream &o){
-    uint back = rule->ctx->fixedLength();
-    if(back != ~0u && back > 0u)
-       o << "\tYYCURSOR -= " << back << ";";
-    o << "\n";
-    ++oline;
-    line_source(rule->code->line, o);
-    o << rule->code->text;
-// not sure if we need this or not.    oline += std::count(rule->code->text, rule->code->text + ::strlen(rule->code->text), '\n');
-    o << "\n";
-    ++oline;
-    o << "#line " << ++oline << " \"re2c-output.c\"\n";
-    // TODO: use this once we get an output filename: o << "#line " << ++oline << " \"" << outputFileName << "\"\n";
-//    o << "\n#line " << rule->code->line
-//      << "\n\t" << rule->code->text << "\n";
-}
-
-void doLinear(ostream &o, uint i, Span *s, uint n, State *next){
-    for(;;){
-       State *bg = s[0].to;
-       while(n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1){
-           if(s[1].to == next && n == 3){
-               indent(o, i); genIf(o, "!=", s[0].ub); genGoTo(o, bg);
-               indent(o, i); genGoTo(o, next);
-               return;
-           } else {
-               indent(o, i); genIf(o, "==", s[0].ub); genGoTo(o, s[1].to);
-           }
-           n -= 2; s += 2;
-       }
-       if(n == 1){
-//         if(bg != next){
-               indent(o, i); genGoTo(o, s[0].to);
-//         }
-           return;
-       } else if(n == 2 && bg == next){
-           indent(o, i); genIf(o, ">=", s[0].ub); genGoTo(o, s[1].to);
-           indent(o, i); genGoTo(o, next);
-           return;
-       } else {
-           indent(o, i); genIf(o, "<=", s[0].ub - 1); genGoTo(o, bg);
-           n -= 1; s += 1;
+void Rule::emit(ostream &o, bool &readCh)
+{
+       uint back = rule->ctx->fixedLength();
+       if(back != ~0u && back > 0u) {
+               o << "\tYYCURSOR -= " << back << ";";
        }
-    }
-    indent(o, i); genGoTo(o, next);
+       o << "\n";
+       ++oline;
+       line_source(rule->code->line, o);
+       o << rule->code->text;
+       // not sure if we need this or not.    oline += std::count(rule->code->text, rule->code->text + ::strlen(rule->code->text), '\n');
+       o << "\n";
+       ++oline;
+       o << "#line " << ++oline << " \"re2c-output.c\"\n";
+       // TODO: use this once we get an output filename: o << "#line " << ++oline << " \"" << outputFileName << "\"\n";
+       //    o << "\n#line " << rule->code->line
+       //      << "\n\t" << rule->code->text << "\n";
+}
+
+void doLinear(ostream &o, uint i, Span *s, uint n, State *from, State *next, bool &readCh)
+{
+       for(;;)
+       {
+               State *bg = s[0].to;
+               while(n >= 3 && s[2].to == bg && (s[1].ub - s[0].ub) == 1)
+               {
+                       if(s[1].to == next && n == 3)
+                       {
+                               indent(o, i); genIf(o, "!=", s[0].ub, readCh); genGoTo(o, from, bg, readCh);
+                               indent(o, i); genGoTo(o, from, next, readCh);
+                               return;
+                       }
+                       else
+                       {
+                               indent(o, i); genIf(o, "==", s[0].ub, readCh); genGoTo(o, from, s[1].to, readCh);
+                       }
+                       n -= 2; s += 2;
+               }
+               if(n == 1)
+               {
+//             if(bg != next){
+                               indent(o, i); genGoTo(o, from, s[0].to, readCh);
+//             }
+                       return;
+               }
+               else if(n == 2 && bg == next)
+               {
+                       indent(o, i); genIf(o, ">=", s[0].ub, readCh); genGoTo(o, from, s[1].to, readCh);
+                       indent(o, i); genGoTo(o, from, next, readCh);
+                       return;
+               }
+               else
+               {
+                       indent(o, i); genIf(o, "<=", s[0].ub - 1, readCh); genGoTo(o, from, bg, readCh);
+                       n -= 1; s += 1;
+               }
+       }
+       indent(o, i); genGoTo(o, from, next, readCh);
 }
 
-void Go::genLinear(ostream &o, State *next){
-    doLinear(o, 0, span, nSpans, next);
+void Go::genLinear(ostream &o, State *from, State *next, bool &readCh)
+{
+       doLinear(o, 0, span, nSpans, from, next, readCh);
 }
 
 void genCases(ostream &o, uint lb, Span *s){
@@ -319,394 +372,529 @@ void genCases(ostream &o, uint lb, Span *s){
     }
 }
 
-void Go::genSwitch(ostream &o, State *next){
-    if(nSpans <= 2){
-       genLinear(o, next);
-    } else {
-       State *def = span[nSpans-1].to;
-       Span **sP = new Span*[nSpans-1], **r, **s, **t;
-
-       t = &sP[0];
-       for(uint i = 0; i < nSpans; ++i)
-           if(span[i].to != def)
-               *(t++) = &span[i];
-
-       o << "\tswitch(yych){\n";
-       ++oline;
-       while(t != &sP[0]){
-           r = s = &sP[0];
-           if(*s == &span[0])
-               genCases(o, 0, *s);
-           else
-               genCases(o, (*s)[-1].ub, *s);
-           State *to = (*s)->to;
-           while(++s < t){
-               if((*s)->to == to)
-                   genCases(o, (*s)[-1].ub, *s);
+void Go::genSwitch(ostream &o, State *from, State *next, bool &readCh)
+{
+       if(nSpans <= 2){
+               genLinear(o, from, next, readCh);
+       }
+       else
+       {
+               State *def = span[nSpans-1].to;
+               Span **sP = new Span*[nSpans-1], **r, **s, **t;
+       
+               t = &sP[0];
+               for(uint i = 0; i < nSpans; ++i)
+               {
+                       if(span[i].to != def)
+                       {
+                               *(t++) = &span[i];
+                       }
+               }
+       
+               if (readCh)
+               {
+                       o << "\tswitch((yych = *YYCURSOR)) {\n";
+                       readCh =false;
+               }
                else
-                   *(r++) = *s;
-           }
-           genGoTo(o, to);
-           t = r;
+               {
+                       o << "\tswitch(yych){\n";
+               }
+               ++oline;
+               while(t != &sP[0])
+               {
+                       r = s = &sP[0];
+                       if(*s == &span[0])
+                       genCases(o, 0, *s);
+                       else
+                       genCases(o, (*s)[-1].ub, *s);
+                       State *to = (*s)->to;
+                       while(++s < t)
+                       {
+                               if((*s)->to == to)
+                               {
+                                       genCases(o, (*s)[-1].ub, *s);
+                               }
+                               else
+                               {
+                                       *(r++) = *s;
+                               }
+                       }
+                       genGoTo(o, from, to, readCh);
+                       t = r;
+               }
+               o << "\tdefault:";
+               genGoTo(o, from, def, readCh);
+               o << "\t}\n";
+               ++oline;
+       
+               delete [] sP;
        }
-       o << "\tdefault:";
-       genGoTo(o, def);
-       o << "\t}\n";
-       ++oline;
-
-       delete [] sP;
-    }
 }
 
-void doBinary(ostream &o, uint i, Span *s, uint n, State *next){
-    if(n <= 4){
-       doLinear(o, i, s, n, next);
-    } else {
-       uint h = n/2;
-       indent(o, i); genIf(o, "<=", s[h-1].ub - 1); o << "{\n";
-       ++oline;
-       doBinary(o, i+1, &s[0], h, next);
-       indent(o, i); o << "\t} else {\n";
-       ++oline;
-       doBinary(o, i+1, &s[h], n - h, next);
-       indent(o, i); o << "\t}\n";
-       ++oline;
-    }
+void doBinary(ostream &o, uint i, Span *s, uint n, State *from, State *next, bool &readCh)
+{
+       if(n <= 4)
+       {
+               doLinear(o, i, s, n, from, next, readCh);
+       }
+       else
+       {
+               uint h = n/2;
+               indent(o, i); genIf(o, "<=", s[h-1].ub - 1, readCh); o << "{\n";
+               ++oline;
+               doBinary(o, i+1, &s[0], h, from, next, readCh);
+               indent(o, i); o << "\t} else {\n";
+               ++oline;
+               doBinary(o, i+1, &s[h], n - h, from, next, readCh);
+               indent(o, i); o << "\t}\n";
+               ++oline;
+       }
 }
 
-void Go::genBinary(ostream &o, State *next){
-    doBinary(o, 0, span, nSpans, next);
+void Go::genBinary(ostream &o, State *from, State *next, bool &readCh)
+{
+       doBinary(o, 0, span, nSpans, from, next, readCh);
 }
 
-void Go::genBase(ostream &o, State *next){
-    if(nSpans == 0)
-       return;
-    if(!sFlag){
-       genSwitch(o, next);
-       return;
-    }
-    if(nSpans > 8){
-       Span *bot = &span[0], *top = &span[nSpans-1];
-       uint util;
-       if(bot[0].to == top[0].to){
-           util = (top[-1].ub - bot[0].ub)/(nSpans - 2);
-       } else {
-           if(bot[0].ub > (top[0].ub - top[-1].ub)){
-               util = (top[0].ub - bot[0].ub)/(nSpans - 1);
-           } else {
-               util = top[-1].ub/(nSpans - 1);
-           }
+void Go::genBase(ostream &o, State *from, State *next, bool &readCh)
+{
+       if(nSpans == 0)
+       {
+               return;
        }
-       if(util <= 2){
-           genSwitch(o, next);
-           return;
+       if(!sFlag)
+       {
+               genSwitch(o, from, next, readCh);
+               return;
+       }
+       if(nSpans > 8)
+       {
+               Span *bot = &span[0], *top = &span[nSpans-1];
+               uint util;
+               if(bot[0].to == top[0].to)
+               {
+                       util = (top[-1].ub - bot[0].ub)/(nSpans - 2);
+               }
+               else
+               {
+                       if(bot[0].ub > (top[0].ub - top[-1].ub))
+                       {
+                               util = (top[0].ub - bot[0].ub)/(nSpans - 1);
+                       }
+                       else
+                       {
+                               util = top[-1].ub/(nSpans - 1);
+                       }
+               }
+               if(util <= 2)
+               {
+                       genSwitch(o, from, next, readCh);
+                       return;
+               }
+       }
+       if(nSpans > 5)
+       {
+               genBinary(o, from, next, readCh);
+       }
+       else
+       {
+               genLinear(o, from, next, readCh);
        }
-    }
-    if(nSpans > 5){
-       genBinary(o, next);
-    } else {
-       genLinear(o, next);
-    }
 }
 
-void Go::genGoto(ostream &o, State *next){
-    if(bFlag){
-       for(uint i = 0; i < nSpans; ++i){
-           State *to = span[i].to;
-           if(to && to->isBase){
-               BitMap *b = BitMap::find(to);
-               if(b && matches(b->go, b->on, this, to)){
-                   Go go;
-                   go.span = new Span[nSpans];
-                   go.unmap(this, to);
-                   o << "\tif(yybm[" << b->i << "+yych] & " << (uint) b->m << ")";
-                   genGoTo(o, to);
-                   go.genBase(o, next);
-                   delete [] go.span;
-                   return;
+void Go::genGoto(ostream &o, State *from, State *next, bool &readCh)
+{
+       if(bFlag)
+       {
+               for(uint i = 0; i < nSpans; ++i)
+               {
+                       State *to = span[i].to;
+                       if(to && to->isBase)
+                       {
+                               BitMap *b = BitMap::find(to);
+                               if(b && matches(b->go, b->on, this, to))
+                               {
+                                       Go go;
+                                       go.span = new Span[nSpans];
+                                       go.unmap(this, to);
+                                       o << "\tif(yybm[" << b->i << "+";
+                                       if (readCh)
+                                       {
+                                               o << "(yych = *YYCURSOR)";
+                                       }
+                                       else
+                                       {
+                                               o << "ych";
+                                       }
+                                       o << "] & " << (uint) b->m << ")";
+                                       genGoTo(o, from, to, readCh);
+                                       go.genBase(o, from, next, readCh);
+                                       delete [] go.span;
+                                       return;
+                               }
+                       }
                }
-           }
        }
-    }
-    genBase(o, next);
-}
-
-void State::emit(ostream &o){
-    o << "yy" << label << ":";
-    action->emit(o);
-}
-
-uint merge(Span *x0, State *fg, State *bg){
-    Span *x = x0, *f = fg->go.span, *b = bg->go.span;
-    uint nf = fg->go.nSpans, nb = bg->go.nSpans;
-    State *prev = NULL, *to;
-    // NB: we assume both spans are for same range
-    for(;;){
-       if(f->ub == b->ub){
-           to = f->to == b->to? bg : f->to;
-           if(to == prev){
-               --x;
-           } else {
-               x->to = prev = to;
-           }
-           x->ub = f->ub;
-           ++x; ++f; --nf; ++b; --nb;
-           if(nf == 0 && nb == 0)
-               return x - x0;
-       }
-       while(f->ub < b->ub){
-           to = f->to == b->to? bg : f->to;
-           if(to == prev){
-               --x;
-           } else {
-               x->to = prev = to;
-           }
-           x->ub = f->ub;
-           ++x; ++f; --nf;
-       }
-       while(b->ub < f->ub){
-           to = b->to == f->to? bg : f->to;
-           if(to == prev){
-               --x;
-           } else {
-               x->to = prev = to;
-           }
-           x->ub = b->ub;
-           ++x; ++b; --nb;
+       genBase(o, from, next, readCh);
+}
+
+void State::emit(ostream &o, bool &readCh){
+       o << "yy" << label << ":";
+/*    o << "\nfprintf(stderr, \"<" << label << ">\");\n";*/
+       action->emit(o, readCh);
+}
+
+uint merge(Span *x0, State *fg, State *bg)
+{
+       Span *x = x0, *f = fg->go.span, *b = bg->go.span;
+       uint nf = fg->go.nSpans, nb = bg->go.nSpans;
+       State *prev = NULL, *to;
+       // NB: we assume both spans are for same range
+       for(;;)
+       {
+               if(f->ub == b->ub)
+               {
+                       to = f->to == b->to? bg : f->to;
+                       if(to == prev){
+                               --x;
+                       }
+                       else
+                       {
+                               x->to = prev = to;
+                       }
+                       x->ub = f->ub;
+                       ++x; ++f; --nf; ++b; --nb;
+                       if(nf == 0 && nb == 0)
+                       {
+                               return x - x0;
+                       }
+               }
+               while(f->ub < b->ub)
+               {
+                       to = f->to == b->to? bg : f->to;
+                       if(to == prev)
+                       {
+                               --x;
+                       }
+                       else
+                       {
+                               x->to = prev = to;
+                       }
+                       x->ub = f->ub;
+                       ++x; ++f; --nf;
+               }
+               while(b->ub < f->ub)
+               {
+                       to = b->to == f->to? bg : f->to;
+                       if(to == prev)
+                       {
+                               --x;
+                       }
+                       else
+                       {
+                               x->to = prev = to;
+                       }
+                       x->ub = b->ub;
+                       ++x; ++b; --nb;
+               }
        }
-    }
 }
 
 const uint cInfinity = ~0;
 
 class SCC {
 public:
-    State      **top, **stk;
+       State   **top, **stk;
 public:
-    SCC(uint);
-    ~SCC();
-    void traverse(State*);
+       SCC(uint);
+       ~SCC();
+       void traverse(State*);
 };
 
 SCC::SCC(uint size){
-    top = stk = new State*[size];
+       top = stk = new State*[size];
 }
 
 SCC::~SCC(){
-    delete [] stk;
-}
-
-void SCC::traverse(State *x){
-    *top = x;
-    uint k = ++top - stk;
-    x->depth = k;
-    for(uint i = 0; i < x->go.nSpans; ++i){
-       State *y = x->go.span[i].to;
-       if(y){
-           if(y->depth == 0)
-               traverse(y);
-           if(y->depth < x->depth)
-               x->depth = y->depth;
+       delete [] stk;
+}
+
+void SCC::traverse(State *x)
+{
+       *top = x;
+       uint k = ++top - stk;
+       x->depth = k;
+       for(uint i = 0; i < x->go.nSpans; ++i)
+       {
+               State *y = x->go.span[i].to;
+               if(y)
+               {
+                       if(y->depth == 0)
+                       {
+                               traverse(y);
+                       }
+                       if(y->depth < x->depth)
+                       {
+                               x->depth = y->depth;
+                       }
+               }
        }
-    }
-    if(x->depth == k)
-       do {
-           (*--top)->depth = cInfinity;
-           (*top)->link = x;
-       } while(*top != x);
-}
-
-uint maxDist(State *s){
-    uint mm = 0;
-    for(uint i = 0; i < s->go.nSpans; ++i){
-       State *t = s->go.span[i].to;
-       if(t){
-           uint m = 1;
-           if(!t->link)
-               m += maxDist(t);
-           if(m > mm)
-               mm = m;
+       if(x->depth == k)
+       {
+               do
+               {
+                       (*--top)->depth = cInfinity;
+                       (*top)->link = x;
+               } while(*top != x);
        }
-    }
-    return mm;
 }
 
-void calcDepth(State *head){
-    State *t;
-    for(State *s = head; s; s = s->next){
-       if(s->link == s){
-           for(uint i = 0; i < s->go.nSpans; ++i){
-               t = s->go.span[i].to;
-               if(t && t->link == s)
-                   goto inSCC;
-           }
-           s->link = NULL;
-       } else {
-       inSCC:
-           s->depth = maxDist(s);
+uint maxDist(State *s)
+{
+       uint mm = 0;
+       for(uint i = 0; i < s->go.nSpans; ++i)
+       {
+               State *t = s->go.span[i].to;
+               if(t)
+               {
+                       uint m = 1;
+                       if(!t->link)
+                       {
+                               m += maxDist(t);
+                       }
+                       if(m > mm)
+                       {
+                               mm = m;
+                       }
+               }
+       }
+       return mm;
+}
+
+void calcDepth(State *head)
+{
+       State *t;
+       for(State *s = head; s; s = s->next)
+       {
+               if(s->link == s){
+                       for(uint i = 0; i < s->go.nSpans; ++i)
+                       {
+                               t = s->go.span[i].to;
+                               if(t && t->link == s)
+                               {
+                                       goto inSCC;
+                               }
+                       }
+                       s->link = NULL;
+               }else
+               {
+                       inSCC:
+                       s->depth = maxDist(s);
+               }
        }
-    }
 }
  
-void DFA::findSCCs(){
-    SCC scc(nStates);
-    State *s;
+void DFA::findSCCs()
+{
+       SCC scc(nStates);
+       State *s;
+
+       for(s = head; s; s = s->next)
+       {
+               s->depth = 0;
+               s->link = NULL;
+       }
 
-    for(s = head; s; s = s->next){
-       s->depth = 0;
-       s->link = NULL;
-    }
+       for(s = head; s; s = s->next)
+       {
+               if(!s->depth)
+               {
+                       scc.traverse(s);
+               }
+       }
 
-    for(s = head; s; s = s->next)
-       if(!s->depth)
-           scc.traverse(s);
-
-    calcDepth(head);
-}
-
-void DFA::split(State *s){
-    State *move = new State;
-    (void) new Move(move);
-    addState(&s->next, move);
-    move->link = s->link;
-    move->rule = s->rule;
-    move->go = s->go;
-    s->rule = NULL;
-    s->go.nSpans = 1;
-    s->go.span = new Span[1];
-    s->go.span[0].ub = ubChar;
-    s->go.span[0].to = move;
-}
-
-void DFA::emit(ostream &o){
-    static uint label = 0;
-    State *s;
-    uint i;
-
-    findSCCs();
-    head->link = head;
-    head->depth = maxDist(head);
-
-    uint nRules = 0;
-    for(s = head; s; s = s->next)
-       if(s->rule && s->rule->accept >= nRules)
-               nRules = s->rule->accept + 1;
-
-    uint nSaves = 0;
-    uint *saves = new uint[nRules];
-    memset(saves, ~0, (nRules)*sizeof(*saves));
-
-    // mark backtracking points
-    for(s = head; s; s = s->next){
-       RuleOp *ignore = NULL;
-       if(s->rule){
-           for(i = 0; i < s->go.nSpans; ++i)
-               if(s->go.span[i].to && !s->go.span[i].to->rule){
-                   delete s->action;
-                   if(saves[s->rule->accept] == ~0u)
-                       saves[s->rule->accept] = nSaves++;
-                   (void) new Save(s, saves[s->rule->accept]);
-                   continue;
+       calcDepth(head);
+}
+
+void DFA::split(State *s)
+{
+       State *move = new State;
+       (void) new Move(move);
+       addState(&s->next, move);
+       move->link = s->link;
+       move->rule = s->rule;
+       move->go = s->go;
+       s->rule = NULL;
+       s->go.nSpans = 1;
+       s->go.span = new Span[1];
+       s->go.span[0].ub = ubChar;
+       s->go.span[0].to = move;
+}
+
+void DFA::emit(ostream &o)
+{
+       static uint label = 0;
+       State *s;
+       uint i;
+
+       findSCCs();
+       head->link = head;
+       head->depth = maxDist(head);
+
+       uint nRules = 0;
+       for(s = head; s; s = s->next)
+       {
+               if(s->rule && s->rule->accept >= nRules)
+               {
+                       nRules = s->rule->accept + 1;
                }
-           ignore = s->rule;
        }
-    }
 
-    // insert actions
-    State **rules = new State*[nRules];
-    memset(rules, 0, (nRules)*sizeof(*rules));
-    State *accept = NULL;
-    for(s = head; s; s = s->next){
-       State *ow;
-       if(!s->rule){
-           ow = accept;
-       } else {
-           if(!rules[s->rule->accept]){
-               State *n = new State;
-               (void) new Rule(n, s->rule);
-               rules[s->rule->accept] = n;
-               addState(&s->next, n);
-           }
-           ow = rules[s->rule->accept];
-       }
-       for(i = 0; i < s->go.nSpans; ++i)
-           if(!s->go.span[i].to){
-               if(!ow){
-                   ow = accept = new State;
-                   (void) new Accept(accept, nRules, saves, rules);
-                   addState(&s->next, accept);
+       uint nSaves = 0;
+       uint *saves = new uint[nRules];
+       memset(saves, ~0, (nRules)*sizeof(*saves));
+
+       // mark backtracking points
+       for(s = head; s; s = s->next)
+       {
+               RuleOp *ignore = NULL;
+               if(s->rule)
+               {
+                       for(i = 0; i < s->go.nSpans; ++i)
+                       {
+                               if(s->go.span[i].to && !s->go.span[i].to->rule){
+                                       delete s->action;
+                                       if(saves[s->rule->accept] == ~0u)
+                                       {
+                                               saves[s->rule->accept] = nSaves++;
+                                       }
+                                       (void) new Save(s, saves[s->rule->accept]);
+                                       continue;
+                               }
+                       }
+                       ignore = s->rule;
                }
-               s->go.span[i].to = ow;
-           }
-    }
+       }
 
-    // split ``base'' states into two parts
-    for(s = head; s; s = s->next){
-       s->isBase = false;
-       if(s->link){
-           for(i = 0; i < s->go.nSpans; ++i){
-               if(s->go.span[i].to == s){
-                   s->isBase = true;
-                   split(s);
-                   if(bFlag)
-                       BitMap::find(&s->next->go, s);
-                   s = s->next;
-                   break;
+       // insert actions
+       State **rules = new State*[nRules];
+       memset(rules, 0, (nRules)*sizeof(*rules));
+       State *accept = NULL;
+       for(s = head; s; s = s->next)
+       {
+               State *ow;
+               if(!s->rule)
+               {
+                       ow = accept;
+               }
+               else
+               {
+                       if(!rules[s->rule->accept])
+                       {
+                               State *n = new State;
+                               (void) new Rule(n, s->rule);
+                               rules[s->rule->accept] = n;
+                               addState(&s->next, n);
+                       }
+                       ow = rules[s->rule->accept];
+               }
+               for(i = 0; i < s->go.nSpans; ++i)
+               if(!s->go.span[i].to)
+               {
+                       if(!ow)
+                       {
+                               ow = accept = new State;
+                               (void) new Accept(accept, nRules, saves, rules);
+                               addState(&s->next, accept);
+                       }
+                       s->go.span[i].to = ow;
                }
-           }
        }
-    }
 
-    // find ``base'' state, if possible
-    Span *span = new Span[ubChar - lbChar];
-    for(s = head; s; s = s->next){
-       if(!s->link){
-           for(i = 0; i < s->go.nSpans; ++i){
-               State *to = s->go.span[i].to;
-               if(to && to->isBase){
-                   to = to->go.span[0].to;
-                   uint nSpans = merge(span, s, to);
-                   if(nSpans < s->go.nSpans){
-                       delete [] s->go.span;
-                       s->go.nSpans = nSpans;
-                       s->go.span = new Span[nSpans];
-                       memcpy(s->go.span, span, nSpans*sizeof(Span));
-                   }
-                   break;
+       // split ``base'' states into two parts
+       for(s = head; s; s = s->next)
+       {
+               s->isBase = false;
+               if(s->link)
+               {
+                       for(i = 0; i < s->go.nSpans; ++i)
+                       {
+                               if(s->go.span[i].to == s){
+                                       s->isBase = true;
+                                       split(s);
+                                       if(bFlag)
+                                       {
+                                               BitMap::find(&s->next->go, s);
+                                       }
+                                       s = s->next;
+                                       break;
+                               }
+                       }
                }
-           }
        }
-    }
-    delete [] span;
 
-    delete head->action;
+       // find ``base'' state, if possible
+       Span *span = new Span[ubChar - lbChar];
+       for(s = head; s; s = s->next)
+       {
+               if(!s->link)
+               {
+                       for(i = 0; i < s->go.nSpans; ++i)
+                       {
+                               State *to = s->go.span[i].to;
+                               if(to && to->isBase)
+                               {
+                                       to = to->go.span[0].to;
+                                       uint nSpans = merge(span, s, to);
+                                       if(nSpans < s->go.nSpans)
+                                       {
+                                               delete [] s->go.span;
+                                               s->go.nSpans = nSpans;
+                                               s->go.span = new Span[nSpans];
+                                               memcpy(s->go.span, span, nSpans*sizeof(Span));
+                                       }
+                                       break;
+                               }
+                       }
+               }
+       }
+       delete [] span;
 
-    ++oline;
-    o << "\n#line " << ++oline << " \"re2c-output.c\"\n";
-    // TODO: Switch to use this once we have an outputFileName: o << "\n#line " << ++oline << " \"" << outputFileName << "\"\n";
-    o << "{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n";
-    oline += 3;
+       delete head->action;
 
+       ++oline;
+       o << "\n#line " << ++oline << " \"re2c-output.c\"\n";
+       // TODO: Switch to use this once we have an outputFileName: o << "\n#line " << ++oline << " \"" << outputFileName << "\"\n";
+       o << "{\n\tYYCTYPE yych;\n\tunsigned int yyaccept;\n";
+       oline += 3;
 
-    if(bFlag)
-       BitMap::gen(o, lbChar, ubChar);
 
-    o << "\tgoto yy" << label << ";\n";
-    ++oline;
-    (void) new Enter(head, label++);
+       if(bFlag)
+       {
+               BitMap::gen(o, lbChar, ubChar);
+       }
 
-    for(s = head; s; s = s->next)
-       s->label = label++;
+       o << "\tgoto yy" << label << ";\n";
+       ++oline;
+       (void) new Enter(head, label++);
 
-    for(s = head; s; s = s->next){
-       s->emit(o);
-       s->go.genGoto(o, s->next);
-    }
-    o << "}\n";
-    ++oline;
+       for(s = head; s; s = s->next)
+       {
+               s->label = label++;
+       }
+
+       for(s = head; s; s = s->next)
+       {
+               bool readCh = false;
+               s->emit(o, readCh);
+               s->go.genGoto(o, s, s->next, readCh);
+       }
+       o << "}\n";
+       ++oline;
 
-    BitMap::first = NULL;
+       BitMap::first = NULL;
 
-    delete [] saves;
-    delete [] rules;
+       delete [] saves;
+       delete [] rules;
 }
diff --git a/dfa.h b/dfa.h
index 6ca66360899573a02af6036ef1b2341bac6f2a04..6bd782482d1a47da639fd6701ba629553a0c3afb 100644 (file)
--- a/dfa.h
+++ b/dfa.h
@@ -16,13 +16,17 @@ public:
     State              *state;
 public:
     Action(State*);
-    virtual void emit(ostream&) = 0;
+    virtual void emit(ostream&, bool&) = 0;
+    virtual bool isRule() const;
+    virtual bool isMatch() const;
+    virtual bool readAhead() const;
 };
 
 class Match: public Action {
 public:
     Match(State*);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
+    bool isMatch() const;
 };
 
 class Enter: public Action {
@@ -30,7 +34,7 @@ public:
     uint               label;
 public:
     Enter(State*, uint);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
 };
 
 class Save: public Match {
@@ -38,13 +42,14 @@ public:
     uint               selector;
 public:
     Save(State*, uint);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
+    bool isMatch() const;
 };
 
 class Move: public Action {
 public:
     Move(State*);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
 };
 
 class Accept: public Action {
@@ -54,7 +59,7 @@ public:
     State              **rules;
 public:
     Accept(State*, uint, uint*, State**);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
 };
 
 class Rule: public Action {
@@ -62,7 +67,8 @@ public:
     RuleOp             *rule;
 public:
     Rule(State*, RuleOp*);
-    void emit(ostream&);
+    void emit(ostream&, bool&);
+    bool isRule() const;
 };
 
 class Span {
@@ -78,11 +84,11 @@ public:
     uint               nSpans;
     Span               *span;
 public:
-    void genGoto(ostream&, State*);
-    void genBase(ostream&, State*);
-    void genLinear(ostream&, State*);
-    void genBinary(ostream&, State*);
-    void genSwitch(ostream&, State*);
+    void genGoto(ostream&, State *from, State*, bool &readCh);
+    void genBase(ostream&, State *from, State*, bool &readCh);
+    void genLinear(ostream&, State *from, State*, bool &readCh);
+    void genBinary(ostream&, State *from, State*, bool &readCh);
+    void genSwitch(ostream&, State *from, State*, bool &readCh);
     void compact();
     void unmap(Go*, State*);
 };
@@ -102,7 +108,7 @@ public:
 public:
     State();
     ~State();
-    void emit(ostream&);
+    void emit(ostream&, bool&);
     friend ostream& operator<<(ostream&, const State&);
     friend ostream& operator<<(ostream&, const State*);
 };
@@ -132,15 +138,33 @@ inline Action::Action(State *s) : state(s) {
     s->action = this;
 }
 
+inline bool Action::isRule() const
+       { return false; }
+
+inline bool Action::isMatch() const
+       { return false; }
+
+inline bool Action::readAhead() const
+       { return !isMatch() || !state->next->action->isRule(); }
+
 inline Match::Match(State *s) : Action(s)
     { }
 
+inline bool Match::isMatch() const
+       { return true; }
+
 inline Enter::Enter(State *s, uint l) : Action(s), label(l)
     { }
 
 inline Save::Save(State *s, uint i) : Match(s), selector(i)
     { }
 
+inline bool Save::isMatch() const
+       { return false; }
+
+inline bool Rule::isRule() const
+       { return true; }
+
 inline ostream& operator<<(ostream &o, const State *s)
     { return o << *s; }
 
index add18f5dca72dbcf100bdfeff487b8258fca23a6..2963b6970701be29822a048bfaa7fecb0fcae7de 100644 (file)
@@ -24,8 +24,8 @@ flexible.
 make re2c
 #regenerate file scanner.cc
 rm -f scanner.cc
-make scanner.cc
-rm -f re2c
+./re2c scanner.re > scanner.cc
+rm -f re2c scanner.o
 make
 
 %install