-/* 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>
#line 92 "scanner.re"
{ goto echo; }
#line 26 "re2c-output.c"
-yy4: yych = *++YYCURSOR;
+yy4: ++YYCURSOR;
goto yy5;
yy5:
#line 88 "scanner.re"
yy12: yych = *++YYCURSOR;
if(yych != 'c') goto yy8;
goto yy13;
-yy13: yych = *++YYCURSOR;
+yy13: ++YYCURSOR;
goto yy14;
yy14:
#line 85 "scanner.re"
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"
goto yy20;
yy30: yych = *++YYCURSOR;
goto yy22;
-yy31: yych = *++YYCURSOR;
+yy31: ++YYCURSOR;
+ yych = *YYCURSOR;
goto yy42;
yy32:
#line 149 "scanner.re"
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"
goto scan;
}
#line 200 "re2c-output.c"
-yy37: yych = *++YYCURSOR;
+yy37: ++YYCURSOR;
goto yy38;
yy38:
#line 160 "scanner.re"
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;
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;
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;
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;
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;
goto yy76;
}
}
-yy76: yych = *++YYCURSOR;
+yy76: ++YYCURSOR;
goto yy77;
yy77:
#line 167 "scanner.re"
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"
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;
comment:
-#line 485 "re2c-output.c"
+#line 499 "re2c-output.c"
{
YYCTYPE yych;
unsigned int yyaccept;
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"
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"
goto scan;
else
goto comment; }
-#line 538 "re2c-output.c"
+#line 552 "re2c-output.c"
}
#line 195 "scanner.re"
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){
;
}
;
}
-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){
}
}
-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;
}