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.
-/* 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>
yych = *(YYMARKER = ++YYCURSOR);
if(yych == '*') goto yy16;
yy3:
-#line 165 "scanner.re"
+#line 172 "scanner.re"
{
goto echo;
}
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));
#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
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;
}
yy14:
++YYCURSOR;
-#line 132 "scanner.re"
+#line 139 "scanner.re"
{
if (ignore_eoc) {
ignore_eoc = false;
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;
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;
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;
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"
}
goto value;
}
-#line 332 "scanner.cc"
+#line 339 "scanner.cc"
{
YYCTYPE yych;
unsigned int yyaccept = 0;
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);
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;
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;
}
}
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);
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);
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);
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);
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;
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);
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);
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);
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);
}
}
++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;
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);
++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);
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);
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);
}
}
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) {
}
}
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;
if(yych == 0x0A) goto yy199;
goto yy203;
}
-#line 329 "scanner.re"
+#line 336 "scanner.re"
}
}
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";
}
if (state->link)
{
- if (bUseYYMarker)
+ if (bUsedYYMarker)
{
o << indent(ind) << "YYMARKER = ++YYCURSOR;\n";
}
}
else
{
- if (bUseYYMarker)
+ if (bUsedYYMarker)
{
o << indent(ind) << "yych = *(YYMARKER = ++YYCURSOR);\n";
}
if (first)
{
first = false;
- bUseYYMarker = true;
+ bUsedYYMarker = true;
o << indent(ind) << "YYCURSOR = YYMARKER;\n";
if (bUsedYYAccept && cases > 1)
{
uint nRules = 0;
- maxFill = 1;
for (s = head; s; s = s->next)
{
s->depth = maxDist(s);
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;
extern bool bUseStateNext;
extern bool bWroteGetState;
extern bool bUseYYFill;
-extern bool bUseYYMarker;
extern uint asc2ebc[256];
extern uint ebc2asc[256];
<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>
<p>re2c - convert regular expressions to C/C++</p>
<a name="lbAC" id="lbAC"> </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"> </a>
<h2>DESCRIPTION</h2>
<p><b>re2c</b> is a preprocessor that generates C-based recognizers from
</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>
<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
<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>
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
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;
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"),
"-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"
"-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"
eFlag = true;
break;
- case 's':
- sFlag = true;
- break;
-
case 'd':
dFlag = true;
break;
case 'f':
fFlag = true;
+ tFlag = true;
break;
case 'i':
outputFileName = opt_arg;
break;
+ case 's':
+ sFlag = true;
+ break;
+
+ case 't':
+ tFlag = true;
+ break;
+
case 'v':
cout << "re2c " << PACKAGE_VERSION << "\n";
return 2;
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";
next_fill_index = 0;
Symbol::ClearTable();
bWroteGetState = false;
+ bUsedYYMaxFill = false;
}
+ bLastPass = true;
parse(scanner, output);
return 0;
}
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
.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.
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
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
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.
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" {
--- /dev/null
+/* Generated by re2c */
+#line 1 "error13.re"
+#define YYMAXFILL 1
+
+re2c: error: line 0, column 1: found scanner block after YYMAXFILL declaration
--- /dev/null
+/*!max:re2c */
+
+/*!re2c
+ "ABC" { return 1; }
+ "ABD" { return 2; }
+ [^] { return 0; }
+*/
--- /dev/null
+/* 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"
+
--- /dev/null
+/*!max:re2c */
+
+/*!re2c
+ "ABC" { return 1; }
+ "ABD" { return 2; }
+ [^] { return 0; }
+*/
--- /dev/null
+/* 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
--- /dev/null
+/*!re2c
+ "ABC" { return 1; }
+ "ABD" { return 2; }
+ [^] { return 0; }
+*/
+
+/*!max:re2c */
+
+/*!max:re2c */
--- /dev/null
+re2c: error: line 5, column 1: cannot generate YYMAXFILL twice
--- /dev/null
+/*!re2c
+ "ABC" { return 1; }
+ "ABD" { return 2; }
+ [^] { return 0; }
+*/
+
+/*!max:re2c */
+
+/*!max:re2c */