A FILE* to which trace output should be written.
-** If NULL, then tracing is turned off.
-**
A prefix string written at the beginning of every
-** line of trace output. If NULL, then tracing is
-** turned off.
-**
-**
-** Outputs:
-** None.
-*/
-void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
- yyTraceFILE = TraceFILE;
- yyTracePrompt = zTracePrompt;
- if( yyTraceFILE==0 ) yyTracePrompt = 0;
- else if( yyTracePrompt==0 ) yyTraceFILE = 0;
-}
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing shifts, the names of all terminals and nonterminals
-** are required. The following table supplies these names */
-static const char *const yyTokenName[] = {
-%%
-};
-#endif /* NDEBUG */
-
-#ifndef NDEBUG
-/* For tracing reduce actions, the names of all rules are required.
-*/
-static const char *const yyRuleName[] = {
-%%
-};
-#endif /* NDEBUG */
-
-#if YYSTACKDEPTH<=0
-/*
-** Try to increase the size of the parser stack.
-*/
-static void yyGrowStack(yyParser *p){
- int newSize;
- yyStackEntry *pNew;
-
- newSize = p->yystksz*2 + 100;
- pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
- if( pNew ){
- p->yystack = pNew;
- p->yystksz = newSize;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
- yyTracePrompt, p->yystksz);
- }
-#endif
- }
-}
-#endif
-
-/*
-** This function allocates a new parser.
-** The only argument is a pointer to a function which works like
-** malloc.
-**
-** Inputs:
-** A pointer to the function used to allocate memory.
-**
-** Outputs:
-** A pointer to a parser. This pointer is used in subsequent calls
-** to Parse and ParseFree.
-*/
-void *ParseAlloc(void *(*mallocProc)(size_t)){
- yyParser *pParser;
- pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
- if( pParser ){
- pParser->yyidx = -1;
-#if YYSTACKDEPTH<=0
- yyGrowStack(pParser);
-#endif
- }
- return pParser;
-}
-
-/* The following function deletes the value associated with a
-** symbol. The symbol can be either a terminal or nonterminal.
-** "yymajor" is the symbol code, and "yypminor" is a pointer to
-** the value.
-*/
-static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
- switch( yymajor ){
- /* Here is inserted the actions which take place when a
- ** terminal or non-terminal is destroyed. This can happen
- ** when the symbol is popped from the stack during a
- ** reduce or during error processing or when a parser is
- ** being destroyed before it is finished parsing.
- **
- ** Note: during a reduce, the only symbols destroyed are those
- ** which appear on the RHS of the rule, but which are not used
- ** inside the C code.
- */
-%%
- default: break; /* If no destructor action specified: do nothing */
- }
-}
-
-/*
-** Pop the parser's stack once.
-**
-** If there is a destructor routine associated with the token which
-** is popped from the stack, then call it.
-**
-** Return the major token number for the symbol popped.
-*/
-static int yy_pop_parser_stack(yyParser *pParser){
- YYCODETYPE yymajor;
- yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
-
- if( pParser->yyidx<0 ) return 0;
-#ifndef NDEBUG
- if( yyTraceFILE && pParser->yyidx>=0 ){
- fprintf(yyTraceFILE,"%sPopping %s\n",
- yyTracePrompt,
- yyTokenName[yytos->major]);
- }
-#endif
- yymajor = yytos->major;
- yy_destructor( yymajor, &yytos->minor);
- pParser->yyidx--;
- return yymajor;
-}
-
-/*
-** Deallocate and destroy a parser. Destructors are all called for
-** all stack elements before shutting the parser down.
-**
-** Inputs:
-**
-**
A pointer to the parser. This should be a pointer
-** obtained from ParseAlloc.
-**
A pointer to a function used to reclaim memory obtained
-** from malloc.
-**
-*/
-void ParseFree(
- void *p, /* The parser to be deleted */
- void (*freeProc)(void*) /* Function used to reclaim memory */
-){
- yyParser *pParser = (yyParser*)p;
- if( pParser==0 ) return;
- while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
-#if YYSTACKDEPTH<=0
- free(pParser->yystack);
-#endif
- (*freeProc)((void*)pParser);
-}
-
-/*
-** Find the appropriate action for a parser given the terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_shift_action(
- yyParser *pParser, /* The parser */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
- int stateno = pParser->yystack[pParser->yyidx].stateno;
-
- if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
- return yy_default[stateno];
- }
- if( iLookAhead==YYNOCODE ){
- return YY_NO_ACTION;
- }
- i += iLookAhead;
- if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
- if( iLookAhead>0 ){
-#ifdef YYFALLBACK
- int iFallback; /* Fallback token */
- if( iLookAhead %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
- }
-#endif
- return yy_find_shift_action(pParser, iFallback);
- }
-#endif
-#ifdef YYWILDCARD
- {
- int j = i - iLookAhead + YYWILDCARD;
- if( j>=0 && j %s\n",
- yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
- }
-#endif /* NDEBUG */
- return yy_action[j];
- }
- }
-#endif /* YYWILDCARD */
- }
- return yy_default[stateno];
- }else{
- return yy_action[i];
- }
-}
-
-/*
-** Find the appropriate action for a parser given the non-terminal
-** look-ahead token iLookAhead.
-**
-** If the look-ahead token is YYNOCODE, then check to see if the action is
-** independent of the look-ahead. If it is, return the action, otherwise
-** return YY_NO_ACTION.
-*/
-static int yy_find_reduce_action(
- int stateno, /* Current state number */
- YYCODETYPE iLookAhead /* The look-ahead token */
-){
- int i;
- assert( stateno<=YY_REDUCE_MAX );
- i = yy_reduce_ofst[stateno];
- assert( i!=YY_REDUCE_USE_DFLT );
- assert( iLookAhead!=YYNOCODE );
- i += iLookAhead;
- assert( i>=0 && iyyidx--;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will execute if the parser
- ** stack every overflows */
-%%
- ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
-}
-
-/*
-** Perform a shift action.
-*/
-static void yy_shift(
- yyParser *yypParser, /* The parser to be shifted */
- int yyNewState, /* The new state to shift in */
- int yyMajor, /* The major token to shift in */
- YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
-){
- yyStackEntry *yytos;
- yypParser->yyidx++;
-#if YYSTACKDEPTH>0
- if( yypParser->yyidx>=YYSTACKDEPTH ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
-#else
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyGrowStack(yypParser);
- if( yypParser->yyidx>=yypParser->yystksz ){
- yyStackOverflow(yypParser, yypMinor);
- return;
- }
- }
-#endif
- yytos = &yypParser->yystack[yypParser->yyidx];
- yytos->stateno = yyNewState;
- yytos->major = yyMajor;
- yytos->minor = *yypMinor;
-#ifndef NDEBUG
- if( yyTraceFILE && yypParser->yyidx>0 ){
- int i;
- fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
- fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
- for(i=1; i<=yypParser->yyidx; i++)
- fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
- fprintf(yyTraceFILE,"\n");
- }
-#endif
-}
-
-/* The following table contains information about every rule that
-** is used during the reduce.
-*/
-static const struct {
- YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
- unsigned char nrhs; /* Number of right-hand side symbols in the rule */
-} yyRuleInfo[] = {
-%%
-};
-
-static void yy_accept(yyParser*); /* Forward Declaration */
-
-/*
-** Perform a reduce action and the shift that must immediately
-** follow the reduce.
-*/
-static void yy_reduce(
- yyParser *yypParser, /* The parser */
- int yyruleno /* Number of the rule by which to reduce */
-){
- int yygoto; /* The next state */
- int yyact; /* The next action */
- YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
- yyStackEntry *yymsp; /* The top of the parser's stack */
- int yysize; /* Amount to pop the stack */
- ParseARG_FETCH;
- yymsp = &yypParser->yystack[yypParser->yyidx];
-#ifndef NDEBUG
- if( yyTraceFILE && yyruleno>=0
- && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
- fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
- yyRuleName[yyruleno]);
- }
-#endif /* NDEBUG */
-
- /* Silence complaints from purify about yygotominor being uninitialized
- ** in some cases when it is copied into the stack after the following
- ** switch. yygotominor is uninitialized when a rule reduces that does
- ** not set the value of its left-hand side nonterminal. Leaving the
- ** value of the nonterminal uninitialized is utterly harmless as long
- ** as the value is never used. So really the only thing this code
- ** accomplishes is to quieten purify.
- **
- ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
- ** without this code, their parser segfaults. I'm not sure what there
- ** parser is doing to make this happen. This is the second bug report
- ** from wireshark this week. Clearly they are stressing Lemon in ways
- ** that it has not been previously stressed... (SQLite ticket #2172)
- */
- memset(&yygotominor, 0, sizeof(yygotominor));
-
-
- switch( yyruleno ){
- /* Beginning here are the reduction cases. A typical example
- ** follows:
- ** case 0:
- ** #line
- ** { ... } // User supplied code
- ** #line
- ** break;
- */
-%%
- };
- yygoto = yyRuleInfo[yyruleno].lhs;
- yysize = yyRuleInfo[yyruleno].nrhs;
- yypParser->yyidx -= yysize;
- yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
- if( yyact < YYNSTATE ){
-#ifdef NDEBUG
- /* If we are not debugging and the reduce action popped at least
- ** one element off the stack, then we can push the new element back
- ** onto the stack here, and skip the stack overflow test in yy_shift().
- ** That gives a significant speed improvement. */
- if( yysize ){
- yypParser->yyidx++;
- yymsp -= yysize-1;
- yymsp->stateno = yyact;
- yymsp->major = yygoto;
- yymsp->minor = yygotominor;
- }else
-#endif
- {
- yy_shift(yypParser,yyact,yygoto,&yygotominor);
- }
- }else{
- assert( yyact == YYNSTATE + YYNRULE + 1 );
- yy_accept(yypParser);
- }
-}
-
-/*
-** The following code executes when the parse fails
-*/
-static void yy_parse_failed(
- yyParser *yypParser /* The parser */
-){
- ParseARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser fails */
-%%
- ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/*
-** The following code executes when a syntax error first occurs.
-*/
-static void yy_syntax_error(
- yyParser *yypParser, /* The parser */
- int yymajor, /* The major type of the error token */
- YYMINORTYPE yyminor /* The minor type of the error token */
-){
- ParseARG_FETCH;
-#define TOKEN (yyminor.yy0)
-%%
- ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/*
-** The following is executed when the parser accepts
-*/
-static void yy_accept(
- yyParser *yypParser /* The parser */
-){
- ParseARG_FETCH;
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
- }
-#endif
- while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
- /* Here code is inserted which will be executed whenever the
- ** parser accepts */
-%%
- ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
-}
-
-/* The main parser program.
-** The first argument is a pointer to a structure obtained from
-** "ParseAlloc" which describes the current state of the parser.
-** The second argument is the major token number. The third is
-** the minor token. The fourth optional argument is whatever the
-** user wants (and specified in the grammar) and is available for
-** use by the action routines.
-**
-** Inputs:
-**
-**
A pointer to the parser (an opaque structure.)
-**
The major token number.
-**
The minor token number.
-**
An option argument of a grammar-specified type.
-**
-**
-** Outputs:
-** None.
-*/
-void Parse(
- void *yyp, /* The parser */
- int yymajor, /* The major token code number */
- ParseTOKENTYPE yyminor /* The value for the token */
- ParseARG_PDECL /* Optional %extra_argument parameter */
-){
- YYMINORTYPE yyminorunion;
- int yyact; /* The parser action. */
- int yyendofinput; /* True if we are at the end of input */
-#ifdef YYERRORSYMBOL
- int yyerrorhit = 0; /* True if yymajor has invoked an error */
-#endif
- yyParser *yypParser; /* The parser */
-
- /* (re)initialize the parser, if necessary */
- yypParser = (yyParser*)yyp;
- if( yypParser->yyidx<0 ){
-#if YYSTACKDEPTH<=0
- if( yypParser->yystksz <=0 ){
- memset(&yyminorunion, 0, sizeof(yyminorunion));
- yyStackOverflow(yypParser, &yyminorunion);
- return;
- }
-#endif
- yypParser->yyidx = 0;
- yypParser->yyerrcnt = -1;
- yypParser->yystack[0].stateno = 0;
- yypParser->yystack[0].major = 0;
- }
- yyminorunion.yy0 = yyminor;
- yyendofinput = (yymajor==0);
- ParseARG_STORE;
-
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
-
- do{
- yyact = yy_find_shift_action(yypParser,yymajor);
- if( yyactyyerrcnt--;
- yymajor = YYNOCODE;
- /* [RH] If we can reduce the stack now, do it. Otherwise, constructs */
- /* like "include " won't work because the next token after */
- /* the include will be shifted before the include is reduced. Then the */
- /* parser will act as if that token had been the first one in the */
- /* included file. */
- while( yypParser->yyidx>= 0 && (yyact = yy_find_shift_action(yypParser,YYNOCODE)) < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
- }
- }else if( yyact < YYNSTATE + YYNRULE ){
- yy_reduce(yypParser,yyact-YYNSTATE);
- }else{
-#ifdef YYERRORSYMBOL
- int yymx;
-#endif
- assert( yyact == YY_ERROR_ACTION );
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
- }
-#endif
-#ifdef YYERRORSYMBOL
- /* A syntax error has occurred.
- ** The response to an error depends upon whether or not the
- ** grammar defines an error token "ERROR".
- **
- ** This is what we do if the grammar does define ERROR:
- **
- ** * Call the %syntax_error function.
- **
- ** * Begin popping the stack until we enter a state where
- ** it is legal to shift the error symbol, then shift
- ** the error symbol.
- **
- ** * Set the error count to three.
- **
- ** * Begin accepting and shifting new tokens. No new error
- ** processing will occur until three tokens have been
- ** shifted successfully.
- **
- */
- if( yypParser->yyerrcnt<0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yymx = yypParser->yystack[yypParser->yyidx].major;
- if( yymx==YYERRORSYMBOL || yyerrorhit ){
-#ifndef NDEBUG
- if( yyTraceFILE ){
- fprintf(yyTraceFILE,"%sDiscard input token %s\n",
- yyTracePrompt,yyTokenName[yymajor]);
- }
-#endif
- yy_destructor(yymajor,&yyminorunion);
- yymajor = YYNOCODE;
- }else{
- while(
- yypParser->yyidx >= 0 &&
- yymx != YYERRORSYMBOL &&
- (yyact = yy_find_reduce_action(
- yypParser->yystack[yypParser->yyidx].stateno,
- YYERRORSYMBOL)) >= YYNSTATE
- ){
- yy_pop_parser_stack(yypParser);
- }
- if( yypParser->yyidx < 0 || yymajor==0 ){
- yy_destructor(yymajor,&yyminorunion);
- yy_parse_failed(yypParser);
- yymajor = YYNOCODE;
- }else if( yymx!=YYERRORSYMBOL ){
- YYMINORTYPE u2;
- u2.YYERRSYMDT = 0;
- yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
- }
- }
- yypParser->yyerrcnt = 3;
- yyerrorhit = 1;
-#else /* YYERRORSYMBOL is not defined */
- /* This is what we do if the grammar does not define ERROR:
- **
- ** * Report an error message, and throw away the input token.
- **
- ** * If the input token is $, then fail the parse.
- **
- ** As before, subsequent error messages are suppressed until
- ** three input tokens have been successfully shifted.
- */
- if( yypParser->yyerrcnt<=0 ){
- yy_syntax_error(yypParser,yymajor,yyminorunion);
- }
- yypParser->yyerrcnt = 3;
- yy_destructor(yymajor,&yyminorunion);
- if( yyendofinput ){
- yy_parse_failed(yypParser);
- }
- yymajor = YYNOCODE;
-#endif
- }
- }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
- return;
-}
+/* Driver template for the LEMON parser generator.
+** The author disclaims copyright to this source code.
+*/
+/* First off, code is included which follows the "include" declaration
+** in the input file. */
+#include
+#include
+#include
+%%
+/* Next is all token values, in a form suitable for use by makeheaders.
+** This section will be null unless lemon is run with the -m switch.
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+%%
+/* Make sure the INTERFACE macro is defined.
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** YYCODETYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 terminals
+** and nonterminals. "int" is used otherwise.
+** YYNOCODE is a number of type YYCODETYPE which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** YYACTIONTYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 rules and
+** states combined. "int" is used otherwise.
+** ParseTOKENTYPE is the data type used for minor tokens given
+** directly to the parser from the tokenizer.
+** YYMINORTYPE is the data type used for all minor tokens.
+** This is typically a union of many types, one of
+** which is ParseTOKENTYPE. The entry in the union
+** for base tokens is called "yy0".
+** YYSTACKDEPTH is the maximum depth of the parser's stack. If
+** zero the stack is dynamically sized using realloc()
+** ParseARG_SDECL A static variable declaration for the %extra_argument
+** ParseARG_PDECL A parameter declaration for the %extra_argument
+** ParseARG_STORE Code to store %extra_argument into yypParser
+** ParseARG_FETCH Code to extract %extra_argument from yypParser
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+%%
+#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
+#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
+#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == YYNSTATE+YYNRULE A syntax error has occurred.
+**
+** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+**
+** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large table named yy_action[].
+** Given state S and lookahead X, the action is computed as
+**
+** yy_action[ yy_shift_ofst[S] + X ]
+**
+** If the index value yy_shift_ofst[S]+X is out of range or if the value
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
+** and that yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the yy_reduce_ofst[] array is used in place of
+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+** YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** yy_action[] A single table containing all actions.
+** yy_lookahead[] A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** yy_shift_ofst[] For each state, the offset into yy_action for
+** shifting terminals.
+** yy_reduce_ofst[] For each state, the offset into yy_action for
+** shifting non-terminals after a reduce.
+** yy_default[] Default action for each state.
+*/
+%%
+#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0]))
+
+/* The next table maps tokens into fallback tokens. If a construct
+** like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammer, then ID becomes a fallback token for X, Y,
+** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+** but it does not parse, the type of the token is changed to ID and
+** the parse is retried before an error is thrown.
+*/
+#ifdef YYFALLBACK
+static const YYCODETYPE yyFallback[] = {
+%%
+};
+#endif /* YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + The semantic value stored at this level of the stack. This is
+** the information used by the action routines in the grammar.
+** It is sometimes called the "minor" token.
+*/
+struct yyStackEntry {
+ int stateno; /* The state-number */
+ int major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct yyStackEntry yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct yyParser {
+ int yyidx; /* Index of top element in stack */
+ int yyerrcnt; /* Shifts left before out of the error */
+ ParseARG_SDECL /* A place to hold %extra_argument */
+#if YYSTACKDEPTH<=0
+ int yystksz; /* Current side of the stack */
+ yyStackEntry *yystack; /* The parser's stack */
+#else
+ yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
+#endif
+};
+typedef struct yyParser yyParser;
+
+#ifndef NDEBUG
+#include
+static FILE *yyTraceFILE = 0;
+static char *yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
+** by making either argument NULL
+**
+** Inputs:
+**
+**
A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+**
A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+**
+**
+** Outputs:
+** None.
+*/
+void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
+ yyTraceFILE = TraceFILE;
+ yyTracePrompt = zTracePrompt;
+ if( yyTraceFILE==0 ) yyTracePrompt = 0;
+ else if( yyTracePrompt==0 ) yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing shifts, the names of all terminals and nonterminals
+** are required. The following table supplies these names */
+static const char *const yyTokenName[] = {
+%%
+};
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const yyRuleName[] = {
+%%
+};
+#endif /* NDEBUG */
+
+#if YYSTACKDEPTH<=0
+/*
+** Try to increase the size of the parser stack.
+*/
+static void yyGrowStack(yyParser *p){
+ int newSize;
+ yyStackEntry *pNew;
+
+ newSize = p->yystksz*2 + 100;
+ pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ if( pNew ){
+ p->yystack = pNew;
+ p->yystksz = newSize;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
+ yyTracePrompt, p->yystksz);
+ }
+#endif
+ }
+}
+#endif
+
+/*
+** This function allocates a new parser.
+** The only argument is a pointer to a function which works like
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** A pointer to a parser. This pointer is used in subsequent calls
+** to Parse and ParseFree.
+*/
+void *ParseAlloc(void *(*mallocProc)(size_t)){
+ yyParser *pParser;
+ pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+ if( pParser ){
+ pParser->yyidx = -1;
+#if YYSTACKDEPTH<=0
+ yyGrowStack(pParser);
+#endif
+ }
+ return pParser;
+}
+
+/* The following function deletes the value associated with a
+** symbol. The symbol can be either a terminal or nonterminal.
+** "yymajor" is the symbol code, and "yypminor" is a pointer to
+** the value.
+*/
+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+ switch( yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+%%
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+**
+** Return the major token number for the symbol popped.
+*/
+static int yy_pop_parser_stack(yyParser *pParser){
+ YYCODETYPE yymajor;
+ yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+
+ if( pParser->yyidx<0 ) return 0;
+#ifndef NDEBUG
+ if( yyTraceFILE && pParser->yyidx>=0 ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ yymajor = yytos->major;
+ yy_destructor( yymajor, &yytos->minor);
+ pParser->yyidx--;
+ return yymajor;
+}
+
+/*
+** Deallocate and destroy a parser. Destructors are all called for
+** all stack elements before shutting the parser down.
+**
+** Inputs:
+**
+**
A pointer to the parser. This should be a pointer
+** obtained from ParseAlloc.
+**
A pointer to a function used to reclaim memory obtained
+** from malloc.
+**
+*/
+void ParseFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+ yyParser *pParser = (yyParser*)p;
+ if( pParser==0 ) return;
+ while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+ free(pParser->yystack);
+#endif
+ (*freeProc)((void*)pParser);
+}
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_shift_action(
+ yyParser *pParser, /* The parser */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yystack[pParser->yyidx].stateno;
+
+ if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+ if( iLookAhead>0 ){
+#ifdef YYFALLBACK
+ int iFallback; /* Fallback token */
+ if( iLookAhead %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
+#endif
+ return yy_find_shift_action(pParser, iFallback);
+ }
+#endif
+#ifdef YYWILDCARD
+ {
+ int j = i - iLookAhead + YYWILDCARD;
+ if( j>=0 && j %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
+ }
+#endif /* NDEBUG */
+ return yy_action[j];
+ }
+ }
+#endif /* YYWILDCARD */
+ }
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_reduce_action(
+ int stateno, /* Current state number */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+ if( stateno>YY_REDUCE_MAX ||
+ (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ assert( i!=YY_REDUCE_USE_DFLT );
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+ return yy_action[i];
+}
+
+/*
+** The following routine is called if the stack overflows.
+*/
+static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+ ParseARG_FETCH;
+ yypParser->yyidx--;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+%%
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
+}
+
+/*
+** Perform a shift action.
+*/
+static void yy_shift(
+ yyParser *yypParser, /* The parser to be shifted */
+ int yyNewState, /* The new state to shift in */
+ int yyMajor, /* The major token to shift in */
+ YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
+){
+ yyStackEntry *yytos;
+ yypParser->yyidx++;
+#if YYSTACKDEPTH>0
+ if( yypParser->yyidx>=YYSTACKDEPTH ){
+ yyStackOverflow(yypParser, yypMinor);
+ return;
+ }
+#else
+ if( yypParser->yyidx>=yypParser->yystksz ){
+ yyGrowStack(yypParser);
+ if( yypParser->yyidx>=yypParser->yystksz ){
+ yyStackOverflow(yypParser, yypMinor);
+ return;
+ }
+ }
+#endif
+ yytos = &yypParser->yystack[yypParser->yyidx];
+ yytos->stateno = yyNewState;
+ yytos->major = yyMajor;
+ yytos->minor = *yypMinor;
+#ifndef NDEBUG
+ if( yyTraceFILE && yypParser->yyidx>0 ){
+ int i;
+ fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
+ fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
+ for(i=1; i<=yypParser->yyidx; i++)
+ fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"\n");
+ }
+#endif
+}
+
+/* The following table contains information about every rule that
+** is used during the reduce.
+*/
+static const struct {
+ YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
+ unsigned char nrhs; /* Number of right-hand side symbols in the rule */
+} yyRuleInfo[] = {
+%%
+};
+
+static void yy_accept(yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void yy_reduce(
+ yyParser *yypParser, /* The parser */
+ int yyruleno /* Number of the rule by which to reduce */
+){
+ int yygoto; /* The next state */
+ int yyact; /* The next action */
+ YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
+ yyStackEntry *yymsp; /* The top of the parser's stack */
+ int yysize; /* Amount to pop the stack */
+ ParseARG_FETCH;
+ yymsp = &yypParser->yystack[yypParser->yyidx];
+#ifndef NDEBUG
+ if( yyTraceFILE && yyruleno>=0
+ && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
+ yyRuleName[yyruleno]);
+ }
+#endif /* NDEBUG */
+
+ /* Silence complaints from purify about yygotominor being uninitialized
+ ** in some cases when it is copied into the stack after the following
+ ** switch. yygotominor is uninitialized when a rule reduces that does
+ ** not set the value of its left-hand side nonterminal. Leaving the
+ ** value of the nonterminal uninitialized is utterly harmless as long
+ ** as the value is never used. So really the only thing this code
+ ** accomplishes is to quieten purify.
+ **
+ ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
+ ** without this code, their parser segfaults. I'm not sure what there
+ ** parser is doing to make this happen. This is the second bug report
+ ** from wireshark this week. Clearly they are stressing Lemon in ways
+ ** that it has not been previously stressed... (SQLite ticket #2172)
+ */
+ memset(&yygotominor, 0, sizeof(yygotominor));
+
+
+ switch( yyruleno ){
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** case 0:
+ ** #line
+ ** { ... } // User supplied code
+ ** #line
+ ** break;
+ */
+%%
+ };
+ yygoto = yyRuleInfo[yyruleno].lhs;
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ yypParser->yyidx -= yysize;
+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto);
+ if( yyact < YYNSTATE ){
+#ifdef NDEBUG
+ /* If we are not debugging and the reduce action popped at least
+ ** one element off the stack, then we can push the new element back
+ ** onto the stack here, and skip the stack overflow test in yy_shift().
+ ** That gives a significant speed improvement. */
+ if( yysize ){
+ yypParser->yyidx++;
+ yymsp -= yysize-1;
+ yymsp->stateno = yyact;
+ yymsp->major = yygoto;
+ yymsp->minor = yygotominor;
+ }else
+#endif
+ {
+ yy_shift(yypParser,yyact,yygoto,&yygotominor);
+ }
+ }else{
+ assert( yyact == YYNSTATE + YYNRULE + 1 );
+ yy_accept(yypParser);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+static void yy_parse_failed(
+ yyParser *yypParser /* The parser */
+){
+ ParseARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+%%
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void yy_syntax_error(
+ yyParser *yypParser, /* The parser */
+ int yymajor, /* The major type of the error token */
+ YYMINORTYPE yyminor /* The minor type of the error token */
+){
+ ParseARG_FETCH;
+#define TOKEN (yyminor.yy0)
+%%
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void yy_accept(
+ yyParser *yypParser /* The parser */
+){
+ ParseARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+%%
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "ParseAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+**
+**
A pointer to the parser (an opaque structure.)
+**
The major token number.
+**
The minor token number.
+**
An option argument of a grammar-specified type.
+**
+**
+** Outputs:
+** None.
+*/
+void Parse(
+ void *yyp, /* The parser */
+ int yymajor, /* The major token code number */
+ ParseTOKENTYPE yyminor /* The value for the token */
+ ParseARG_PDECL /* Optional %extra_argument parameter */
+){
+ YYMINORTYPE yyminorunion;
+ int yyact; /* The parser action. */
+ int yyendofinput; /* True if we are at the end of input */
+#ifdef YYERRORSYMBOL
+ int yyerrorhit = 0; /* True if yymajor has invoked an error */
+#endif
+ yyParser *yypParser; /* The parser */
+
+ /* (re)initialize the parser, if necessary */
+ yypParser = (yyParser*)yyp;
+ if( yypParser->yyidx<0 ){
+#if YYSTACKDEPTH<=0
+ if( yypParser->yystksz <=0 ){
+ memset(&yyminorunion, 0, sizeof(yyminorunion));
+ yyStackOverflow(yypParser, &yyminorunion);
+ return;
+ }
+#endif
+ yypParser->yyidx = 0;
+ yypParser->yyerrcnt = -1;
+ yypParser->yystack[0].stateno = 0;
+ yypParser->yystack[0].major = 0;
+ }
+ yyminorunion.yy0 = yyminor;
+ yyendofinput = (yymajor==0);
+ ParseARG_STORE;
+
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+
+ do{
+ yyact = yy_find_shift_action(yypParser,yymajor);
+ if( yyactyyerrcnt--;
+ yymajor = YYNOCODE;
+ }else if( yyact < YYNSTATE + YYNRULE ){
+ yy_reduce(yypParser,yyact-YYNSTATE);
+ }else{
+#ifdef YYERRORSYMBOL
+ int yymx;
+#endif
+ assert( yyact == YY_ERROR_ACTION );
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
+ }
+#endif
+#ifdef YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( yypParser->yyerrcnt<0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yymx = yypParser->yystack[yypParser->yyidx].major;
+ if( yymx==YYERRORSYMBOL || yyerrorhit ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sDiscard input token %s\n",
+ yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+ yy_destructor(yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+ }else{
+ while(
+ yypParser->yyidx >= 0 &&
+ yymx != YYERRORSYMBOL &&
+ (yyact = yy_find_reduce_action(
+ yypParser->yystack[yypParser->yyidx].stateno,
+ YYERRORSYMBOL)) >= YYNSTATE
+ ){
+ yy_pop_parser_stack(yypParser);
+ }
+ if( yypParser->yyidx < 0 || yymajor==0 ){
+ yy_destructor(yymajor,&yyminorunion);
+ yy_parse_failed(yypParser);
+ yymajor = YYNOCODE;
+ }else if( yymx!=YYERRORSYMBOL ){
+ YYMINORTYPE u2;
+ u2.YYERRSYMDT = 0;
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ }
+ }
+ yypParser->yyerrcnt = 3;
+ yyerrorhit = 1;
+#else /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( yypParser->yyerrcnt<=0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yypParser->yyerrcnt = 3;
+ yy_destructor(yymajor,&yyminorunion);
+ if( yyendofinput ){
+ yy_parse_failed(yypParser);
+ }
+ yymajor = YYNOCODE;
+#endif
+ }
+ }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+ return;
+}
diff --git a/tools/re2c/CHANGELOG b/tools/re2c/CHANGELOG
index c2b10eeb7..c371edbe1 100644
--- a/tools/re2c/CHANGELOG
+++ b/tools/re2c/CHANGELOG
@@ -1,3 +1,57 @@
+Version 0.12.3 (2007-08-24)
+---------------------------
+- Fixed issue with some compilers.
+- Fixed #1776177 Build on AIX.
+- Fixed #1743180 fwrite with 0 length crashes on OS X.
+
+Version 0.12.2 (2007-06-26)
+---------------------------
+- Fixed #1743180 fwrite with 0 length crashes on OS X.
+
+Version 0.12.1 (2007-05-23)
+---------------------------
+- Fixed #1711240 problem with '"' and 7F on EBCDIC plattforms.
+
+Version 0.12.0 (2007-05-01)
+---------------------------
+- Re-release of 0.11.3 as new stable branch.
+- Fixed issue with short form of switches and parameter if not first switch.
+- Fixed #1708378 segfault in actions.cc.
+
+Version 0.11.3 (2007-04-01)
+---------------------------
+- Added support for underscores in named definitions.
+- Added new option --no-generation-date.
+- Fixed issue with long form of switches.
+
+Version 0.11.2 (2007-03-01)
+---------------------------
+- Added inplace configuration 're2c:yyfill:parameter'.
+- Added inplace configuration 're2c:yych:conversion'.
+- Fixed -u switch code generation.
+- Added ability to avoid defines and overwrite variable and label names.
+
+Version 0.11.1 (2007-02-20)
+---------------------------
+- Applied #1647875 add const to yybm vector.
+
+Version 0.11.0 (2007-01-01)
+---------------------------
+- Added -u switch to support unicode.
+
+Version 0.10.8 (2007-04-01)
+---------------------------
+- Fixed issue with long form of switches.
+
+Version 0.10.7 (2007-02-20)
+---------------------------
+- Applied #1647875 add const to yybm vector.
+
+Version 0.10.6 (2006-08-05)
+---------------------------
+- Fixed #1529351 Segv bug on unterminated code blocks.
+- Fixed #1528269 Invalid code generation.
+
Version 0.10.5 (2006-06-11)
---------------------------
- Fixed long form of -1 switch to --single-pass as noted in man page and help.
@@ -20,7 +74,7 @@ Version 0.10.2 (2006-05-01)
- Fixed -i switch.
- Added configuration 'yyfill:enable' to allow suppression of YYFILL() blocks.
- Added tutorial like lessons to re2c.
-- Added /*!ignore!re2c */ to support documenting of re2c source.
+- Added /*!ignore:re2c */ to support documenting of re2c source.
- Fixed issue with multiline re2c comments (/*!max:re2c ... */ and alike).
- Fixed generation of YYDEBUG() when using -d switch.
- Added /*!getstate:re2c */ which triggers generation of the YYGETSTATE() block.
diff --git a/tools/re2c/Makefile b/tools/re2c/Makefile
index e1d3fc3e4..f465951c5 100644
--- a/tools/re2c/Makefile
+++ b/tools/re2c/Makefile
@@ -1,11 +1,11 @@
-ifeq (Windows_NT,$(OS))
- WIN=1
- WINCMD=1
-endif
-ifeq (msys,$(OSTYPE))
- WIN=1
- WINCMD=0
-endif
+ifeq (Windows_NT,$(OS))
+ WIN=1
+ WINCMD=1
+endif
+ifeq (msys,$(OSTYPE))
+ WIN=1
+ WINCMD=0
+endif
ifeq (1,$(WIN))
EXE = re2c.exe
diff --git a/tools/re2c/README b/tools/re2c/README
index 0cb9ab639..84c2f4fdb 100644
--- a/tools/re2c/README
+++ b/tools/re2c/README
@@ -1,4 +1,4 @@
-re2c Version 0.10.5
+re2c Version 0.12.3
------------------
Originally written by Peter Bumbulis (peter@csg.uwaterloo.ca)
@@ -17,7 +17,7 @@ platforms in 32 bit and 64 bit mode:
- GCC 3.3 ... 4.1
- Microsoft VC 7, 7.1, 8
- Intel 9.0
-- Sun C++ 5.8 (CXXFLAGS='-compat5 -library=stlport4')
+- Sun C++ 5.8 (CXXFLAGS='-library=stlport4')
- MIPSpro Compilers: Version 7.4.4m
GCC 2.x and Microsoft VC 6 are not capable of compiling re2c.
@@ -41,7 +41,7 @@ re2c) you need the following steps:
Or you can create a rpm package and install it by the following commands:
./configure
make rpm
- rpm -Uhv /re2c-0.10.5-1.rpm
+ rpm -Uhv /re2c-0.12.3-1.rpm
If you want to build from CVS then the first thing you should do is
regenerating all build files using the following command:
@@ -51,7 +51,7 @@ need to generate RPM packages for cvs builds use these commands:
./autogen.sh
./configure
./makerpm
- rpm -Uhv /re2c-0.10.5-.rpm
+ rpm -Uhv /re2c-0.12.3-.rpm
Here should be a number like 1. And must equal
the directory where the makerpm step has written the generated rpm to.
diff --git a/tools/re2c/actions.cc b/tools/re2c/actions.cc
index edb5d53a1..b90584827 100644
--- a/tools/re2c/actions.cc
+++ b/tools/re2c/actions.cc
@@ -1,1062 +1,1062 @@
-/* $Id: actions.cc,v 1.35 2006/02/25 12:57:50 helly Exp $ */
-#include
-#include
-#include
-#include
-#include
-
-#include "globals.h"
-#include "parser.h"
-#include "dfa.h"
-
-namespace re2c
-{
-
-void Symbol::ClearTable()
-{
+/* $Id: actions.cc 608 2006-11-05 00:48:30Z helly $ */
+#include
+#include
+#include
+#include
+#include
+
+#include "globals.h"
+#include "parser.h"
+#include "dfa.h"
+
+namespace re2c
+{
+
+void Symbol::ClearTable()
+{
for (SymbolTable::iterator it = symbol_table.begin(); it != symbol_table.end(); ++it)
{
delete it->second;
}
- symbol_table.clear();
-}
-
-Symbol::SymbolTable Symbol::symbol_table;
-
-Symbol *Symbol::find(const SubStr &str)
-{
- const std::string ss(str.to_string());
- SymbolTable::const_iterator it = symbol_table.find(ss);
-
- if (it == symbol_table.end())
- {
- return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second;
- }
-
- return (*it).second;
-}
-
-void showIns(std::ostream &o, const Ins &i, const Ins &base)
-{
- o.width(3);
- o << &i - &base << ": ";
-
- switch (i.i.tag)
- {
-
- case CHAR:
- {
- o << "match ";
-
- for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j)
- prtCh(o, j->c.value);
-
- break;
- }
-
- case GOTO:
- o << "goto " << ((Ins*) i.i.link - &base);
- break;
-
- case FORK:
- o << "fork " << ((Ins*) i.i.link - &base);
- break;
-
- case CTXT:
- o << "ctxt";
- break;
-
- case TERM:
- o << "term " << ((RuleOp*) i.i.link)->accept;
- break;
- }
-
- o << "\n";
-}
-
-uint RegExp::fixedLength()
-{
- return ~0;
-}
-
-const char *NullOp::type = "NullOp";
-
-void NullOp::calcSize(Char*)
-{
- size = 0;
-}
-
-uint NullOp::fixedLength()
-{
- return 0;
-}
-
-void NullOp::compile(Char*, Ins*)
-{
- ;
-}
-
-void NullOp::split(CharSet&)
-{
- ;
-}
-
-std::ostream& operator<<(std::ostream &o, const Range &r)
-{
- if ((r.ub - r.lb) == 1)
- {
- prtCh(o, r.lb);
- }
- else
- {
- prtCh(o, r.lb);
- o << "-";
- prtCh(o, r.ub - 1);
- }
-
- return o << r.next;
-}
-
-Range *doUnion(Range *r1, Range *r2)
-{
- Range *r, **rP = &r;
-
- for (;;)
- {
- Range *s;
-
- if (r1->lb <= r2->lb)
- {
- s = new Range(*r1);
- }
- else
- {
- s = new Range(*r2);
- }
-
- *rP = s;
- rP = &s->next;
-
- for (;;)
- {
- if (r1->lb <= r2->lb)
- {
- if (r1->lb > s->ub)
- break;
-
- if (r1->ub > s->ub)
- s->ub = r1->ub;
-
- if (!(r1 = r1->next))
- {
- uint ub = 0;
-
- for (; r2 && r2->lb <= s->ub; r2 = r2->next)
- ub = r2->ub;
-
- if (ub > s->ub)
- s->ub = ub;
-
- *rP = r2;
-
- return r;
- }
- }
- else
- {
- if (r2->lb > s->ub)
- break;
-
- if (r2->ub > s->ub)
- s->ub = r2->ub;
-
- if (!(r2 = r2->next))
- {
- uint ub = 0;
-
- for (; r1 && r1->lb <= s->ub; r1 = r1->next)
- ub = r1->ub;
-
- if (ub > s->ub)
- s->ub = ub;
-
- *rP = r1;
-
- return r;
- }
- }
- }
- }
-
- *rP = NULL;
- return r;
-}
-
-Range *doDiff(Range *r1, Range *r2)
-{
- Range *r, *s, **rP = &r;
-
- for (; r1; r1 = r1->next)
- {
- uint lb = r1->lb;
-
- for (; r2 && r2->ub <= r1->lb; r2 = r2->next)
-
- ;
- for (; r2 && r2->lb < r1->ub; r2 = r2->next)
- {
- if (lb < r2->lb)
- {
- *rP = s = new Range(lb, r2->lb);
- rP = &s->next;
- }
-
- if ((lb = r2->ub) >= r1->ub)
- goto noMore;
- }
-
- *rP = s = new Range(lb, r1->ub);
- rP = &s->next;
-
-noMore:
- ;
- }
-
- *rP = NULL;
- return r;
-}
-
-MatchOp *merge(MatchOp *m1, MatchOp *m2)
-{
- if (!m1)
- return m2;
-
- if (!m2)
- return m1;
-
- return new MatchOp(doUnion(m1->match, m2->match));
-}
-
-const char *MatchOp::type = "MatchOp";
-
-void MatchOp::display(std::ostream &o) const
-{
- o << match;
-}
-
-void MatchOp::calcSize(Char *rep)
-{
- size = 1;
-
- for (Range *r = match; r; r = r->next)
- for (uint c = r->lb; c < r->ub; ++c)
- if (rep[c] == c)
- ++size;
-}
-
-uint MatchOp::fixedLength()
-{
- return 1;
-}
-
-void MatchOp::compile(Char *rep, Ins *i)
-{
- i->i.tag = CHAR;
- i->i.link = &i[size];
- Ins *j = &i[1];
- uint bump = size;
-
- for (Range *r = match; r; r = r->next)
- {
- for (uint c = r->lb; c < r->ub; ++c)
- {
- if (rep[c] == c)
- {
- j->c.value = c;
- j->c.bump = --bump;
- j++;
- }
- }
- }
-}
-
-void MatchOp::split(CharSet &s)
-{
- for (Range *r = match; r; r = r->next)
- {
- for (uint c = r->lb; c < r->ub; ++c)
- {
- CharPtn *x = s.rep[c], *a = x->nxt;
-
- if (!a)
- {
- if (x->card == 1)
- continue;
-
- x->nxt = a = s.freeHead;
-
- if (!(s.freeHead = s.freeHead->nxt))
- s.freeTail = &s.freeHead;
-
- a->nxt = NULL;
-
- x->fix = s.fix;
-
- s.fix = x;
- }
-
- if (--(x->card) == 0)
- {
- *s.freeTail = x;
- *(s.freeTail = &x->nxt) = NULL;
- }
-
- s.rep[c] = a;
- ++(a->card);
- }
- }
-
- for (; s.fix; s.fix = s.fix->fix)
- if (s.fix->card)
- s.fix->nxt = NULL;
-}
-
-RegExp * mkDiff(RegExp *e1, RegExp *e2)
-{
- MatchOp *m1, *m2;
-
- if (!(m1 = (MatchOp*) e1->isA(MatchOp::type)))
- return NULL;
-
- if (!(m2 = (MatchOp*) e2->isA(MatchOp::type)))
- return NULL;
-
- Range *r = doDiff(m1->match, m2->match);
-
- return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp;
-}
-
-RegExp *doAlt(RegExp *e1, RegExp *e2)
-{
- if (!e1)
- return e2;
-
- if (!e2)
- return e1;
-
- return new AltOp(e1, e2);
-}
-
-RegExp *mkAlt(RegExp *e1, RegExp *e2)
-{
- AltOp *a;
- MatchOp *m1, *m2;
-
- if ((a = (AltOp*) e1->isA(AltOp::type)))
- {
- if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type)))
- e1 = a->exp2;
- }
- else if ((m1 = (MatchOp*) e1->isA(MatchOp::type)))
- {
- e1 = NULL;
- }
-
- if ((a = (AltOp*) e2->isA(AltOp::type)))
- {
- if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type)))
- e2 = a->exp2;
- }
- else if ((m2 = (MatchOp*) e2->isA(MatchOp::type)))
- {
- e2 = NULL;
- }
-
- return doAlt(merge(m1, m2), doAlt(e1, e2));
-}
-
-const char *AltOp::type = "AltOp";
-
-void AltOp::calcSize(Char *rep)
-{
- exp1->calcSize(rep);
- exp2->calcSize(rep);
- size = exp1->size + exp2->size + 2;
-}
-
-uint AltOp::fixedLength()
-{
- uint l1 = exp1->fixedLength();
- uint l2 = exp1->fixedLength();
-
- if (l1 != l2 || l1 == ~0u)
- return ~0;
-
- return l1;
-}
-
-void AltOp::compile(Char *rep, Ins *i)
-{
- i->i.tag = FORK;
- Ins *j = &i[exp1->size + 1];
- i->i.link = &j[1];
- exp1->compile(rep, &i[1]);
- j->i.tag = GOTO;
- j->i.link = &j[exp2->size + 1];
- exp2->compile(rep, &j[1]);
-}
-
-void AltOp::split(CharSet &s)
-{
- exp1->split(s);
- exp2->split(s);
-}
-
-const char *CatOp::type = "CatOp";
-
-void CatOp::calcSize(Char *rep)
-{
- exp1->calcSize(rep);
- exp2->calcSize(rep);
- size = exp1->size + exp2->size;
-}
-
-uint CatOp::fixedLength()
-{
- uint l1, l2;
-
- if ((l1 = exp1->fixedLength()) != ~0u )
- if ((l2 = exp2->fixedLength()) != ~0u)
- return l1 + l2;
-
- return ~0u;
-}
-
-void CatOp::compile(Char *rep, Ins *i)
-{
- exp1->compile(rep, &i[0]);
- exp2->compile(rep, &i[exp1->size]);
-}
-
-void CatOp::split(CharSet &s)
-{
- exp1->split(s);
- exp2->split(s);
-}
-
-const char *CloseOp::type = "CloseOp";
-
-void CloseOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
- size = exp->size + 1;
-}
-
-void CloseOp::compile(Char *rep, Ins *i)
-{
- exp->compile(rep, &i[0]);
- i += exp->size;
- i->i.tag = FORK;
- i->i.link = i - exp->size;
-}
-
-void CloseOp::split(CharSet &s)
-{
- exp->split(s);
-}
-
-const char *CloseVOp::type = "CloseVOp";
-
-void CloseVOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
-
- if (max >= 0)
- {
- size = (exp->size * min) + ((1 + exp->size) * (max - min));
- }
- else
- {
- size = (exp->size * min) + 1;
- }
-}
-
-void CloseVOp::compile(Char *rep, Ins *i)
-{
- Ins *jumppoint;
- int st;
- jumppoint = i + ((1 + exp->size) * (max - min));
-
- for (st = min; st < max; st++)
- {
- i->i.tag = FORK;
- i->i.link = jumppoint;
- i++;
- exp->compile(rep, &i[0]);
- i += exp->size;
- }
-
- for (st = 0; st < min; st++)
- {
- exp->compile(rep, &i[0]);
- i += exp->size;
-
- if (max < 0 && st == 0)
- {
- i->i.tag = FORK;
- i->i.link = i - exp->size;
- i++;
- }
- }
-}
-
-void CloseVOp::split(CharSet &s)
-{
- exp->split(s);
-}
-
-RegExp *expr(Scanner &);
-
-uint Scanner::unescape(SubStr &s) const
-{
- static const char * hex = "0123456789abcdef";
- static const char * oct = "01234567";
-
- s.len--;
- uint c, ucb = 0;
-
- if ((c = *s.str++) != '\\' || s.len == 0)
- {
- return xlat(c);
- }
-
- s.len--;
-
- switch (c = *s.str++)
- {
- case 'n': return xlat('\n');
- case 't': return xlat('\t');
- case 'v': return xlat('\v');
- case 'b': return xlat('\b');
- case 'r': return xlat('\r');
- case 'f': return xlat('\f');
- case 'a': return xlat('\a');
-
- case 'x':
- {
- if (s.len < 2)
- {
- fatal(s.ofs()+s.len, "Illegal hexadecimal character code, two hexadecimal digits are required");
- return ~0;
- }
-
- const char *p1 = strchr(hex, tolower(s.str[0]));
- const char *p2 = strchr(hex, tolower(s.str[1]));
-
- if (!p1 || !p2)
- {
- fatal(s.ofs()+(p1?1:0), "Illegal hexadecimal character code");
- return ~0;
- }
- else
- {
- s.len -= 2;
- s.str += 2;
-
- uint v = (uint)((p1 - hex) << 4)
- + (uint)((p2 - hex));
-
- return v;
- }
- }
-
- case 'U':
- {
- if (s.len < 8)
- {
- fatal(s.ofs()+s.len, "Illegal unicode character, eight hexadecimal digits are required");
- return ~0;
- }
-
- uint l = 0;
-
- if (s.str[0] == '0')
- {
- l++;
- if (s.str[1] == '0')
- {
- l++;
- if (s.str[2] == '0' || (s.str[2] == '1' && uFlag))
- {
- l++;
- if (uFlag) {
- const char *u3 = strchr(hex, tolower(s.str[2]));
- const char *u4 = strchr(hex, tolower(s.str[3]));
- if (u3 && u4)
- {
- ucb = (uint)((u3 - hex) << 20)
- + (uint)((u4 - hex) << 16);
- l++;
- }
- }
- else if (s.str[3] == '0')
- {
- l++;
- }
- }
- }
- }
-
- if (l != 4)
- {
- fatal(s.ofs()+l, "Illegal unicode character, eight hexadecimal digits are required");
- }
-
- s.len -= 4;
- s.str += 4;
-
- // no break;
- }
- case 'X':
- case 'u':
- {
- if (s.len < 4)
- {
- fatal(s.ofs()+s.len,
- c == 'X'
- ? "Illegal hexadecimal character code, four hexadecimal digits are required"
- : "Illegal unicode character, four hexadecimal digits are required");
- return ~0;
- }
-
- const char *p1 = strchr(hex, tolower(s.str[0]));
- const char *p2 = strchr(hex, tolower(s.str[1]));
- const char *p3 = strchr(hex, tolower(s.str[2]));
- const char *p4 = strchr(hex, tolower(s.str[3]));
-
- if (!p1 || !p2 || !p3 || !p4)
- {
- fatal(s.ofs()+(p1?1:0)+(p2?1:0)+(p3?1:0),
- c == 'X'
- ? "Illegal hexadecimal character code, non hexxdecimal digit found"
- : "Illegal unicode character, non hexadecimal digit found");
- return ~0;
- }
- else
- {
- s.len -= 4;
- s.str += 4;
-
- uint v = (uint)((p1 - hex) << 12)
- + (uint)((p2 - hex) << 8)
- + (uint)((p3 - hex) << 4)
- + (uint)((p4 - hex))
- + ucb;
-
- if (v >= nRealChars)
- {
- fatal(s.ofs(),
- c == 'X'
- ? "Illegal hexadecimal character code, out of range"
- : "Illegal unicode character, out of range");
- }
-
- return v;
- }
- }
-
- case '4':
- case '5':
- case '6':
- case '7':
- {
- fatal(s.ofs()-1, "Illegal octal character code, first digit must be 0 thru 3");
- return ~0;
- }
-
- case '0':
- case '1':
- case '2':
- case '3':
- {
- if (s.len < 2)
- {
- fatal(s.ofs()+s.len, "Illegal octal character code, three octal digits are required");
- return ~0;
- }
-
- const char *p0 = strchr(oct, c);
- const char *p1 = strchr(oct, s.str[0]);
- const char *p2 = strchr(oct, s.str[1]);
-
- if (!p0 || !p1 || !p2)
- {
- fatal(s.ofs()+(p1?1:0), "Illegal octal character code, non octal digit found");
- return ~0;
- }
- else
- {
- s.len -= 2;
- s.str += 2;
-
- uint v = (uint)((p0 - oct) << 6) + (uint)((p1 - oct) << 3) + (uint)(p2 - oct);
-
- return v;
- }
- }
-
- default:
- return xlat(c);
- }
-}
-
-std::string& Scanner::unescape(SubStr& str_in, std::string& str_out) const
-{
- str_out.clear();
-
- while(str_in.len)
- {
- uint c = unescape(str_in);
-
- if (c > 0xFF)
- {
- fatal(str_in.ofs(), "Illegal character");
- }
-
- str_out += static_cast(c);
- }
-
- return str_out;
-}
-
-Range * Scanner::getRange(SubStr &s) const
-{
- uint lb = unescape(s), ub, xlb, xub, c;
-
- if (s.len < 2 || *s.str != '-')
- {
- ub = lb;
- }
- else
- {
- s.len--;
- s.str++;
- ub = unescape(s);
-
- if (ub < lb)
- {
- uint tmp = lb;
- lb = ub;
- ub = tmp;
- }
-
- xlb = xlat(lb);
- xub = xlat(ub);
-
- for(c = lb; c <= ub; c++)
- {
- if (!(xlb <= xlat(c) && xlat(c) <= ub))
- {
- /* range doesn't work */
- Range * r = new Range(xlb, xlb + 1);
- for (c = lb + 1; c <= ub; c++)
- {
- r = doUnion(r, new Range(xlat(c), xlat(c) + 1));
- }
- return r;
- }
- }
-
- lb = xlb;
- ub = xub;
- }
-
- return new Range(lb, ub + 1);
-}
-
-RegExp * Scanner::matchChar(uint c) const
-{
- return new MatchOp(new Range(c, c + 1));
-}
-
-RegExp * Scanner::strToRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- RegExp *re = matchChar(unescape(s));
-
- while (s.len > 0)
- re = new CatOp(re, matchChar(unescape(s)));
-
- return re;
-}
-
-RegExp * Scanner::strToCaseInsensitiveRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- uint c = unescape(s);
-
- RegExp *re, *reL, *reU;
-
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
- {
- reL = matchChar(xlat(tolower(c)));
- reU = matchChar(xlat(toupper(c)));
- re = mkAlt(reL, reU);
- }
- else
- {
- re = matchChar(c);
- }
-
- while (s.len > 0)
- {
- uint c = unescape(s);
-
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
- {
- reL = matchChar(xlat(tolower(c)));
- reU = matchChar(xlat(toupper(c)));
- re = new CatOp(re, mkAlt(reL, reU));
- }
- else
- {
- re = new CatOp(re, matchChar(c));
- }
- }
-
- return re;
-}
-
-RegExp * Scanner::ranToRE(SubStr s) const
-{
- s.len -= 2;
- s.str += 1;
-
- if (s.len == 0)
- return new NullOp;
-
- Range *r = getRange(s);
-
- while (s.len > 0)
- r = doUnion(r, getRange(s));
-
- return new MatchOp(r);
-}
-
-RegExp * Scanner::invToRE(SubStr s) const
-{
- s.len--;
- s.str++;
-
- RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
-
- if (s.len <= 2)
- {
- return any;
- }
-
- RegExp * ran = ranToRE(s);
- RegExp * inv = mkDiff(any, ran);
-
- delete ran;
- delete any;
-
- return inv;
-}
-
-RegExp * Scanner::mkDot() const
-{
- RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
- RegExp * ran = matchChar(xlat('\n'));
- RegExp * inv = mkDiff(any, ran);
-
- delete ran;
- delete any;
-
- return inv;
-}
-
-const char *RuleOp::type = "RuleOp";
-
-RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a)
- : exp(e)
- , ctx(c)
- , ins(NULL)
- , accept(a)
- , code(t)
- , line(0)
-{
- ;
-}
-
-void RuleOp::calcSize(Char *rep)
-{
- exp->calcSize(rep);
- ctx->calcSize(rep);
- size = exp->size + (ctx->size ? ctx->size + 2 : 1);
-}
-
-void RuleOp::compile(Char *rep, Ins *i)
-{
- ins = i;
- exp->compile(rep, &i[0]);
- i += exp->size;
- if (ctx->size)
- {
- i->i.tag = CTXT;
- i->i.link = &i[1];
- i++;
- ctx->compile(rep, &i[0]);
- i += ctx->size;
- }
- i->i.tag = TERM;
- i->i.link = this;
-}
-
-void RuleOp::split(CharSet &s)
-{
- exp->split(s);
- ctx->split(s);
-}
-
-void optimize(Ins *i)
-{
- while (!isMarked(i))
- {
- mark(i);
-
- if (i->i.tag == CHAR)
- {
- i = (Ins*) i->i.link;
- }
- else if (i->i.tag == GOTO || i->i.tag == FORK)
- {
- Ins *target = (Ins*) i->i.link;
- optimize(target);
-
- if (target->i.tag == GOTO)
- i->i.link = target->i.link == target ? i : target;
-
- if (i->i.tag == FORK)
- {
- Ins *follow = (Ins*) & i[1];
- optimize(follow);
-
- if (follow->i.tag == GOTO && follow->i.link == follow)
- {
- i->i.tag = GOTO;
- }
- else if (i->i.link == i)
- {
- i->i.tag = GOTO;
- i->i.link = follow;
- }
- }
-
- return ;
- }
- else
- {
- ++i;
- }
- }
-}
-
-void genCode(std::ostream& o, RegExp *re)
-{
- genCode(o, 0, re);
-}
-
-CharSet::CharSet()
- : fix(0)
- , freeHead(0)
- , freeTail(0)
- , rep(new CharPtr[nRealChars])
- , ptn(new CharPtn[nRealChars])
-{
- for (uint j = 0; j < nRealChars; ++j)
- {
- rep[j] = &ptn[0];
- ptn[j].nxt = &ptn[j + 1]; /* wrong for j=nRealChars but will be corrected below */
- ptn[j].card = 0;
- }
-
- freeHead = &ptn[1];
- *(freeTail = &ptn[nRealChars - 1].nxt) = NULL;
- ptn[0].card = nRealChars;
- ptn[0].nxt = NULL;
-}
-
-CharSet::~CharSet()
-{
- delete[] rep;
- delete[] ptn;
-}
-
-void genCode(std::ostream& o, uint ind, RegExp *re)
-{
- CharSet cs;
- uint j;
-
- re->split(cs);
- /*
- for(uint k = 0; k < nChars;){
- for(j = k; ++k < nRealChars && cs.rep[k] == cs.rep[j];);
- printSpan(cerr, j, k);
- cerr << "\t" << cs.rep[j] - &cs.ptn[0] << endl;
- }
- */
- Char *rep = new Char[nRealChars];
-
- for (j = 0; j < nRealChars; ++j)
- {
- if (!cs.rep[j]->nxt)
- cs.rep[j]->nxt = &cs.ptn[j];
-
- rep[j] = (Char) (cs.rep[j]->nxt - &cs.ptn[0]);
- }
-
- re->calcSize(rep);
- Ins *ins = new Ins[re->size + 1];
- memset(ins, 0, (re->size + 1)*sizeof(Ins));
- re->compile(rep, ins);
- Ins *eoi = &ins[re->size];
- eoi->i.tag = GOTO;
- eoi->i.link = eoi;
-
- optimize(ins);
-
- for (j = 0; j < re->size;)
- {
- unmark(&ins[j]);
-
- if (ins[j].i.tag == CHAR)
- {
- j = (Ins*) ins[j].i.link - ins;
- }
- else
- {
- j++;
- }
- }
-
- DFA *dfa = new DFA(ins, re->size, 0, nRealChars, rep);
- dfa->emit(o, ind);
- delete dfa;
- delete [] ins;
- delete [] rep;
-}
-
-} // end namespace re2c
-
+ symbol_table.clear();
+}
+
+Symbol::SymbolTable Symbol::symbol_table;
+
+Symbol *Symbol::find(const SubStr &str)
+{
+ const std::string ss(str.to_string());
+ SymbolTable::const_iterator it = symbol_table.find(ss);
+
+ if (it == symbol_table.end())
+ {
+ return (*symbol_table.insert(SymbolTable::value_type(ss, new Symbol(str))).first).second;
+ }
+
+ return (*it).second;
+}
+
+void showIns(std::ostream &o, const Ins &i, const Ins &base)
+{
+ o.width(3);
+ o << &i - &base << ": ";
+
+ switch (i.i.tag)
+ {
+
+ case CHAR:
+ {
+ o << "match ";
+
+ for (const Ins *j = &(&i)[1]; j < (Ins*) i.i.link; ++j)
+ prtCh(o, j->c.value);
+
+ break;
+ }
+
+ case GOTO:
+ o << "goto " << ((Ins*) i.i.link - &base);
+ break;
+
+ case FORK:
+ o << "fork " << ((Ins*) i.i.link - &base);
+ break;
+
+ case CTXT:
+ o << "ctxt";
+ break;
+
+ case TERM:
+ o << "term " << ((RuleOp*) i.i.link)->accept;
+ break;
+ }
+
+ o << "\n";
+}
+
+uint RegExp::fixedLength()
+{
+ return ~0;
+}
+
+const char *NullOp::type = "NullOp";
+
+void NullOp::calcSize(Char*)
+{
+ size = 0;
+}
+
+uint NullOp::fixedLength()
+{
+ return 0;
+}
+
+void NullOp::compile(Char*, Ins*)
+{
+ ;
+}
+
+void NullOp::split(CharSet&)
+{
+ ;
+}
+
+std::ostream& operator<<(std::ostream &o, const Range &r)
+{
+ if ((r.ub - r.lb) == 1)
+ {
+ prtCh(o, r.lb);
+ }
+ else
+ {
+ prtCh(o, r.lb);
+ o << "-";
+ prtCh(o, r.ub - 1);
+ }
+
+ return o << r.next;
+}
+
+Range *doUnion(Range *r1, Range *r2)
+{
+ Range *r, **rP = &r;
+
+ for (;;)
+ {
+ Range *s;
+
+ if (r1->lb <= r2->lb)
+ {
+ s = new Range(*r1);
+ }
+ else
+ {
+ s = new Range(*r2);
+ }
+
+ *rP = s;
+ rP = &s->next;
+
+ for (;;)
+ {
+ if (r1->lb <= r2->lb)
+ {
+ if (r1->lb > s->ub)
+ break;
+
+ if (r1->ub > s->ub)
+ s->ub = r1->ub;
+
+ if (!(r1 = r1->next))
+ {
+ uint ub = 0;
+
+ for (; r2 && r2->lb <= s->ub; r2 = r2->next)
+ ub = r2->ub;
+
+ if (ub > s->ub)
+ s->ub = ub;
+
+ *rP = r2;
+
+ return r;
+ }
+ }
+ else
+ {
+ if (r2->lb > s->ub)
+ break;
+
+ if (r2->ub > s->ub)
+ s->ub = r2->ub;
+
+ if (!(r2 = r2->next))
+ {
+ uint ub = 0;
+
+ for (; r1 && r1->lb <= s->ub; r1 = r1->next)
+ ub = r1->ub;
+
+ if (ub > s->ub)
+ s->ub = ub;
+
+ *rP = r1;
+
+ return r;
+ }
+ }
+ }
+ }
+
+ *rP = NULL;
+ return r;
+}
+
+Range *doDiff(Range *r1, Range *r2)
+{
+ Range *r, *s, **rP = &r;
+
+ for (; r1; r1 = r1->next)
+ {
+ uint lb = r1->lb;
+
+ for (; r2 && r2->ub <= r1->lb; r2 = r2->next)
+
+ ;
+ for (; r2 && r2->lb < r1->ub; r2 = r2->next)
+ {
+ if (lb < r2->lb)
+ {
+ *rP = s = new Range(lb, r2->lb);
+ rP = &s->next;
+ }
+
+ if ((lb = r2->ub) >= r1->ub)
+ goto noMore;
+ }
+
+ *rP = s = new Range(lb, r1->ub);
+ rP = &s->next;
+
+noMore:
+ ;
+ }
+
+ *rP = NULL;
+ return r;
+}
+
+MatchOp *merge(MatchOp *m1, MatchOp *m2)
+{
+ if (!m1)
+ return m2;
+
+ if (!m2)
+ return m1;
+
+ return new MatchOp(doUnion(m1->match, m2->match));
+}
+
+const char *MatchOp::type = "MatchOp";
+
+void MatchOp::display(std::ostream &o) const
+{
+ o << match;
+}
+
+void MatchOp::calcSize(Char *rep)
+{
+ size = 1;
+
+ for (Range *r = match; r; r = r->next)
+ for (uint c = r->lb; c < r->ub; ++c)
+ if (rep[c] == c)
+ ++size;
+}
+
+uint MatchOp::fixedLength()
+{
+ return 1;
+}
+
+void MatchOp::compile(Char *rep, Ins *i)
+{
+ i->i.tag = CHAR;
+ i->i.link = &i[size];
+ Ins *j = &i[1];
+ uint bump = size;
+
+ for (Range *r = match; r; r = r->next)
+ {
+ for (uint c = r->lb; c < r->ub; ++c)
+ {
+ if (rep[c] == c)
+ {
+ j->c.value = c;
+ j->c.bump = --bump;
+ j++;
+ }
+ }
+ }
+}
+
+void MatchOp::split(CharSet &s)
+{
+ for (Range *r = match; r; r = r->next)
+ {
+ for (uint c = r->lb; c < r->ub; ++c)
+ {
+ CharPtn *x = s.rep[c], *a = x->nxt;
+
+ if (!a)
+ {
+ if (x->card == 1)
+ continue;
+
+ x->nxt = a = s.freeHead;
+
+ if (!(s.freeHead = s.freeHead->nxt))
+ s.freeTail = &s.freeHead;
+
+ a->nxt = NULL;
+
+ x->fix = s.fix;
+
+ s.fix = x;
+ }
+
+ if (--(x->card) == 0)
+ {
+ *s.freeTail = x;
+ *(s.freeTail = &x->nxt) = NULL;
+ }
+
+ s.rep[c] = a;
+ ++(a->card);
+ }
+ }
+
+ for (; s.fix; s.fix = s.fix->fix)
+ if (s.fix->card)
+ s.fix->nxt = NULL;
+}
+
+RegExp * mkDiff(RegExp *e1, RegExp *e2)
+{
+ MatchOp *m1, *m2;
+
+ if (!(m1 = (MatchOp*) e1->isA(MatchOp::type)))
+ return NULL;
+
+ if (!(m2 = (MatchOp*) e2->isA(MatchOp::type)))
+ return NULL;
+
+ Range *r = doDiff(m1->match, m2->match);
+
+ return r ? (RegExp*) new MatchOp(r) : (RegExp*) new NullOp;
+}
+
+RegExp *doAlt(RegExp *e1, RegExp *e2)
+{
+ if (!e1)
+ return e2;
+
+ if (!e2)
+ return e1;
+
+ return new AltOp(e1, e2);
+}
+
+RegExp *mkAlt(RegExp *e1, RegExp *e2)
+{
+ AltOp *a;
+ MatchOp *m1, *m2;
+
+ if ((a = (AltOp*) e1->isA(AltOp::type)))
+ {
+ if ((m1 = (MatchOp*) a->exp1->isA(MatchOp::type)))
+ e1 = a->exp2;
+ }
+ else if ((m1 = (MatchOp*) e1->isA(MatchOp::type)))
+ {
+ e1 = NULL;
+ }
+
+ if ((a = (AltOp*) e2->isA(AltOp::type)))
+ {
+ if ((m2 = (MatchOp*) a->exp1->isA(MatchOp::type)))
+ e2 = a->exp2;
+ }
+ else if ((m2 = (MatchOp*) e2->isA(MatchOp::type)))
+ {
+ e2 = NULL;
+ }
+
+ return doAlt(merge(m1, m2), doAlt(e1, e2));
+}
+
+const char *AltOp::type = "AltOp";
+
+void AltOp::calcSize(Char *rep)
+{
+ exp1->calcSize(rep);
+ exp2->calcSize(rep);
+ size = exp1->size + exp2->size + 2;
+}
+
+uint AltOp::fixedLength()
+{
+ uint l1 = exp1->fixedLength();
+ uint l2 = exp1->fixedLength();
+
+ if (l1 != l2 || l1 == ~0u)
+ return ~0;
+
+ return l1;
+}
+
+void AltOp::compile(Char *rep, Ins *i)
+{
+ i->i.tag = FORK;
+ Ins *j = &i[exp1->size + 1];
+ i->i.link = &j[1];
+ exp1->compile(rep, &i[1]);
+ j->i.tag = GOTO;
+ j->i.link = &j[exp2->size + 1];
+ exp2->compile(rep, &j[1]);
+}
+
+void AltOp::split(CharSet &s)
+{
+ exp1->split(s);
+ exp2->split(s);
+}
+
+const char *CatOp::type = "CatOp";
+
+void CatOp::calcSize(Char *rep)
+{
+ exp1->calcSize(rep);
+ exp2->calcSize(rep);
+ size = exp1->size + exp2->size;
+}
+
+uint CatOp::fixedLength()
+{
+ uint l1, l2;
+
+ if ((l1 = exp1->fixedLength()) != ~0u )
+ if ((l2 = exp2->fixedLength()) != ~0u)
+ return l1 + l2;
+
+ return ~0u;
+}
+
+void CatOp::compile(Char *rep, Ins *i)
+{
+ exp1->compile(rep, &i[0]);
+ exp2->compile(rep, &i[exp1->size]);
+}
+
+void CatOp::split(CharSet &s)
+{
+ exp1->split(s);
+ exp2->split(s);
+}
+
+const char *CloseOp::type = "CloseOp";
+
+void CloseOp::calcSize(Char *rep)
+{
+ exp->calcSize(rep);
+ size = exp->size + 1;
+}
+
+void CloseOp::compile(Char *rep, Ins *i)
+{
+ exp->compile(rep, &i[0]);
+ i += exp->size;
+ i->i.tag = FORK;
+ i->i.link = i - exp->size;
+}
+
+void CloseOp::split(CharSet &s)
+{
+ exp->split(s);
+}
+
+const char *CloseVOp::type = "CloseVOp";
+
+void CloseVOp::calcSize(Char *rep)
+{
+ exp->calcSize(rep);
+
+ if (max >= 0)
+ {
+ size = (exp->size * min) + ((1 + exp->size) * (max - min));
+ }
+ else
+ {
+ size = (exp->size * min) + 1;
+ }
+}
+
+void CloseVOp::compile(Char *rep, Ins *i)
+{
+ Ins *jumppoint;
+ int st;
+ jumppoint = i + ((1 + exp->size) * (max - min));
+
+ for (st = min; st < max; st++)
+ {
+ i->i.tag = FORK;
+ i->i.link = jumppoint;
+ i++;
+ exp->compile(rep, &i[0]);
+ i += exp->size;
+ }
+
+ for (st = 0; st < min; st++)
+ {
+ exp->compile(rep, &i[0]);
+ i += exp->size;
+
+ if (max < 0 && st == 0)
+ {
+ i->i.tag = FORK;
+ i->i.link = i - exp->size;
+ i++;
+ }
+ }
+}
+
+void CloseVOp::split(CharSet &s)
+{
+ exp->split(s);
+}
+
+RegExp *expr(Scanner &);
+
+uint Scanner::unescape(SubStr &s) const
+{
+ static const char * hex = "0123456789abcdef";
+ static const char * oct = "01234567";
+
+ s.len--;
+ uint c, ucb = 0;
+
+ if ((c = *s.str++) != '\\' || s.len == 0)
+ {
+ return xlat(c);
+ }
+
+ s.len--;
+
+ switch (c = *s.str++)
+ {
+ case 'n': return xlat('\n');
+ case 't': return xlat('\t');
+ case 'v': return xlat('\v');
+ case 'b': return xlat('\b');
+ case 'r': return xlat('\r');
+ case 'f': return xlat('\f');
+ case 'a': return xlat('\a');
+
+ case 'x':
+ {
+ if (s.len < 2)
+ {
+ fatal(s.ofs()+s.len, "Illegal hexadecimal character code, two hexadecimal digits are required");
+ return ~0;
+ }
+
+ const char *p1 = strchr(hex, tolower(s.str[0]));
+ const char *p2 = strchr(hex, tolower(s.str[1]));
+
+ if (!p1 || !p2)
+ {
+ fatal(s.ofs()+(p1?1:0), "Illegal hexadecimal character code");
+ return ~0;
+ }
+ else
+ {
+ s.len -= 2;
+ s.str += 2;
+
+ uint v = (uint)((p1 - hex) << 4)
+ + (uint)((p2 - hex));
+
+ return v;
+ }
+ }
+
+ case 'U':
+ {
+ if (s.len < 8)
+ {
+ fatal(s.ofs()+s.len, "Illegal unicode character, eight hexadecimal digits are required");
+ return ~0;
+ }
+
+ uint l = 0;
+
+ if (s.str[0] == '0')
+ {
+ l++;
+ if (s.str[1] == '0')
+ {
+ l++;
+ if (s.str[2] == '0' || (s.str[2] == '1' && uFlag))
+ {
+ l++;
+ if (uFlag) {
+ const char *u3 = strchr(hex, tolower(s.str[2]));
+ const char *u4 = strchr(hex, tolower(s.str[3]));
+ if (u3 && u4)
+ {
+ ucb = (uint)((u3 - hex) << 20)
+ + (uint)((u4 - hex) << 16);
+ l++;
+ }
+ }
+ else if (s.str[3] == '0')
+ {
+ l++;
+ }
+ }
+ }
+ }
+
+ if (l != 4)
+ {
+ fatal(s.ofs()+l, "Illegal unicode character, eight hexadecimal digits are required");
+ }
+
+ s.len -= 4;
+ s.str += 4;
+
+ // no break;
+ }
+ case 'X':
+ case 'u':
+ {
+ if (s.len < 4)
+ {
+ fatal(s.ofs()+s.len,
+ c == 'X'
+ ? "Illegal hexadecimal character code, four hexadecimal digits are required"
+ : "Illegal unicode character, four hexadecimal digits are required");
+ return ~0;
+ }
+
+ const char *p1 = strchr(hex, tolower(s.str[0]));
+ const char *p2 = strchr(hex, tolower(s.str[1]));
+ const char *p3 = strchr(hex, tolower(s.str[2]));
+ const char *p4 = strchr(hex, tolower(s.str[3]));
+
+ if (!p1 || !p2 || !p3 || !p4)
+ {
+ fatal(s.ofs()+(p1?1:0)+(p2?1:0)+(p3?1:0),
+ c == 'X'
+ ? "Illegal hexadecimal character code, non hexxdecimal digit found"
+ : "Illegal unicode character, non hexadecimal digit found");
+ return ~0;
+ }
+ else
+ {
+ s.len -= 4;
+ s.str += 4;
+
+ uint v = (uint)((p1 - hex) << 12)
+ + (uint)((p2 - hex) << 8)
+ + (uint)((p3 - hex) << 4)
+ + (uint)((p4 - hex))
+ + ucb;
+
+ if (v >= nRealChars)
+ {
+ fatal(s.ofs(),
+ c == 'X'
+ ? "Illegal hexadecimal character code, out of range"
+ : "Illegal unicode character, out of range");
+ }
+
+ return v;
+ }
+ }
+
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ {
+ fatal(s.ofs()-1, "Illegal octal character code, first digit must be 0 thru 3");
+ return ~0;
+ }
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ {
+ if (s.len < 2)
+ {
+ fatal(s.ofs()+s.len, "Illegal octal character code, three octal digits are required");
+ return ~0;
+ }
+
+ const char *p0 = strchr(oct, c);
+ const char *p1 = strchr(oct, s.str[0]);
+ const char *p2 = strchr(oct, s.str[1]);
+
+ if (!p0 || !p1 || !p2)
+ {
+ fatal(s.ofs()+(p1?1:0), "Illegal octal character code, non octal digit found");
+ return ~0;
+ }
+ else
+ {
+ s.len -= 2;
+ s.str += 2;
+
+ uint v = (uint)((p0 - oct) << 6) + (uint)((p1 - oct) << 3) + (uint)(p2 - oct);
+
+ return v;
+ }
+ }
+
+ default:
+ return xlat(c);
+ }
+}
+
+std::string& Scanner::unescape(SubStr& str_in, std::string& str_out) const
+{
+ str_out.clear();
+
+ while(str_in.len)
+ {
+ uint c = unescape(str_in);
+
+ if (c > 0xFF)
+ {
+ fatal(str_in.ofs(), "Illegal character");
+ }
+
+ str_out += static_cast(c);
+ }
+
+ return str_out;
+}
+
+Range * Scanner::getRange(SubStr &s) const
+{
+ uint lb = unescape(s), ub, xlb, xub, c;
+
+ if (s.len < 2 || *s.str != '-')
+ {
+ ub = lb;
+ }
+ else
+ {
+ s.len--;
+ s.str++;
+ ub = unescape(s);
+
+ if (ub < lb)
+ {
+ uint tmp = lb;
+ lb = ub;
+ ub = tmp;
+ }
+
+ xlb = xlat(lb);
+ xub = xlat(ub);
+
+ for(c = lb; c <= ub; c++)
+ {
+ if (!(xlb <= xlat(c) && xlat(c) <= ub))
+ {
+ /* range doesn't work */
+ Range * r = new Range(xlb, xlb + 1);
+ for (c = lb + 1; c <= ub; c++)
+ {
+ r = doUnion(r, new Range(xlat(c), xlat(c) + 1));
+ }
+ return r;
+ }
+ }
+
+ lb = xlb;
+ ub = xub;
+ }
+
+ return new Range(lb, ub + 1);
+}
+
+RegExp * Scanner::matchChar(uint c) const
+{
+ return new MatchOp(new Range(c, c + 1));
+}
+
+RegExp * Scanner::strToRE(SubStr s) const
+{
+ s.len -= 2;
+ s.str += 1;
+
+ if (s.len == 0)
+ return new NullOp;
+
+ RegExp *re = matchChar(unescape(s));
+
+ while (s.len > 0)
+ re = new CatOp(re, matchChar(unescape(s)));
+
+ return re;
+}
+
+RegExp * Scanner::strToCaseInsensitiveRE(SubStr s) const
+{
+ s.len -= 2;
+ s.str += 1;
+
+ if (s.len == 0)
+ return new NullOp;
+
+ uint c = unescape(s);
+
+ RegExp *re, *reL, *reU;
+
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+ {
+ reL = matchChar(xlat(tolower(c)));
+ reU = matchChar(xlat(toupper(c)));
+ re = mkAlt(reL, reU);
+ }
+ else
+ {
+ re = matchChar(c);
+ }
+
+ while (s.len > 0)
+ {
+ uint c = unescape(s);
+
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
+ {
+ reL = matchChar(xlat(tolower(c)));
+ reU = matchChar(xlat(toupper(c)));
+ re = new CatOp(re, mkAlt(reL, reU));
+ }
+ else
+ {
+ re = new CatOp(re, matchChar(c));
+ }
+ }
+
+ return re;
+}
+
+RegExp * Scanner::ranToRE(SubStr s) const
+{
+ s.len -= 2;
+ s.str += 1;
+
+ if (s.len == 0)
+ return new NullOp;
+
+ Range *r = getRange(s);
+
+ while (s.len > 0)
+ r = doUnion(r, getRange(s));
+
+ return new MatchOp(r);
+}
+
+RegExp * Scanner::invToRE(SubStr s) const
+{
+ s.len--;
+ s.str++;
+
+ RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
+
+ if (s.len <= 2)
+ {
+ return any;
+ }
+
+ RegExp * ran = ranToRE(s);
+ RegExp * inv = mkDiff(any, ran);
+
+ delete ran;
+ delete any;
+
+ return inv;
+}
+
+RegExp * Scanner::mkDot() const
+{
+ RegExp * any = ranToRE(SubStr(wFlag ? "[\\X0000-\\XFFFF]" : "[\\000-\\377]"));
+ RegExp * ran = matchChar(xlat('\n'));
+ RegExp * inv = mkDiff(any, ran);
+
+ delete ran;
+ delete any;
+
+ return inv;
+}
+
+const char *RuleOp::type = "RuleOp";
+
+RuleOp::RuleOp(RegExp *e, RegExp *c, Token *t, uint a)
+ : exp(e)
+ , ctx(c)
+ , ins(NULL)
+ , accept(a)
+ , code(t)
+ , line(0)
+{
+ ;
+}
+
+void RuleOp::calcSize(Char *rep)
+{
+ exp->calcSize(rep);
+ ctx->calcSize(rep);
+ size = exp->size + (ctx->size ? ctx->size + 2 : 1);
+}
+
+void RuleOp::compile(Char *rep, Ins *i)
+{
+ ins = i;
+ exp->compile(rep, &i[0]);
+ i += exp->size;
+ if (ctx->size)
+ {
+ i->i.tag = CTXT;
+ i->i.link = &i[1];
+ i++;
+ ctx->compile(rep, &i[0]);
+ i += ctx->size;
+ }
+ i->i.tag = TERM;
+ i->i.link = this;
+}
+
+void RuleOp::split(CharSet &s)
+{
+ exp->split(s);
+ ctx->split(s);
+}
+
+void optimize(Ins *i)
+{
+ while (!isMarked(i))
+ {
+ mark(i);
+
+ if (i->i.tag == CHAR)
+ {
+ i = (Ins*) i->i.link;
+ }
+ else if (i->i.tag == GOTO || i->i.tag == FORK)
+ {
+ Ins *target = (Ins*) i->i.link;
+ optimize(target);
+
+ if (target->i.tag == GOTO)
+ i->i.link = target->i.link == target ? i : target;
+
+ if (i->i.tag == FORK)
+ {
+ Ins *follow = (Ins*) & i[1];
+ optimize(follow);
+
+ if (follow->i.tag == GOTO && follow->i.link == follow)
+ {
+ i->i.tag = GOTO;
+ }
+ else if (i->i.link == i)
+ {
+ i->i.tag = GOTO;
+ i->i.link = follow;
+ }
+ }
+
+ return ;
+ }
+ else
+ {
+ ++i;
+ }
+ }
+}
+
+void genCode(std::ostream& o, RegExp *re)
+{
+ genCode(o, 0, re);
+}
+
+CharSet::CharSet()
+ : fix(0)
+ , freeHead(0)
+ , freeTail(0)
+ , rep(new CharPtr[nRealChars])
+ , ptn(new CharPtn[nRealChars])
+{
+ for (uint j = 0; j < nRealChars; ++j)
+ {
+ rep[j] = &ptn[0];
+ ptn[j].nxt = &ptn[j + 1]; /* wrong for j=nRealChars but will be corrected below */
+ ptn[j].card = 0;
+ }
+
+ freeHead = &ptn[1];
+ *(freeTail = &ptn[nRealChars - 1].nxt) = NULL;
+ ptn[0].card = nRealChars;
+ ptn[0].nxt = NULL;
+}
+
+CharSet::~CharSet()
+{
+ delete[] rep;
+ delete[] ptn;
+}
+
+void genCode(std::ostream& o, uint ind, RegExp *re)
+{
+ CharSet cs;
+ uint j;
+
+ re->split(cs);
+ /*
+ for(uint k = 0; k < nChars;){
+ for(j = k; ++k < nRealChars && cs.rep[k] == cs.rep[j];);
+ printSpan(cerr, j, k);
+ cerr << "\t" << cs.rep[j] - &cs.ptn[0] << endl;
+ }
+ */
+ Char *rep = new Char[nRealChars];
+
+ for (j = 0; j < nRealChars; ++j)
+ {
+ if (!cs.rep[j]->nxt)
+ cs.rep[j]->nxt = &cs.ptn[j];
+
+ rep[j] = (Char) (cs.rep[j]->nxt - &cs.ptn[0]);
+ }
+
+ re->calcSize(rep);
+ Ins *ins = new Ins[re->size + 1];
+ memset(ins, 0, (re->size + 1)*sizeof(Ins));
+ re->compile(rep, ins);
+ Ins *eoi = &ins[re->size];
+ eoi->i.tag = GOTO;
+ eoi->i.link = eoi;
+
+ optimize(ins);
+
+ for (j = 0; j < re->size;)
+ {
+ unmark(&ins[j]);
+
+ if (ins[j].i.tag == CHAR)
+ {
+ j = (Ins*) ins[j].i.link - ins;
+ }
+ else
+ {
+ j++;
+ }
+ }
+
+ DFA *dfa = new DFA(ins, re->size, 0, nRealChars, rep);
+ dfa->emit(o, ind);
+ delete dfa;
+ delete [] ins;
+ delete [] rep;
+}
+
+} // end namespace re2c
+
diff --git a/tools/re2c/basics.h b/tools/re2c/basics.h
index 009adda18..c9ddb6276 100644
--- a/tools/re2c/basics.h
+++ b/tools/re2c/basics.h
@@ -1,4 +1,4 @@
-/* $Id: basics.h,v 1.6 2005/12/29 14:32:09 helly Exp $ */
+/* $Id: basics.h 520 2006-05-25 13:31:06Z helly $ */
#ifndef _basics_h
#define _basics_h
diff --git a/tools/re2c/code.cc b/tools/re2c/code.cc
index 38477a24b..f6eea4d0b 100644
--- a/tools/re2c/code.cc
+++ b/tools/re2c/code.cc
@@ -1,900 +1,900 @@
-/* $Id: code.cc,v 1.74 2006/05/14 13:38:26 helly Exp $ */
-#include
-#include
-#include
-#include
-#include
-#include "substr.h"
-#include "globals.h"
-#include "dfa.h"
-#include "parser.h"
-#include "code.h"
-
-namespace re2c
-{
-
-// there must be at least one span in list; all spans must cover
-// same range
-
-std::string indent(uint ind)
-{
- std::string str;
-
- while (ind-- > 0)
- {
- str += indString;
- }
- return str;
-}
-
-static std::string space(uint this_label)
-{
- int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
- int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
-
- return std::string(std::max(1, nl - tl + 1), ' ');
-}
-
-void Go::compact()
-{
- // arrange so that adjacent spans have different targets
- uint i = 0;
-
- for (uint j = 1; j < nSpans; ++j)
- {
- if (span[j].to != span[i].to)
- {
- ++i;
- span[i].to = span[j].to;
- }
-
- span[i].ub = span[j].ub;
- }
-
- nSpans = i + 1;
-}
-
-void Go::unmap(Go *base, const State *x)
-{
- Span *s = span, *b = base->span, *e = &b[base->nSpans];
- uint lb = 0;
- s->ub = 0;
- s->to = NULL;
-
- for (; b != e; ++b)
- {
- if (b->to == x)
- {
- if ((s->ub - lb) > 1)
- {
- s->ub = b->ub;
- }
- }
- else
- {
- if (b->to != s->to)
- {
- if (s->ub)
- {
- lb = s->ub;
- ++s;
- }
-
- s->to = b->to;
- }
-
- s->ub = b->ub;
- }
- }
-
- s->ub = e[ -1].ub;
- ++s;
- nSpans = s - span;
-}
-
-void doGen(const Go *g, const State *s, uint *bm, uint f, uint m)
-{
- Span *b = g->span, *e = &b[g->nSpans];
- uint lb = 0;
-
- for (; b < e; ++b)
- {
- if (b->to == s)
- {
- for (; lb < b->ub && lb < 256; ++lb)
- {
- bm[lb-f] |= m;
- }
- }
-
- lb = b->ub;
- }
-}
-
-void prt(std::ostream& o, const Go *g, const State *s)
-{
- Span *b = g->span, *e = &b[g->nSpans];
- uint lb = 0;
-
- for (; b < e; ++b)
- {
- if (b->to == s)
- {
- printSpan(o, lb, b->ub);
- }
-
- lb = b->ub;
- }
-}
-
-bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2)
-{
- Span *b1 = g1->span, *e1 = &b1[g1->nSpans];
- uint lb1 = 0;
- Span *b2 = g2->span, *e2 = &b2[g2->nSpans];
- uint lb2 = 0;
-
- for (;;)
- {
- for (; b1 < e1 && b1->to != s1; ++b1)
- {
- lb1 = b1->ub;
- }
-
- for (; b2 < e2 && b2->to != s2; ++b2)
- {
- lb2 = b2->ub;
- }
-
- if (b1 == e1)
- {
- return b2 == e2;
- }
-
- if (b2 == e2)
- {
- return false;
- }
-
- if (lb1 != lb2 || b1->ub != b2->ub)
- {
- return false;
- }
-
- ++b1;
- ++b2;
- }
-}
-
-BitMap *BitMap::first = NULL;
-
-BitMap::BitMap(const Go *g, const State *x)
- : go(g)
- , on(x)
- , next(first)
- , i(0)
- , m(0)
-{
- first = this;
-}
-
-BitMap::~BitMap()
-{
- delete next;
-}
-
-const BitMap *BitMap::find(const Go *g, const State *x)
-{
- for (const BitMap *b = first; b; b = b->next)
- {
- if (matches(b->go, b->on, g, x))
- {
- return b;
- }
- }
-
- return new BitMap(g, x);
-}
-
-const BitMap *BitMap::find(const State *x)
-{
- for (const BitMap *b = first; b; b = b->next)
- {
- if (b->on == x)
- {
- return b;
- }
- }
-
- return NULL;
-}
-
-void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub)
-{
- if (first && bLastPass)
- {
- o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {";
-
- uint c = 1, n = ub - lb;
- const BitMap *cb = first;
-
- while((cb = cb->next) != NULL) {
- ++c;
- }
- BitMap *b = first;
-
- uint *bm = new uint[n];
-
- for (uint i = 0, t = 1; b; i += n, t += 8)
- {
- memset(bm, 0, n * sizeof(uint));
-
- for (uint m = 0x80; b && m; m >>= 1)
- {
- b->i = i;
- b->m = m;
- doGen(b->go, b->on, bm, lb, m);
- b = const_cast(b->next);
- }
-
- if (c > 8)
- {
- o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */";
- }
-
- for (uint j = 0; j < n; ++j)
- {
- if (j % 8 == 0)
- {
- o << "\n" << indent(ind+1);
- }
-
- if (yybmHexTable)
- {
- prtHex(o, bm[j], false);
- }
- else
- {
- o << std::setw(3) << (uint)bm[j];
- }
- o << ", ";
- }
- }
-
- o << "\n" << indent(ind) << "};\n";
- /* stats(); */
-
- delete[] bm;
- }
-}
-
-void BitMap::stats()
-{
- uint n = 0;
-
- for (const BitMap *b = first; b; b = b->next)
- {
- prt(std::cerr, b->go, b->on);
- std::cerr << std::endl;
- ++n;
- }
-
- std::cerr << n << " bitmaps\n";
- first = NULL;
-}
-
-void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh)
-{
- if (readCh && from->label + 1 != to->label)
- {
- o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- o << indent(ind) << "goto " << labelPrefix << to->label << ";\n";
- vUsedLabels.insert(to->label);
-}
-
-void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh)
-{
- o << indent(ind) << "if(";
- if (readCh)
- {
+/* $Id: code.cc 717 2007-04-29 22:29:59Z helly $ */
+#include
+#include
+#include
+#include
+#include
+#include "substr.h"
+#include "globals.h"
+#include "dfa.h"
+#include "parser.h"
+#include "code.h"
+
+namespace re2c
+{
+
+// there must be at least one span in list; all spans must cover
+// same range
+
+std::string indent(uint ind)
+{
+ std::string str;
+
+ while (ind-- > 0)
+ {
+ str += indString;
+ }
+ return str;
+}
+
+static std::string space(uint this_label)
+{
+ int nl = next_label > 999999 ? 6 : next_label > 99999 ? 5 : next_label > 9999 ? 4 : next_label > 999 ? 3 : next_label > 99 ? 2 : next_label > 9 ? 1 : 0;
+ int tl = this_label > 999999 ? 6 : this_label > 99999 ? 5 : this_label > 9999 ? 4 : this_label > 999 ? 3 : this_label > 99 ? 2 : this_label > 9 ? 1 : 0;
+
+ return std::string(std::max(1, nl - tl + 1), ' ');
+}
+
+void Go::compact()
+{
+ // arrange so that adjacent spans have different targets
+ uint i = 0;
+
+ for (uint j = 1; j < nSpans; ++j)
+ {
+ if (span[j].to != span[i].to)
+ {
+ ++i;
+ span[i].to = span[j].to;
+ }
+
+ span[i].ub = span[j].ub;
+ }
+
+ nSpans = i + 1;
+}
+
+void Go::unmap(Go *base, const State *x)
+{
+ Span *s = span, *b = base->span, *e = &b[base->nSpans];
+ uint lb = 0;
+ s->ub = 0;
+ s->to = NULL;
+
+ for (; b != e; ++b)
+ {
+ if (b->to == x)
+ {
+ if ((s->ub - lb) > 1)
+ {
+ s->ub = b->ub;
+ }
+ }
+ else
+ {
+ if (b->to != s->to)
+ {
+ if (s->ub)
+ {
+ lb = s->ub;
+ ++s;
+ }
+
+ s->to = b->to;
+ }
+
+ s->ub = b->ub;
+ }
+ }
+
+ s->ub = e[ -1].ub;
+ ++s;
+ nSpans = s - span;
+}
+
+void doGen(const Go *g, const State *s, uint *bm, uint f, uint m)
+{
+ Span *b = g->span, *e = &b[g->nSpans];
+ uint lb = 0;
+
+ for (; b < e; ++b)
+ {
+ if (b->to == s)
+ {
+ for (; lb < b->ub && lb < 256; ++lb)
+ {
+ bm[lb-f] |= m;
+ }
+ }
+
+ lb = b->ub;
+ }
+}
+
+void prt(std::ostream& o, const Go *g, const State *s)
+{
+ Span *b = g->span, *e = &b[g->nSpans];
+ uint lb = 0;
+
+ for (; b < e; ++b)
+ {
+ if (b->to == s)
+ {
+ printSpan(o, lb, b->ub);
+ }
+
+ lb = b->ub;
+ }
+}
+
+bool matches(const Go *g1, const State *s1, const Go *g2, const State *s2)
+{
+ Span *b1 = g1->span, *e1 = &b1[g1->nSpans];
+ uint lb1 = 0;
+ Span *b2 = g2->span, *e2 = &b2[g2->nSpans];
+ uint lb2 = 0;
+
+ for (;;)
+ {
+ for (; b1 < e1 && b1->to != s1; ++b1)
+ {
+ lb1 = b1->ub;
+ }
+
+ for (; b2 < e2 && b2->to != s2; ++b2)
+ {
+ lb2 = b2->ub;
+ }
+
+ if (b1 == e1)
+ {
+ return b2 == e2;
+ }
+
+ if (b2 == e2)
+ {
+ return false;
+ }
+
+ if (lb1 != lb2 || b1->ub != b2->ub)
+ {
+ return false;
+ }
+
+ ++b1;
+ ++b2;
+ }
+}
+
+BitMap *BitMap::first = NULL;
+
+BitMap::BitMap(const Go *g, const State *x)
+ : go(g)
+ , on(x)
+ , next(first)
+ , i(0)
+ , m(0)
+{
+ first = this;
+}
+
+BitMap::~BitMap()
+{
+ delete next;
+}
+
+const BitMap *BitMap::find(const Go *g, const State *x)
+{
+ for (const BitMap *b = first; b; b = b->next)
+ {
+ if (matches(b->go, b->on, g, x))
+ {
+ return b;
+ }
+ }
+
+ return new BitMap(g, x);
+}
+
+const BitMap *BitMap::find(const State *x)
+{
+ for (const BitMap *b = first; b; b = b->next)
+ {
+ if (b->on == x)
+ {
+ return b;
+ }
+ }
+
+ return NULL;
+}
+
+void BitMap::gen(std::ostream &o, uint ind, uint lb, uint ub)
+{
+ if (first && bLastPass)
+ {
+ o << indent(ind) << "static const unsigned char " << mapCodeName["yybm"] << "[] = {";
+
+ uint c = 1, n = ub - lb;
+ const BitMap *cb = first;
+
+ while((cb = cb->next) != NULL) {
+ ++c;
+ }
+ BitMap *b = first;
+
+ uint *bm = new uint[n];
+
+ for (uint i = 0, t = 1; b; i += n, t += 8)
+ {
+ memset(bm, 0, n * sizeof(uint));
+
+ for (uint m = 0x80; b && m; m >>= 1)
+ {
+ b->i = i;
+ b->m = m;
+ doGen(b->go, b->on, bm, lb, m);
+ b = const_cast(b->next);
+ }
+
+ if (c > 8)
+ {
+ o << "\n" << indent(ind+1) << "/* table " << t << " .. " << std::min(c, t+7) << ": " << i << " */";
+ }
+
+ for (uint j = 0; j < n; ++j)
+ {
+ if (j % 8 == 0)
+ {
+ o << "\n" << indent(ind+1);
+ }
+
+ if (yybmHexTable)
+ {
+ prtHex(o, bm[j], false);
+ }
+ else
+ {
+ o << std::setw(3) << (uint)bm[j];
+ }
+ o << ", ";
+ }
+ }
+
+ o << "\n" << indent(ind) << "};\n";
+ /* stats(); */
+
+ delete[] bm;
+ }
+}
+
+void BitMap::stats()
+{
+ uint n = 0;
+
+ for (const BitMap *b = first; b; b = b->next)
+ {
+ prt(std::cerr, b->go, b->on);
+ std::cerr << std::endl;
+ ++n;
+ }
+
+ std::cerr << n << " bitmaps\n";
+ first = NULL;
+}
+
+void genGoTo(std::ostream &o, uint ind, const State *from, const State *to, bool & readCh)
+{
+ if (readCh && from->label + 1 != to->label)
+ {
+ o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
+ readCh = false;
+ }
+
+ o << indent(ind) << "goto " << labelPrefix << to->label << ";\n";
+ vUsedLabels.insert(to->label);
+}
+
+void genIf(std::ostream &o, uint ind, const char *cmp, uint v, bool &readCh)
+{
+ o << indent(ind) << "if(";
+ if (readCh)
+ {
o << "(" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")";
- readCh = false;
- }
- else
- {
- o << mapCodeName["yych"];
- }
-
- o << " " << cmp << " ";
- prtChOrHex(o, v);
- o << ") ";
-}
-
-static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker)
-{
- uint fillIndex = next_fill_index;
-
- if (fFlag)
- {
- next_fill_index++;
+ readCh = false;
+ }
+ else
+ {
+ o << mapCodeName["yych"];
+ }
+
+ o << " " << cmp << " ";
+ prtChOrHex(o, v);
+ o << ") ";
+}
+
+static void need(std::ostream &o, uint ind, uint n, bool & readCh, bool bSetMarker)
+{
+ uint fillIndex = next_fill_index;
+
+ if (fFlag)
+ {
+ next_fill_index++;
o << indent(ind) << mapCodeName["YYSETSTATE"] << "(" << fillIndex << ");\n";
- }
-
- if (bUseYYFill)
- {
- if (n == 1)
- {
+ }
+
+ if (bUseYYFill)
+ {
+ if (n == 1)
+ {
o << indent(ind) << "if(" << mapCodeName["YYLIMIT"] << " == " << mapCodeName["YYCURSOR"] << ") " << mapCodeName["YYFILL"];
- }
- else
- {
- o << indent(ind) << "if((YYLIMIT - YYCURSOR) < " << n << ") YYFILL(" << n << ");\n";
- }
+ }
+ else
+ {
+ o << indent(ind) << "if((" << mapCodeName["YYLIMIT"] << " - " << mapCodeName["YYCURSOR"] << ") < " << n << ") " << mapCodeName["YYFILL"];
+ }
if (bUseYYFillParam)
{
o << "(" << n << ")";
}
o << ";\n";
- }
-
- if (fFlag)
- {
+ }
+
+ if (fFlag)
+ {
o << mapCodeName["yyFillLabel"] << fillIndex << ":\n";
- }
-
- if (bSetMarker)
- {
+ }
+
+ if (bSetMarker)
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ");\n";
- }
- else
- {
+ }
+ else
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
-}
-
-void Match::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (state->link)
- {
+ }
+ readCh = false;
+}
+
+void Match::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (state->link)
+ {
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- else if (!readAhead())
- {
- /* do not read next char if match */
+ }
+ else if (!readAhead())
+ {
+ /* do not read next char if match */
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = true;
- }
- else
- {
+ readCh = true;
+ }
+ else
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- if (state->link)
- {
- need(o, ind, state->depth, readCh, false);
- }
-}
-
-void Enter::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (state->link)
- {
+ readCh = false;
+ }
+
+ if (state->link)
+ {
+ need(o, ind, state->depth, readCh, false);
+ }
+}
+
+void Enter::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (state->link)
+ {
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- if (vUsedLabels.count(label))
- {
+ if (vUsedLabels.count(label))
+ {
o << labelPrefix << label << ":\n";
- }
- need(o, ind, state->depth, readCh, false);
- }
- else
- {
- /* we shouldn't need 'rule-following' protection here */
+ }
+ need(o, ind, state->depth, readCh, false);
+ }
+ else
+ {
+ /* we shouldn't need 'rule-following' protection here */
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- if (vUsedLabels.count(label))
- {
+ if (vUsedLabels.count(label))
+ {
o << labelPrefix << label << ":\n";
- }
- readCh = false;
- }
-}
-
-void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (!startLabelName.empty())
- {
- o << startLabelName << ":\n";
- }
-
- if (vUsedLabels.count(1))
- {
- if (state->link)
- {
+ }
+ readCh = false;
+ }
+}
+
+void Initial::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (!startLabelName.empty())
+ {
+ o << startLabelName << ":\n";
+ }
+
+ if (vUsedLabels.count(1))
+ {
+ if (state->link)
+ {
o << indent(ind) << "++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- else
- {
+ }
+ else
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- }
-
- if (vUsedLabels.count(label))
- {
+ }
+ }
+
+ if (vUsedLabels.count(label))
+ {
o << labelPrefix << label << ":\n";
- }
- else if (!label)
- {
- o << "\n";
- }
-
- if (dFlag)
- {
+ }
+ else if (!label)
+ {
+ o << "\n";
+ }
+
+ if (dFlag)
+ {
o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
- }
-
- if (state->link)
- {
- need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker);
- }
- else
- {
- if (setMarker && bUsedYYMarker)
- {
+ }
+
+ if (state->link)
+ {
+ need(o, ind, state->depth, readCh, setMarker && bUsedYYMarker);
+ }
+ else
+ {
+ if (setMarker && bUsedYYMarker)
+ {
o << indent(ind) << mapCodeName["YYMARKER"] << " = " << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
- }
-}
-
-void Save::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (bUsedYYAccept)
- {
+ }
+ readCh = false;
+ }
+}
+
+void Save::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (bUsedYYAccept)
+ {
o << indent(ind) << mapCodeName["yyaccept"] << " = " << selector << ";\n";
- }
-
- if (state->link)
- {
- if (bUsedYYMarker)
- {
+ }
+
+ if (state->link)
+ {
+ if (bUsedYYMarker)
+ {
o << indent(ind) << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- need(o, ind, state->depth, readCh, false);
- }
- else
- {
- if (bUsedYYMarker)
- {
+ }
+ need(o, ind, state->depth, readCh, false);
+ }
+ else
+ {
+ if (bUsedYYMarker)
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*(" << mapCodeName["YYMARKER"] << " = ++" << mapCodeName["YYCURSOR"] << ");\n";
- }
- else
- {
+ }
+ else
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*++" << mapCodeName["YYCURSOR"] << ";\n";
- }
- readCh = false;
- }
-}
-
-Move::Move(State *s) : Action(s)
-{
- ;
-}
-
-void Move::emit(std::ostream &, uint, bool &) const
-{
- ;
-}
-
-Accept::Accept(State *x, uint n, uint *s, State **r)
- : Action(x), nRules(n), saves(s), rules(r)
-{
- ;
-}
-
-void Accept::genRuleMap()
-{
- for (uint i = 0; i < nRules; ++i)
- {
- if (saves[i] != ~0u)
- {
- mapRules[saves[i]] = rules[i];
- }
- }
-}
-
-void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const
-{
- if (l < r)
- {
- uint m = (l + r) >> 1;
-
+ }
+ readCh = false;
+ }
+}
+
+Move::Move(State *s) : Action(s)
+{
+ ;
+}
+
+void Move::emit(std::ostream &, uint, bool &) const
+{
+ ;
+}
+
+Accept::Accept(State *x, uint n, uint *s, State **r)
+ : Action(x), nRules(n), saves(s), rules(r)
+{
+ ;
+}
+
+void Accept::genRuleMap()
+{
+ for (uint i = 0; i < nRules; ++i)
+ {
+ if (saves[i] != ~0u)
+ {
+ mapRules[saves[i]] = rules[i];
+ }
+ }
+}
+
+void Accept::emitBinary(std::ostream &o, uint ind, uint l, uint r, bool &readCh) const
+{
+ if (l < r)
+ {
+ uint m = (l + r) >> 1;
+
o << indent(ind) << "if(" << mapCodeName["yyaccept"] << " <= " << m << ") {\n";
- emitBinary(o, ++ind, l, m, readCh);
- o << indent(--ind) << "} else {\n";
- emitBinary(o, ++ind, m + 1, r, readCh);
- o << indent(--ind) << "}\n";
- }
- else
- {
- genGoTo(o, ind, state, mapRules.find(l)->second, readCh);
- }
-}
-
-void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (mapRules.size() > 0)
- {
- bUsedYYMarker = true;
+ emitBinary(o, ++ind, l, m, readCh);
+ o << indent(--ind) << "} else {\n";
+ emitBinary(o, ++ind, m + 1, r, readCh);
+ o << indent(--ind) << "}\n";
+ }
+ else
+ {
+ genGoTo(o, ind, state, mapRules.find(l)->second, readCh);
+ }
+}
+
+void Accept::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (mapRules.size() > 0)
+ {
+ bUsedYYMarker = true;
o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYMARKER"] << ";\n";
-
- if (readCh) // shouldn't be necessary, but might become at some point
- {
+
+ if (readCh) // shouldn't be necessary, but might become at some point
+ {
o << indent(ind) << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ";\n";
- readCh = false;
- }
-
- if (mapRules.size() > 1)
- {
- bUsedYYAccept = true;
-
- if (gFlag && mapRules.size() >= cGotoThreshold)
- {
- o << indent(ind++) << "{\n";
+ readCh = false;
+ }
+
+ if (mapRules.size() > 1)
+ {
+ bUsedYYAccept = true;
+
+ if (gFlag && mapRules.size() >= cGotoThreshold)
+ {
+ o << indent(ind++) << "{\n";
o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[" << mapRules.size() << "] = {\n";
- for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
- {
+ for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
+ {
o << indent(ind) << "&&" << labelPrefix << it->second->label << ",\n";
- vUsedLabels.insert(it->second->label);
- }
- o << indent(--ind) << "};\n";
+ vUsedLabels.insert(it->second->label);
+ }
+ o << indent(--ind) << "};\n";
o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << mapCodeName["yyaccept"] << "];\n";
- o << indent(--ind) << "}\n";
- }
- else if (sFlag)
- {
- emitBinary(o, ind, 0, mapRules.size() - 1, readCh);
- }
- else
- {
+ o << indent(--ind) << "}\n";
+ }
+ else if (sFlag)
+ {
+ emitBinary(o, ind, 0, mapRules.size() - 1, readCh);
+ }
+ else
+ {
o << indent(ind) << "switch(" << mapCodeName["yyaccept"] << ") {\n";
-
- for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
- {
- o << indent(ind) << "case " << it->first << ": \t";
- genGoTo(o, 0, state, it->second, readCh);
- }
-
- o << indent(ind) << "}\n";
- }
- }
- else
- {
- // no need to write if statement here since there is only case 0.
- genGoTo(o, ind, state, mapRules.find(0)->second, readCh);
- }
- }
-}
-
-Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r)
-{
- ;
-}
-
-void Rule::emit(std::ostream &o, uint ind, bool &) const
-{
- uint back = rule->ctx->fixedLength();
-
- if (back != 0u)
- {
+
+ for (RuleMap::const_iterator it = mapRules.begin(); it != mapRules.end(); ++it)
+ {
+ o << indent(ind) << "case " << it->first << ": \t";
+ genGoTo(o, 0, state, it->second, readCh);
+ }
+
+ o << indent(ind) << "}\n";
+ }
+ }
+ else
+ {
+ // no need to write if statement here since there is only case 0.
+ genGoTo(o, ind, state, mapRules.find(0)->second, readCh);
+ }
+ }
+}
+
+Rule::Rule(State *s, RuleOp *r) : Action(s), rule(r)
+{
+ ;
+}
+
+void Rule::emit(std::ostream &o, uint ind, bool &) const
+{
+ uint back = rule->ctx->fixedLength();
+
+ if (back != 0u)
+ {
o << indent(ind) << mapCodeName["YYCURSOR"] << " = " << mapCodeName["YYCTXMARKER"] << ";\n";
- }
-
- RuleLine rl(*rule);
-
- o << file_info(sourceFileInfo, &rl);
- o << indent(ind);
- o << rule->code->text;
- o << "\n";
- o << outputFileInfo;
-}
-
-void doLinear(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
-{
- 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)
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, "!=", s[0].ub, readCh);
- genGoTo(o, 0, from, bg, readCh);
- }
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
- return ;
- }
- else
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, "==", s[0].ub, readCh);
- genGoTo(o, 0, from, s[1].to, readCh);
- }
- }
-
- n -= 2;
- s += 2;
- }
-
- if (n == 1)
- {
- // if(bg != next){
- if (s[0].to->label != from->label + 1)
- {
- genGoTo(o, ind, from, s[0].to, readCh);
- }
- // }
- return ;
- }
- else if (n == 2 && bg == next)
- {
- if (!mask || (s[0].ub > 0x00FF))
- {
- genIf(o, ind, ">=", s[0].ub, readCh);
- genGoTo(o, 0, from, s[1].to, readCh);
- }
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
- return ;
- }
- else
- {
- if (!mask || ((s[0].ub - 1) > 0x00FF))
- {
- genIf(o, ind, "<=", s[0].ub - 1, readCh);
- genGoTo(o, 0, from, bg, readCh);
- }
- n -= 1;
- s += 1;
- }
- }
-
- if (next->label != from->label + 1)
- {
- genGoTo(o, ind, from, next, readCh);
- }
-}
-
-void Go::genLinear(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- doLinear(o, ind, span, nSpans, from, next, readCh, mask);
-}
-
-bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask)
-{
- bool used = false;
-
- if (!newLine)
- {
- o << "\n";
- }
- newLine = true;
- if (lb < s->ub)
- {
- for (;;)
- {
- if (!mask || lb > 0x00FF)
- {
- o << indent(ind) << "case ";
- prtChOrHex(o, lb);
- o << ":";
- newLine = false;
- used = true;
- }
-
- if (++lb == s->ub)
- {
- break;
- }
-
- o << "\n";
- newLine = true;
- }
- }
- return used;
-}
-
-void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- bool newLine = true;
-
- if ((mask ? wSpans : nSpans) <= 2)
- {
- genLinear(o, ind, from, next, readCh, mask);
- }
- 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 (dFlag)
- {
+ }
+
+ RuleLine rl(*rule);
+
+ o << file_info(sourceFileInfo, &rl);
+ o << indent(ind);
+ o << rule->code->text;
+ o << "\n";
+ o << outputFileInfo;
+}
+
+void doLinear(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
+{
+ 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)
+ {
+ if (!mask || (s[0].ub > 0x00FF))
+ {
+ genIf(o, ind, "!=", s[0].ub, readCh);
+ genGoTo(o, 0, from, bg, readCh);
+ }
+ if (next->label != from->label + 1)
+ {
+ genGoTo(o, ind, from, next, readCh);
+ }
+ return ;
+ }
+ else
+ {
+ if (!mask || (s[0].ub > 0x00FF))
+ {
+ genIf(o, ind, "==", s[0].ub, readCh);
+ genGoTo(o, 0, from, s[1].to, readCh);
+ }
+ }
+
+ n -= 2;
+ s += 2;
+ }
+
+ if (n == 1)
+ {
+ // if(bg != next){
+ if (s[0].to->label != from->label + 1)
+ {
+ genGoTo(o, ind, from, s[0].to, readCh);
+ }
+ // }
+ return ;
+ }
+ else if (n == 2 && bg == next)
+ {
+ if (!mask || (s[0].ub > 0x00FF))
+ {
+ genIf(o, ind, ">=", s[0].ub, readCh);
+ genGoTo(o, 0, from, s[1].to, readCh);
+ }
+ if (next->label != from->label + 1)
+ {
+ genGoTo(o, ind, from, next, readCh);
+ }
+ return ;
+ }
+ else
+ {
+ if (!mask || ((s[0].ub - 1) > 0x00FF))
+ {
+ genIf(o, ind, "<=", s[0].ub - 1, readCh);
+ genGoTo(o, 0, from, bg, readCh);
+ }
+ n -= 1;
+ s += 1;
+ }
+ }
+
+ if (next->label != from->label + 1)
+ {
+ genGoTo(o, ind, from, next, readCh);
+ }
+}
+
+void Go::genLinear(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
+{
+ doLinear(o, ind, span, nSpans, from, next, readCh, mask);
+}
+
+bool genCases(std::ostream &o, uint ind, uint lb, Span *s, bool &newLine, uint mask)
+{
+ bool used = false;
+
+ if (!newLine)
+ {
+ o << "\n";
+ }
+ newLine = true;
+ if (lb < s->ub)
+ {
+ for (;;)
+ {
+ if (!mask || lb > 0x00FF)
+ {
+ o << indent(ind) << "case ";
+ prtChOrHex(o, lb);
+ o << ":";
+ newLine = false;
+ used = true;
+ }
+
+ if (++lb == s->ub)
+ {
+ break;
+ }
+
+ o << "\n";
+ newLine = true;
+ }
+ }
+ return used;
+}
+
+void Go::genSwitch(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
+{
+ bool newLine = true;
+
+ if ((mask ? wSpans : nSpans) <= 2)
+ {
+ genLinear(o, ind, from, next, readCh, mask);
+ }
+ 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 (dFlag)
+ {
o << indent(ind) << mapCodeName["YYDEBUG"] << "(-1, " << mapCodeName["yych"] << ");\n";
- }
-
- if (readCh)
- {
+ }
+
+ if (readCh)
+ {
o << indent(ind) << "switch((" << mapCodeName["yych"] << " = " << yychConversion << "*" << mapCodeName["YYCURSOR"] << ")) {\n";
- readCh = false;
- }
- else
- {
+ readCh = false;
+ }
+ else
+ {
o << indent(ind) << "switch(" << mapCodeName["yych"] << ") {\n";
- }
-
- while (t != &sP[0])
- {
- bool used = false;
-
- r = s = &sP[0];
-
- if (*s == &span[0])
- {
- used |= genCases(o, ind, 0, *s, newLine, mask);
- }
- else
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
-
- State *to = (*s)->to;
-
- while (++s < t)
- {
- if ((*s)->to == to)
- {
- used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
- }
- else
- {
- *(r++) = *s;
- }
- }
-
- if (used)
- {
- genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
- newLine = true;
- }
- t = r;
- }
-
- o << indent(ind) << "default:";
- genGoTo(o, 1, from, def, readCh);
- o << indent(ind) << "}\n";
-
- delete [] sP;
- }
-}
-
-void doBinary(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
-{
- if (n <= 4)
- {
- doLinear(o, ind, s, n, from, next, readCh, mask);
- }
- else
- {
- uint h = n / 2;
-
- genIf(o, ind, "<=", s[h - 1].ub - 1, readCh);
- o << "{\n";
- doBinary(o, ind+1, &s[0], h, from, next, readCh, mask);
- o << indent(ind) << "} else {\n";
- doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask);
- o << indent(ind) << "}\n";
- }
-}
-
-void Go::genBinary(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- if (mask)
- {
- Span * sc = new Span[wSpans];
-
- for (uint i = 0, j = 0; i < nSpans; i++)
- {
- if (span[i].ub > 0xFF)
- {
- sc[j++] = span[i];
- }
- }
-
- doBinary(o, ind, sc, wSpans, from, next, readCh, mask);
-
- delete[] sc;
- }
- else
- {
- doBinary(o, ind, span, nSpans, from, next, readCh, mask);
- }
-}
-
-void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
-{
- if ((mask ? wSpans : nSpans) == 0)
- {
- return ;
- }
-
- if (!sFlag)
- {
- genSwitch(o, ind, from, next, readCh, mask);
- return ;
- }
-
- if ((mask ? wSpans : 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, ind, from, next, readCh, mask);
- return ;
- }
- }
-
- if ((mask ? wSpans : nSpans) > 5)
- {
- genBinary(o, ind, from, next, readCh, mask);
- }
- else
- {
- genLinear(o, ind, from, next, readCh, mask);
- }
-}
-
-void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const
-{
+ }
+
+ while (t != &sP[0])
+ {
+ bool used = false;
+
+ r = s = &sP[0];
+
+ if (*s == &span[0])
+ {
+ used |= genCases(o, ind, 0, *s, newLine, mask);
+ }
+ else
+ {
+ used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
+ }
+
+ State *to = (*s)->to;
+
+ while (++s < t)
+ {
+ if ((*s)->to == to)
+ {
+ used |= genCases(o, ind, (*s)[ -1].ub, *s, newLine, mask);
+ }
+ else
+ {
+ *(r++) = *s;
+ }
+ }
+
+ if (used)
+ {
+ genGoTo(o, newLine ? ind+1 : 1, from, to, readCh);
+ newLine = true;
+ }
+ t = r;
+ }
+
+ o << indent(ind) << "default:";
+ genGoTo(o, 1, from, def, readCh);
+ o << indent(ind) << "}\n";
+
+ delete [] sP;
+ }
+}
+
+void doBinary(std::ostream &o, uint ind, Span *s, uint n, const State *from, const State *next, bool &readCh, uint mask)
+{
+ if (n <= 4)
+ {
+ doLinear(o, ind, s, n, from, next, readCh, mask);
+ }
+ else
+ {
+ uint h = n / 2;
+
+ genIf(o, ind, "<=", s[h - 1].ub - 1, readCh);
+ o << "{\n";
+ doBinary(o, ind+1, &s[0], h, from, next, readCh, mask);
+ o << indent(ind) << "} else {\n";
+ doBinary(o, ind+1, &s[h], n - h, from, next, readCh, mask);
+ o << indent(ind) << "}\n";
+ }
+}
+
+void Go::genBinary(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
+{
+ if (mask)
+ {
+ Span * sc = new Span[wSpans];
+
+ for (uint i = 0, j = 0; i < nSpans; i++)
+ {
+ if (span[i].ub > 0xFF)
+ {
+ sc[j++] = span[i];
+ }
+ }
+
+ doBinary(o, ind, sc, wSpans, from, next, readCh, mask);
+
+ delete[] sc;
+ }
+ else
+ {
+ doBinary(o, ind, span, nSpans, from, next, readCh, mask);
+ }
+}
+
+void Go::genBase(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh, uint mask) const
+{
+ if ((mask ? wSpans : nSpans) == 0)
+ {
+ return ;
+ }
+
+ if (!sFlag)
+ {
+ genSwitch(o, ind, from, next, readCh, mask);
+ return ;
+ }
+
+ if ((mask ? wSpans : 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, ind, from, next, readCh, mask);
+ return ;
+ }
+ }
+
+ if ((mask ? wSpans : nSpans) > 5)
+ {
+ genBinary(o, ind, from, next, readCh, mask);
+ }
+ else
+ {
+ genLinear(o, ind, from, next, readCh, mask);
+ }
+}
+
+void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh) const
+{
std::string sYych;
if (readCh)
@@ -905,116 +905,116 @@ void Go::genCpGoto(std::ostream &o, uint ind, const State *from, const State *ne
{
sYych = mapCodeName["yych"];
}
-
- readCh = false;
- if (wFlag)
- {
- o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n";
- genBase(o, ind+1, from, next, readCh, 1);
- o << indent(ind++) << "} else {\n";
- sYych = mapCodeName["yych"];
- }
- else
- {
- o << indent(ind++) << "{\n";
- }
+
+ readCh = false;
+ if (wFlag)
+ {
+ o << indent(ind) << "if(" << sYych <<" & ~0xFF) {\n";
+ genBase(o, ind+1, from, next, readCh, 1);
+ o << indent(ind++) << "} else {\n";
+ sYych = mapCodeName["yych"];
+ }
+ else
+ {
+ o << indent(ind++) << "{\n";
+ }
o << indent(ind++) << "static void *" << mapCodeName["yytarget"] << "[256] = {\n";
- o << indent(ind);
-
- uint ch = 0;
- for (uint i = 0; i < lSpans; ++i)
- {
- vUsedLabels.insert(span[i].to->label);
- for(; ch < span[i].ub; ++ch)
- {
+ o << indent(ind);
+
+ uint ch = 0;
+ for (uint i = 0; i < lSpans; ++i)
+ {
+ vUsedLabels.insert(span[i].to->label);
+ for(; ch < span[i].ub; ++ch)
+ {
o << "&&" << labelPrefix << span[i].to->label;
- if (ch == 255)
- {
- o << "\n";
- i = lSpans;
- break;
- }
- else if (ch % 8 == 7)
- {
- o << ",\n" << indent(ind);
- }
- else
- {
- o << "," << space(span[i].to->label);
- }
- }
- }
- o << indent(--ind) << "};\n";
+ if (ch == 255)
+ {
+ o << "\n";
+ i = lSpans;
+ break;
+ }
+ else if (ch % 8 == 7)
+ {
+ o << ",\n" << indent(ind);
+ }
+ else
+ {
+ o << "," << space(span[i].to->label);
+ }
+ }
+ }
+ o << indent(--ind) << "};\n";
o << indent(ind) << "goto *" << mapCodeName["yytarget"] << "[" << sYych << "];\n";
- o << indent(--ind) << "}\n";
-}
-
-void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh)
-{
- if ((gFlag || wFlag) && wSpans == ~0u)
- {
- uint nBitmaps = 0;
- std::set vTargets;
- wSpans = 0;
- lSpans = 1;
- dSpans = 0;
- for (uint i = 0; i < nSpans; ++i)
- {
- if (span[i].ub > 0xFF)
- {
- wSpans++;
- }
- if (span[i].ub < 0x100 || !wFlag)
- {
- lSpans++;
-
- State *to = span[i].to;
-
- if (to && to->isBase)
- {
- const BitMap *b = BitMap::find(to);
-
- if (b && matches(b->go, b->on, this, to))
- {
- nBitmaps++;
- }
- else
- {
- dSpans++;
- vTargets.insert(to->label);
- }
- }
- else
- {
- dSpans++;
- vTargets.insert(to->label);
- }
- }
- }
- lTargets = vTargets.size() >> nBitmaps;
- }
-
- if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold))
- {
- genCpGoto(o, ind, from, next, readCh);
- return;
- }
- else if (bFlag)
- {
- for (uint i = 0; i < nSpans; ++i)
- {
- State *to = span[i].to;
-
- if (to && to->isBase)
- {
- const BitMap *b = BitMap::find(to);
- std::string sYych;
-
- if (b && matches(b->go, b->on, this, to))
- {
- Go go;
- go.span = new Span[nSpans];
- go.unmap(this, to);
+ o << indent(--ind) << "}\n";
+}
+
+void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next, bool &readCh)
+{
+ if ((gFlag || wFlag) && wSpans == ~0u)
+ {
+ uint nBitmaps = 0;
+ std::set vTargets;
+ wSpans = 0;
+ lSpans = 1;
+ dSpans = 0;
+ for (uint i = 0; i < nSpans; ++i)
+ {
+ if (span[i].ub > 0xFF)
+ {
+ wSpans++;
+ }
+ if (span[i].ub < 0x100 || !wFlag)
+ {
+ lSpans++;
+
+ State *to = span[i].to;
+
+ if (to && to->isBase)
+ {
+ const BitMap *b = BitMap::find(to);
+
+ if (b && matches(b->go, b->on, this, to))
+ {
+ nBitmaps++;
+ }
+ else
+ {
+ dSpans++;
+ vTargets.insert(to->label);
+ }
+ }
+ else
+ {
+ dSpans++;
+ vTargets.insert(to->label);
+ }
+ }
+ }
+ lTargets = vTargets.size() >> nBitmaps;
+ }
+
+ if (gFlag && (lTargets >= cGotoThreshold || dSpans >= cGotoThreshold))
+ {
+ genCpGoto(o, ind, from, next, readCh);
+ return;
+ }
+ else if (bFlag)
+ {
+ for (uint i = 0; i < nSpans; ++i)
+ {
+ State *to = span[i].to;
+
+ if (to && to->isBase)
+ {
+ const BitMap *b = BitMap::find(to);
+ std::string sYych;
+
+ if (b && matches(b->go, b->on, this, to))
+ {
+ Go go;
+ go.span = new Span[nSpans];
+ go.unmap(this, to);
if (readCh)
{
sYych = "(" + mapCodeName["yych"] + " = " + yychConversion + "*" + mapCodeName["YYCURSOR"] + ")";
@@ -1023,683 +1023,683 @@ void Go::genGoto(std::ostream &o, uint ind, const State *from, const State *next
{
sYych = mapCodeName["yych"];
}
- readCh = false;
- if (wFlag)
- {
+ readCh = false;
+ if (wFlag)
+ {
o << indent(ind) << "if(" << sYych << " & ~0xFF) {\n";
sYych = mapCodeName["yych"];
- genBase(o, ind+1, from, next, readCh, 1);
- o << indent(ind) << "} else ";
- }
- else
- {
- o << indent(ind);
- }
+ genBase(o, ind+1, from, next, readCh, 1);
+ o << indent(ind) << "} else ";
+ }
+ else
+ {
+ o << indent(ind);
+ }
o << "if(" << mapCodeName["yybm"] << "[" << b->i << "+" << sYych << "] & ";
- if (yybmHexTable)
- {
- prtHex(o, b->m, false);
- }
- else
- {
- o << (uint) b->m;
- }
- o << ") {\n";
- genGoTo(o, ind+1, from, to, readCh);
- o << indent(ind) << "}\n";
- go.genBase(o, ind, from, next, readCh, 0);
- delete [] go.span;
- return ;
- }
- }
- }
- }
-
- genBase(o, ind, from, next, readCh, 0);
-}
-
-void State::emit(std::ostream &o, uint ind, bool &readCh) const
-{
- if (vUsedLabels.count(label))
- {
+ if (yybmHexTable)
+ {
+ prtHex(o, b->m, false);
+ }
+ else
+ {
+ o << (uint) b->m;
+ }
+ o << ") {\n";
+ genGoTo(o, ind+1, from, to, readCh);
+ o << indent(ind) << "}\n";
+ go.genBase(o, ind, from, next, readCh, 0);
+ delete [] go.span;
+ return ;
+ }
+ }
+ }
+ }
+
+ genBase(o, ind, from, next, readCh, 0);
+}
+
+void State::emit(std::ostream &o, uint ind, bool &readCh) const
+{
+ if (vUsedLabels.count(label))
+ {
o << labelPrefix << label << ":\n";
- }
- if (dFlag && !action->isInitial())
- {
+ }
+ if (dFlag && !action->isInitial())
+ {
o << indent(ind) << mapCodeName["YYDEBUG"] << "(" << label << ", *" << mapCodeName["YYCURSOR"] << ");\n";
- }
- if (isPreCtxt)
- {
+ }
+ if (isPreCtxt)
+ {
o << indent(ind) << mapCodeName["YYCTXMARKER"] << " = " << mapCodeName["YYCURSOR"] << " + 1;\n";
- }
- action->emit(o, ind, 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;
-
-public:
- SCC(uint);
- ~SCC();
- void traverse(State*);
-
-#ifdef PEDANTIC
-private:
- SCC(const SCC& oth)
- : top(oth.top)
- , stk(oth.stk)
- {
- }
- SCC& operator = (const SCC& oth)
- {
- new(this) SCC(oth);
- return *this;
- }
-#endif
-};
-
-SCC::SCC(uint size)
- : top(new State * [size])
- , stk(top)
-{
-}
-
-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;
- }
- }
- }
-
- if (x->depth == k)
- {
- do
- {
- (*--top)->depth = cInfinity;
- (*top)->link = x;
- }
- while (*top != x);
- }
-}
-
-static bool state_is_in_non_trivial_SCC(const State* s)
-{
-
- // does not link to self
- if (s->link != s)
- {
- return true;
- }
-
- // or exists i: (s->go.spans[i].to->link == s)
- //
- // Note: (s->go.spans[i].to == s) is allowed, corresponds to s
- // looping back to itself.
- //
- for (uint i = 0; i < s->go.nSpans; ++i)
- {
- const State* t = s->go.span[i].to;
-
- if (t && t->link == s)
- {
- return true;
- }
- }
- // otherwise no
- return false;
-}
-
-uint maxDist(State *s)
-{
- if (s->depth != cInfinity)
- {
- // Already calculated, just return result.
- return s->depth;
- }
- 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) // marked as non-key state
- {
- if (t->depth == cInfinity)
- {
- t->depth = maxDist(t);
- }
- m += t->depth;
- }
-
- if (m > mm)
- {
- mm = m;
- }
- }
- }
-
- s->depth = mm;
- return mm;
-}
-
-void calcDepth(State *head)
-{
- State* s;
-
- // mark non-key states by s->link = NULL ;
- for (s = head; s; s = s->next)
- {
- if (s != head && !state_is_in_non_trivial_SCC(s))
- {
- s->link = NULL;
- }
- //else: key state, leave alone
- }
-
- for (s = head; s; s = s->next)
- {
- s->depth = cInfinity;
- }
-
- // calculate max number of transitions before guarantied to reach
- // a key state.
- for (s = head; s; s = s->next)
- {
- maxDist(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)
- {
- 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::findBaseState()
-{
- Span *span = new Span[ubChar - lbChar];
-
- for (State *s = head; s; s = s->next)
- {
- if (!s->link)
- {
- for (uint 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;
-}
-
-void DFA::emit(std::ostream &o, uint ind)
-{
- State *s;
- uint i, bitmap_brace = 0;
-
- findSCCs();
- head->link = head;
-
- uint nRules = 0;
-
- for (s = head; s; s = s->next)
- {
- s->depth = maxDist(s);
- if (maxFill < s->depth)
- {
- maxFill = s->depth;
- }
- 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
- bool bSaveOnHead = false;
-
- for (s = head; s; s = s->next)
- {
- 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;
- s->action = NULL;
-
- if (saves[s->rule->accept] == ~0u)
- {
- saves[s->rule->accept] = nSaves++;
- }
-
- bSaveOnHead |= s == head;
- (void) new Save(s, saves[s->rule->accept]); // sets s->action
- }
- }
- }
- }
-
- // insert actions
- State **rules = new State * [nRules];
-
- memset(rules, 0, (nRules)*sizeof(*rules));
-
- State *accept = NULL;
- Accept *accfixup = 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;
- accfixup = new Accept(accept, nRules, saves, rules);
- addState(&s->next, accept);
- }
-
- s->go.span[i].to = ow;
- }
- }
- }
-
- if (accfixup)
- {
- accfixup->genRuleMap();
- }
-
- // 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;
- }
- }
- }
- }
-
- // find ``base'' state, if possible
- findBaseState();
-
- delete head->action;
- head->action = NULL;
-
- if (bFlag)
- {
- o << indent(ind++) << "{\n";
- bitmap_brace = 1;
- BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
- }
-
- bUsedYYAccept = false;
-
- uint start_label = next_label;
-
- (void) new Initial(head, next_label++, bSaveOnHead);
-
- if (bUseStartLabel)
- {
- if (startLabelName.empty())
- {
- vUsedLabels.insert(start_label);
- }
- }
-
- for (s = head; s; s = s->next)
- {
- s->label = next_label++;
- }
-
- // Save 'next_fill_index' and compute information about code generation
- // while writing to null device.
- uint save_fill_index = next_fill_index;
- null_stream null_dev;
-
- for (s = head; s; s = s->next)
- {
- bool readCh = false;
- s->emit(null_dev, ind, readCh);
- s->go.genGoto(null_dev, ind, s, s->next, readCh);
- }
- if (last_fill_index < next_fill_index)
- {
- last_fill_index = next_fill_index;
- }
- next_fill_index = save_fill_index;
-
- // Generate prolog
- o << "\n" << outputFileInfo;
- o << indent(ind++) << "{\n";
-
- if (!fFlag)
- {
+ }
+ action->emit(o, ind, 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;
+
+public:
+ SCC(uint);
+ ~SCC();
+ void traverse(State*);
+
+#ifdef PEDANTIC
+private:
+ SCC(const SCC& oth)
+ : top(oth.top)
+ , stk(oth.stk)
+ {
+ }
+ SCC& operator = (const SCC& oth)
+ {
+ new(this) SCC(oth);
+ return *this;
+ }
+#endif
+};
+
+SCC::SCC(uint size)
+ : top(new State * [size])
+ , stk(top)
+{
+}
+
+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;
+ }
+ }
+ }
+
+ if (x->depth == k)
+ {
+ do
+ {
+ (*--top)->depth = cInfinity;
+ (*top)->link = x;
+ }
+ while (*top != x);
+ }
+}
+
+static bool state_is_in_non_trivial_SCC(const State* s)
+{
+
+ // does not link to self
+ if (s->link != s)
+ {
+ return true;
+ }
+
+ // or exists i: (s->go.spans[i].to->link == s)
+ //
+ // Note: (s->go.spans[i].to == s) is allowed, corresponds to s
+ // looping back to itself.
+ //
+ for (uint i = 0; i < s->go.nSpans; ++i)
+ {
+ const State* t = s->go.span[i].to;
+
+ if (t && t->link == s)
+ {
+ return true;
+ }
+ }
+ // otherwise no
+ return false;
+}
+
+uint maxDist(State *s)
+{
+ if (s->depth != cInfinity)
+ {
+ // Already calculated, just return result.
+ return s->depth;
+ }
+ 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) // marked as non-key state
+ {
+ if (t->depth == cInfinity)
+ {
+ t->depth = maxDist(t);
+ }
+ m += t->depth;
+ }
+
+ if (m > mm)
+ {
+ mm = m;
+ }
+ }
+ }
+
+ s->depth = mm;
+ return mm;
+}
+
+void calcDepth(State *head)
+{
+ State* s;
+
+ // mark non-key states by s->link = NULL ;
+ for (s = head; s; s = s->next)
+ {
+ if (s != head && !state_is_in_non_trivial_SCC(s))
+ {
+ s->link = NULL;
+ }
+ //else: key state, leave alone
+ }
+
+ for (s = head; s; s = s->next)
+ {
+ s->depth = cInfinity;
+ }
+
+ // calculate max number of transitions before guarantied to reach
+ // a key state.
+ for (s = head; s; s = s->next)
+ {
+ maxDist(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)
+ {
+ 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::findBaseState()
+{
+ Span *span = new Span[ubChar - lbChar];
+
+ for (State *s = head; s; s = s->next)
+ {
+ if (!s->link)
+ {
+ for (uint 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;
+}
+
+void DFA::emit(std::ostream &o, uint ind)
+{
+ State *s;
+ uint i, bitmap_brace = 0;
+
+ findSCCs();
+ head->link = head;
+
+ uint nRules = 0;
+
+ for (s = head; s; s = s->next)
+ {
+ s->depth = maxDist(s);
+ if (maxFill < s->depth)
+ {
+ maxFill = s->depth;
+ }
+ 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
+ bool bSaveOnHead = false;
+
+ for (s = head; s; s = s->next)
+ {
+ 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;
+ s->action = NULL;
+
+ if (saves[s->rule->accept] == ~0u)
+ {
+ saves[s->rule->accept] = nSaves++;
+ }
+
+ bSaveOnHead |= s == head;
+ (void) new Save(s, saves[s->rule->accept]); // sets s->action
+ }
+ }
+ }
+ }
+
+ // insert actions
+ State **rules = new State * [nRules];
+
+ memset(rules, 0, (nRules)*sizeof(*rules));
+
+ State *accept = NULL;
+ Accept *accfixup = 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;
+ accfixup = new Accept(accept, nRules, saves, rules);
+ addState(&s->next, accept);
+ }
+
+ s->go.span[i].to = ow;
+ }
+ }
+ }
+
+ if (accfixup)
+ {
+ accfixup->genRuleMap();
+ }
+
+ // 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;
+ }
+ }
+ }
+ }
+
+ // find ``base'' state, if possible
+ findBaseState();
+
+ delete head->action;
+ head->action = NULL;
+
+ if (bFlag)
+ {
+ o << indent(ind++) << "{\n";
+ bitmap_brace = 1;
+ BitMap::gen(o, ind, lbChar, ubChar <= 256 ? ubChar : 256);
+ }
+
+ bUsedYYAccept = false;
+
+ uint start_label = next_label;
+
+ (void) new Initial(head, next_label++, bSaveOnHead);
+
+ if (bUseStartLabel)
+ {
+ if (startLabelName.empty())
+ {
+ vUsedLabels.insert(start_label);
+ }
+ }
+
+ for (s = head; s; s = s->next)
+ {
+ s->label = next_label++;
+ }
+
+ // Save 'next_fill_index' and compute information about code generation
+ // while writing to null device.
+ uint save_fill_index = next_fill_index;
+ null_stream null_dev;
+
+ for (s = head; s; s = s->next)
+ {
+ bool readCh = false;
+ s->emit(null_dev, ind, readCh);
+ s->go.genGoto(null_dev, ind, s, s->next, readCh);
+ }
+ if (last_fill_index < next_fill_index)
+ {
+ last_fill_index = next_fill_index;
+ }
+ next_fill_index = save_fill_index;
+
+ // Generate prolog
+ o << "\n" << outputFileInfo;
+ o << indent(ind++) << "{\n";
+
+ if (!fFlag)
+ {
o << indent(ind) << mapCodeName["YYCTYPE"] << " " << mapCodeName["yych"] << ";\n";
- if (bUsedYYAccept)
- {
+ if (bUsedYYAccept)
+ {
o << indent(ind) << "unsigned int "<< mapCodeName["yyaccept"] << " = 0;\n";
- }
- }
- else
- {
- o << "\n";
- }
-
- genGetState(o, ind, start_label);
-
- if (vUsedLabels.count(1))
- {
- vUsedLabels.insert(0);
+ }
+ }
+ else
+ {
+ o << "\n";
+ }
+
+ genGetState(o, ind, start_label);
+
+ if (vUsedLabels.count(1))
+ {
+ vUsedLabels.insert(0);
o << indent(ind) << "goto " << labelPrefix << "0;\n";
- }
-
- // Generate code
- for (s = head; s; s = s->next)
- {
- bool readCh = false;
- s->emit(o, ind, readCh);
- s->go.genGoto(o, ind, s, s->next, readCh);
- }
-
- // Generate epilog
- o << indent(--ind) << "}\n";
- if (bitmap_brace)
- {
- o << indent(--ind) << "}\n";
- }
-
- // Cleanup
- if (BitMap::first)
- {
- delete BitMap::first;
- BitMap::first = NULL;
- }
-
- delete [] saves;
- delete [] rules;
-
- bUseStartLabel = false;
-}
-
-void genGetState(std::ostream &o, uint& ind, uint start_label)
-{
- if (fFlag && !bWroteGetState)
- {
- vUsedLabels.insert(start_label);
+ }
+
+ // Generate code
+ for (s = head; s; s = s->next)
+ {
+ bool readCh = false;
+ s->emit(o, ind, readCh);
+ s->go.genGoto(o, ind, s, s->next, readCh);
+ }
+
+ // Generate epilog
+ o << indent(--ind) << "}\n";
+ if (bitmap_brace)
+ {
+ o << indent(--ind) << "}\n";
+ }
+
+ // Cleanup
+ if (BitMap::first)
+ {
+ delete BitMap::first;
+ BitMap::first = NULL;
+ }
+
+ delete [] saves;
+ delete [] rules;
+
+ bUseStartLabel = false;
+}
+
+void genGetState(std::ostream &o, uint& ind, uint start_label)
+{
+ if (fFlag && !bWroteGetState)
+ {
+ vUsedLabels.insert(start_label);
o << indent(ind) << "switch(" << mapCodeName["YYGETSTATE"] << "()) {\n";
- if (bUseStateAbort)
- {
- o << indent(ind) << "default: abort();\n";
+ if (bUseStateAbort)
+ {
+ o << indent(ind) << "default: abort();\n";
o << indent(ind) << "case -1: goto " << labelPrefix << start_label << ";\n";
- }
- else
- {
+ }
+ else
+ {
o << indent(ind) << "default: goto " << labelPrefix << start_label << ";\n";
- }
-
- for (size_t i=0; iget_line() << " \"" << li.fname << "\"\n";
- }
- return o;
-}
-
-uint Scanner::get_line() const
-{
- return cline;
-}
-
-void Scanner::config(const Str& cfg, int num)
-{
- if (cfg.to_string() == "indent:top")
- {
- if (num < 0)
- {
- fatal("configuration 'indent:top' must be a positive integer");
- }
- topIndent = num;
- }
- else if (cfg.to_string() == "yybm:hex")
- {
- yybmHexTable = num != 0;
- }
- else if (cfg.to_string() == "startlabel")
- {
- bUseStartLabel = num != 0;
- startLabelName = "";
- }
- else if (cfg.to_string() == "state:abort")
- {
- bUseStateAbort = num != 0;
- }
- else if (cfg.to_string() == "state:nextlabel")
- {
- bUseStateNext = num != 0;
- }
- else if (cfg.to_string() == "yyfill:enable")
- {
- bUseYYFill = num != 0;
- }
+ }
+ bWroteGetState = true;
+ }
+}
+
+std::ostream& operator << (std::ostream& o, const file_info& li)
+{
+ if (li.ln && !iFlag)
+ {
+ o << "#line " << li.ln->get_line() << " \"" << li.fname << "\"\n";
+ }
+ return o;
+}
+
+uint Scanner::get_line() const
+{
+ return cline;
+}
+
+void Scanner::config(const Str& cfg, int num)
+{
+ if (cfg.to_string() == "indent:top")
+ {
+ if (num < 0)
+ {
+ fatal("configuration 'indent:top' must be a positive integer");
+ }
+ topIndent = num;
+ }
+ else if (cfg.to_string() == "yybm:hex")
+ {
+ yybmHexTable = num != 0;
+ }
+ else if (cfg.to_string() == "startlabel")
+ {
+ bUseStartLabel = num != 0;
+ startLabelName = "";
+ }
+ else if (cfg.to_string() == "state:abort")
+ {
+ bUseStateAbort = num != 0;
+ }
+ else if (cfg.to_string() == "state:nextlabel")
+ {
+ bUseStateNext = num != 0;
+ }
+ else if (cfg.to_string() == "yyfill:enable")
+ {
+ bUseYYFill = num != 0;
+ }
else if (cfg.to_string() == "yyfill:parameter")
{
bUseYYFillParam = num != 0;
}
- else if (cfg.to_string() == "cgoto:threshold")
- {
- cGotoThreshold = num;
- }
+ else if (cfg.to_string() == "cgoto:threshold")
+ {
+ cGotoThreshold = num;
+ }
else if (cfg.to_string() == "yych:conversion")
{
if (num)
@@ -1713,18 +1713,18 @@ void Scanner::config(const Str& cfg, int num)
yychConversion = "";
}
}
- else
- {
- fatal("unrecognized configuration name or illegal integer value");
- }
-}
-
+ else
+ {
+ fatal("unrecognized configuration name or illegal integer value");
+ }
+}
+
static std::set mapVariableKeys;
static std::set mapDefineKeys;
static std::set mapLabelKeys;
-void Scanner::config(const Str& cfg, const Str& val)
-{
+void Scanner::config(const Str& cfg, const Str& val)
+{
if (mapDefineKeys.empty())
{
mapVariableKeys.insert("variable:yyaccept");
@@ -1757,15 +1757,15 @@ void Scanner::config(const Str& cfg, const Str& val)
strVal = val.to_string();
}
- if (cfg.to_string() == "indent:string")
- {
- indString = strVal;
- }
- else if (cfg.to_string() == "startlabel")
- {
- startLabelName = val.to_string();
- bUseStartLabel = !startLabelName.empty();
- }
+ if (cfg.to_string() == "indent:string")
+ {
+ indString = strVal;
+ }
+ else if (cfg.to_string() == "startlabel")
+ {
+ startLabelName = strVal;
+ bUseStartLabel = !startLabelName.empty();
+ }
else if (cfg.to_string() == "labelprefix")
{
labelPrefix = strVal;
@@ -1797,10 +1797,10 @@ void Scanner::config(const Str& cfg, const Str& val)
fatal("label already being used and cannot be changed");
}
}
- else
- {
- fatal("unrecognized configuration name or illegal string value");
- }
-}
-
-} // end namespace re2c
+ else
+ {
+ fatal("unrecognized configuration name or illegal string value");
+ }
+}
+
+} // end namespace re2c
diff --git a/tools/re2c/code.h b/tools/re2c/code.h
index 5f2e55123..ed9df0dde 100644
--- a/tools/re2c/code.h
+++ b/tools/re2c/code.h
@@ -1,4 +1,4 @@
-/* $Id: code.h,v 1.7 2006/01/21 15:51:02 helly Exp $ */
+/* $Id: code.h 525 2006-05-25 13:32:49Z helly $ */
#ifndef _code_h
#define _code_h
diff --git a/tools/re2c/dfa.h b/tools/re2c/dfa.h
index e5ac5f4e9..fac2fe21c 100644
--- a/tools/re2c/dfa.h
+++ b/tools/re2c/dfa.h
@@ -1,4 +1,4 @@
-/* $Id: dfa.h,v 1.23 2006/05/14 13:38:26 helly Exp $ */
+/* $Id: dfa.h 569 2006-06-05 22:14:00Z helly $ */
#ifndef _dfa_h
#define _dfa_h
diff --git a/tools/re2c/globals.h b/tools/re2c/globals.h
index b9cc10e16..341d0aac3 100644
--- a/tools/re2c/globals.h
+++ b/tools/re2c/globals.h
@@ -1,4 +1,4 @@
-/* $Id: globals.h,v 1.31 2006/05/14 13:38:26 helly Exp $ */
+/* $Id: globals.h 713 2007-04-29 15:33:47Z helly $ */
#ifndef _globals_h
#define _globals_h
diff --git a/tools/re2c/ins.h b/tools/re2c/ins.h
index 013273859..a2e379585 100644
--- a/tools/re2c/ins.h
+++ b/tools/re2c/ins.h
@@ -1,4 +1,4 @@
-/* $Id: ins.h,v 1.7 2006/01/03 11:40:38 helly Exp $ */
+/* $Id: ins.h 535 2006-05-25 13:36:14Z helly $ */
#ifndef _ins_h
#define _ins_h
diff --git a/tools/re2c/main.cc b/tools/re2c/main.cc
index 966d7e5ad..1116b9772 100644
--- a/tools/re2c/main.cc
+++ b/tools/re2c/main.cc
@@ -1,4 +1,4 @@
-/* $Id: main.cc,v 1.53 2006/05/14 13:38:26 helly Exp $ */
+/* $Id: main.cc 691 2007-04-22 15:07:39Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#elif defined(_WIN32)
@@ -139,7 +139,7 @@ static void usage()
" with -f and disables YYMAXFILL generation prior to last\n"
" re2c block.\n"
"\n"
- "--no-generation-date Suppress the date output in the generated output so that it\n"
+ "--no-generation-date Suppress date output in the generated output so that it\n"
" only shows the re2c version.\n"
;
}
diff --git a/tools/re2c/mbo_getopt.cc b/tools/re2c/mbo_getopt.cc
index 8c33332f3..637627926 100644
--- a/tools/re2c/mbo_getopt.cc
+++ b/tools/re2c/mbo_getopt.cc
@@ -2,7 +2,7 @@
Author: Marcus Boerger
*/
-/* $Id: mbo_getopt.cc,v 1.5 2006/04/17 19:28:47 helly Exp $ */
+/* $Id: mbo_getopt.cc 698 2007-04-23 21:06:56Z helly $ */
#include
#include
diff --git a/tools/re2c/mbo_getopt.h b/tools/re2c/mbo_getopt.h
index f38b7ab5e..ca72f0db7 100644
--- a/tools/re2c/mbo_getopt.h
+++ b/tools/re2c/mbo_getopt.h
@@ -2,7 +2,7 @@
Author: Marcus Boerger
*/
-/* $Id: mbo_getopt.h,v 1.5 2006/04/17 19:28:47 helly Exp $ */
+/* $Id: mbo_getopt.h 539 2006-05-25 13:37:38Z helly $ */
/* Define structure for one recognized option (both single char and long name).
* If short_open is '-' this is the last option.
diff --git a/tools/re2c/parser.cc b/tools/re2c/parser.cc
index 7cbf7a803..ad1bf74ec 100644
--- a/tools/re2c/parser.cc
+++ b/tools/re2c/parser.cc
@@ -95,7 +95,7 @@
#line 1 "./parser.y"
-/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
+/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/tools/re2c/parser.h b/tools/re2c/parser.h
index 1f367c58d..642d6db4e 100644
--- a/tools/re2c/parser.h
+++ b/tools/re2c/parser.h
@@ -1,4 +1,4 @@
-/* $Id: parser.h,v 1.10 2006/01/21 15:51:02 helly Exp $ */
+/* $Id: parser.h 565 2006-06-05 22:07:13Z helly $ */
#ifndef _parser_h
#define _parser_h
diff --git a/tools/re2c/parser.y b/tools/re2c/parser.y
index fa6e267a7..0164c45fe 100644
--- a/tools/re2c/parser.y
+++ b/tools/re2c/parser.y
@@ -1,6 +1,6 @@
%{
-/* $Id: parser.y,v 1.20 2006/04/16 15:15:46 helly Exp $ */
+/* $Id: parser.y 674 2007-04-16 21:39:11Z helly $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
diff --git a/tools/re2c/re.h b/tools/re2c/re.h
index 2dd652bfc..f17bdff7c 100644
--- a/tools/re2c/re.h
+++ b/tools/re2c/re.h
@@ -1,16 +1,16 @@
-/* $Id: re.h,v 1.17 2006/04/09 00:06:33 helly Exp $ */
-#ifndef _re_h
-#define _re_h
-
-#include
-#include
-#include "token.h"
-#include "ins.h"
-#include "globals.h"
-
-namespace re2c
-{
-
+/* $Id: re.h 775 2007-07-10 19:33:17Z helly $ */
+#ifndef _re_h
+#define _re_h
+
+#include
+#include
+#include "token.h"
+#include "ins.h"
+#include "globals.h"
+
+namespace re2c
+{
+
template
class free_list: protected std::set<_Ty>
{
@@ -55,436 +55,442 @@ public:
protected:
bool in_clear;
};
-
-typedef struct extop
-{
- char op;
- int minsize;
- int maxsize;
-}
-
-ExtOp;
-
-struct CharPtn
-{
- uint card;
- CharPtn *fix;
- CharPtn *nxt;
-};
-
-typedef CharPtn *CharPtr;
-
-struct CharSet
-{
- CharSet();
- ~CharSet();
-
- CharPtn *fix;
- CharPtn *freeHead, **freeTail;
- CharPtr *rep;
- CharPtn *ptn;
-};
-
-class Range
-{
-
-public:
- Range *next;
- uint lb, ub; // [lb,ub)
-
- static free_list vFreeList;
-
-public:
- Range(uint l, uint u) : next(NULL), lb(l), ub(u)
- {
- vFreeList.insert(this);
- }
-
- Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
- {
- vFreeList.insert(this);
- }
-
- friend std::ostream& operator<<(std::ostream&, const Range&);
- friend std::ostream& operator<<(std::ostream&, const Range*);
-};
-
-inline std::ostream& operator<<(std::ostream &o, const Range *r)
-{
- return r ? o << *r : o;
-}
-
-class RegExp
-{
-
-public:
- uint size;
-
- static free_list vFreeList;
-
-public:
- RegExp() : size(0)
- {
- }
-
- virtual ~RegExp()
- {
- vFreeList.erase(this);
- }
-
- virtual const char *typeOf() = 0;
- RegExp *isA(const char *t)
- {
- return typeOf() == t ? this : NULL;
- }
-
- virtual void split(CharSet&) = 0;
- virtual void calcSize(Char*) = 0;
- virtual uint fixedLength();
- virtual void compile(Char*, Ins*) = 0;
- virtual void display(std::ostream&) const = 0;
- friend std::ostream& operator<<(std::ostream&, const RegExp&);
- friend std::ostream& operator<<(std::ostream&, const RegExp*);
-};
-
-inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
-{
- re.display(o);
- return o;
-}
-
-inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
-{
- return o << *re;
-}
-
-class NullOp: public RegExp
-{
-
-public:
- static const char *type;
-
-public:
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- uint fixedLength();
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << "_";
- }
-};
-
-class MatchOp: public RegExp
-{
-
-public:
- static const char *type;
- Range *match;
-
-public:
- MatchOp(Range *m) : match(m)
- {
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- uint fixedLength();
- void compile(Char*, Ins*);
- void display(std::ostream&) const;
-
-#ifdef PEDANTIC
-private:
- MatchOp(const MatchOp& oth)
- : RegExp(oth)
- , match(oth.match)
- {
- }
-
- MatchOp& operator = (const MatchOp& oth)
- {
- new(this) MatchOp(oth);
- return *this;
- }
-#endif
-};
-
-class RuleOp: public RegExp
-{
-public:
- static const char *type;
-
-private:
- RegExp *exp;
-
-public:
- RegExp *ctx;
- Ins *ins;
- uint accept;
- Token *code;
- uint line;
-
-public:
- RuleOp(RegExp*, RegExp*, Token*, uint);
-
- ~RuleOp()
- {
- delete code;
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << exp << "/" << ctx << ";";
- }
-
-#ifdef PEDANTIC
-private:
- RuleOp(const RuleOp& oth)
- : RegExp(oth)
- , exp(oth.exp)
- , ctx(oth.ctx)
- , ins(oth.ins)
- , accept(oth.accept)
- , code(oth.code)
- , line(oth.line)
- {
- }
- RuleOp& operator = (const RuleOp& oth)
- {
- new(this) RuleOp(oth);
- return *this;
- }
-#endif
-};
-
-class RuleLine: public line_number
-{
-public:
-
- RuleLine(const RuleOp& _op)
- : op(_op)
- {
- }
-
- uint get_line() const
- {
- return op.code->line;
- }
-
- const RuleOp& op;
-};
-
-RegExp *mkAlt(RegExp*, RegExp*);
-
-class AltOp: public RegExp
-{
-
-private:
- RegExp *exp1, *exp2;
-
-public:
- static const char *type;
-
-public:
- AltOp(RegExp *e1, RegExp *e2)
- : exp1(e1)
- , exp2(e2)
- {
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- uint fixedLength();
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << exp1 << "|" << exp2;
- }
-
- friend RegExp *mkAlt(RegExp*, RegExp*);
-
-#ifdef PEDANTIC
-private:
- AltOp(const AltOp& oth)
- : RegExp(oth)
- , exp1(oth.exp1)
- , exp2(oth.exp2)
- {
- }
- AltOp& operator = (const AltOp& oth)
- {
- new(this) AltOp(oth);
- return *this;
- }
-#endif
-};
-
-class CatOp: public RegExp
-{
-
-private:
- RegExp *exp1, *exp2;
-
-public:
- static const char *type;
-
-public:
- CatOp(RegExp *e1, RegExp *e2)
- : exp1(e1)
- , exp2(e2)
- {
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- uint fixedLength();
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << exp1 << exp2;
- }
-
-#ifdef PEDANTIC
-private:
- CatOp(const CatOp& oth)
- : RegExp(oth)
- , exp1(oth.exp1)
- , exp2(oth.exp2)
- {
- }
- CatOp& operator = (const CatOp& oth)
- {
- new(this) CatOp(oth);
- return *this;
- }
-#endif
-};
-
-class CloseOp: public RegExp
-{
-
-private:
- RegExp *exp;
-
-public:
- static const char *type;
-
-public:
- CloseOp(RegExp *e)
- : exp(e)
- {
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << exp << "+";
- }
-
-#ifdef PEDANTIC
-private:
- CloseOp(const CloseOp& oth)
- : RegExp(oth)
- , exp(oth.exp)
- {
- }
- CloseOp& operator = (const CloseOp& oth)
- {
- new(this) CloseOp(oth);
- return *this;
- }
-#endif
-};
-
-class CloseVOp: public RegExp
-{
-
-private:
- RegExp *exp;
- int min;
- int max;
-
-public:
- static const char *type;
-
-public:
- CloseVOp(RegExp *e, int lb, int ub)
- : exp(e)
- , min(lb)
- , max(ub)
- {
- }
-
- const char *typeOf()
- {
- return type;
- }
-
- void split(CharSet&);
- void calcSize(Char*);
- void compile(Char*, Ins*);
- void display(std::ostream &o) const
- {
- o << exp << "+";
- }
-#ifdef PEDANTIC
-private:
- CloseVOp(const CloseVOp& oth)
- : RegExp(oth)
- , exp(oth.exp)
- , min(oth.min)
- , max(oth.max)
- {
- }
- CloseVOp& operator = (const CloseVOp& oth)
- {
- new(this) CloseVOp(oth);
- return *this;
- }
-#endif
-};
-
-extern void genCode(std::ostream&, RegExp*);
-extern void genCode(std::ostream&, uint, RegExp*);
-extern void genGetState(std::ostream&, uint&, uint);
-extern RegExp *mkDiff(RegExp*, RegExp*);
-extern RegExp *mkAlt(RegExp*, RegExp*);
-
-} // end namespace re2c
-
-#endif
+
+typedef struct extop
+{
+ char op;
+ int minsize;
+ int maxsize;
+}
+
+ExtOp;
+
+struct CharPtn
+{
+ uint card;
+ CharPtn *fix;
+ CharPtn *nxt;
+};
+
+typedef CharPtn *CharPtr;
+
+struct CharSet
+{
+ CharSet();
+ ~CharSet();
+
+ CharPtn *fix;
+ CharPtn *freeHead, **freeTail;
+ CharPtr *rep;
+ CharPtn *ptn;
+};
+
+class Range
+{
+
+public:
+ Range *next;
+ uint lb, ub; // [lb,ub)
+
+ static free_list vFreeList;
+
+public:
+ Range(uint l, uint u) : next(NULL), lb(l), ub(u)
+ {
+ vFreeList.insert(this);
+ }
+
+ Range(Range &r) : next(NULL), lb(r.lb), ub(r.ub)
+ {
+ vFreeList.insert(this);
+ }
+
+ ~Range()
+ {
+ vFreeList.erase(this);
+ }
+
+ friend std::ostream& operator<<(std::ostream&, const Range&);
+ friend std::ostream& operator<<(std::ostream&, const Range*);
+};
+
+inline std::ostream& operator<<(std::ostream &o, const Range *r)
+{
+ return r ? o << *r : o;
+}
+
+class RegExp
+{
+
+public:
+ uint size;
+
+ static free_list vFreeList;
+
+public:
+ RegExp() : size(0)
+ {
+ vFreeList.insert(this);
+ }
+
+ virtual ~RegExp()
+ {
+ vFreeList.erase(this);
+ }
+
+ virtual const char *typeOf() = 0;
+ RegExp *isA(const char *t)
+ {
+ return typeOf() == t ? this : NULL;
+ }
+
+ virtual void split(CharSet&) = 0;
+ virtual void calcSize(Char*) = 0;
+ virtual uint fixedLength();
+ virtual void compile(Char*, Ins*) = 0;
+ virtual void display(std::ostream&) const = 0;
+ friend std::ostream& operator<<(std::ostream&, const RegExp&);
+ friend std::ostream& operator<<(std::ostream&, const RegExp*);
+};
+
+inline std::ostream& operator<<(std::ostream &o, const RegExp &re)
+{
+ re.display(o);
+ return o;
+}
+
+inline std::ostream& operator<<(std::ostream &o, const RegExp *re)
+{
+ return o << *re;
+}
+
+class NullOp: public RegExp
+{
+
+public:
+ static const char *type;
+
+public:
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ uint fixedLength();
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << "_";
+ }
+};
+
+class MatchOp: public RegExp
+{
+
+public:
+ static const char *type;
+ Range *match;
+
+public:
+ MatchOp(Range *m) : match(m)
+ {
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ uint fixedLength();
+ void compile(Char*, Ins*);
+ void display(std::ostream&) const;
+
+#ifdef PEDANTIC
+private:
+ MatchOp(const MatchOp& oth)
+ : RegExp(oth)
+ , match(oth.match)
+ {
+ }
+
+ MatchOp& operator = (const MatchOp& oth)
+ {
+ new(this) MatchOp(oth);
+ return *this;
+ }
+#endif
+};
+
+class RuleOp: public RegExp
+{
+public:
+ static const char *type;
+
+private:
+ RegExp *exp;
+
+public:
+ RegExp *ctx;
+ Ins *ins;
+ uint accept;
+ Token *code;
+ uint line;
+
+public:
+ RuleOp(RegExp*, RegExp*, Token*, uint);
+
+ ~RuleOp()
+ {
+ delete code;
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << exp << "/" << ctx << ";";
+ }
+
+#ifdef PEDANTIC
+private:
+ RuleOp(const RuleOp& oth)
+ : RegExp(oth)
+ , exp(oth.exp)
+ , ctx(oth.ctx)
+ , ins(oth.ins)
+ , accept(oth.accept)
+ , code(oth.code)
+ , line(oth.line)
+ {
+ }
+ RuleOp& operator = (const RuleOp& oth)
+ {
+ new(this) RuleOp(oth);
+ return *this;
+ }
+#endif
+};
+
+class RuleLine: public line_number
+{
+public:
+
+ RuleLine(const RuleOp& _op)
+ : op(_op)
+ {
+ }
+
+ uint get_line() const
+ {
+ return op.code->line;
+ }
+
+ const RuleOp& op;
+};
+
+RegExp *mkAlt(RegExp*, RegExp*);
+
+class AltOp: public RegExp
+{
+
+private:
+ RegExp *exp1, *exp2;
+
+public:
+ static const char *type;
+
+public:
+ AltOp(RegExp *e1, RegExp *e2)
+ : exp1(e1)
+ , exp2(e2)
+ {
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ uint fixedLength();
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << exp1 << "|" << exp2;
+ }
+
+ friend RegExp *mkAlt(RegExp*, RegExp*);
+
+#ifdef PEDANTIC
+private:
+ AltOp(const AltOp& oth)
+ : RegExp(oth)
+ , exp1(oth.exp1)
+ , exp2(oth.exp2)
+ {
+ }
+ AltOp& operator = (const AltOp& oth)
+ {
+ new(this) AltOp(oth);
+ return *this;
+ }
+#endif
+};
+
+class CatOp: public RegExp
+{
+
+private:
+ RegExp *exp1, *exp2;
+
+public:
+ static const char *type;
+
+public:
+ CatOp(RegExp *e1, RegExp *e2)
+ : exp1(e1)
+ , exp2(e2)
+ {
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ uint fixedLength();
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << exp1 << exp2;
+ }
+
+#ifdef PEDANTIC
+private:
+ CatOp(const CatOp& oth)
+ : RegExp(oth)
+ , exp1(oth.exp1)
+ , exp2(oth.exp2)
+ {
+ }
+ CatOp& operator = (const CatOp& oth)
+ {
+ new(this) CatOp(oth);
+ return *this;
+ }
+#endif
+};
+
+class CloseOp: public RegExp
+{
+
+private:
+ RegExp *exp;
+
+public:
+ static const char *type;
+
+public:
+ CloseOp(RegExp *e)
+ : exp(e)
+ {
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << exp << "+";
+ }
+
+#ifdef PEDANTIC
+private:
+ CloseOp(const CloseOp& oth)
+ : RegExp(oth)
+ , exp(oth.exp)
+ {
+ }
+ CloseOp& operator = (const CloseOp& oth)
+ {
+ new(this) CloseOp(oth);
+ return *this;
+ }
+#endif
+};
+
+class CloseVOp: public RegExp
+{
+
+private:
+ RegExp *exp;
+ int min;
+ int max;
+
+public:
+ static const char *type;
+
+public:
+ CloseVOp(RegExp *e, int lb, int ub)
+ : exp(e)
+ , min(lb)
+ , max(ub)
+ {
+ }
+
+ const char *typeOf()
+ {
+ return type;
+ }
+
+ void split(CharSet&);
+ void calcSize(Char*);
+ void compile(Char*, Ins*);
+ void display(std::ostream &o) const
+ {
+ o << exp << "+";
+ }
+#ifdef PEDANTIC
+private:
+ CloseVOp(const CloseVOp& oth)
+ : RegExp(oth)
+ , exp(oth.exp)
+ , min(oth.min)
+ , max(oth.max)
+ {
+ }
+ CloseVOp& operator = (const CloseVOp& oth)
+ {
+ new(this) CloseVOp(oth);
+ return *this;
+ }
+#endif
+};
+
+extern void genCode(std::ostream&, RegExp*);
+extern void genCode(std::ostream&, uint, RegExp*);
+extern void genGetState(std::ostream&, uint&, uint);
+extern RegExp *mkDiff(RegExp*, RegExp*);
+extern RegExp *mkAlt(RegExp*, RegExp*);
+
+} // end namespace re2c
+
+#endif
diff --git a/tools/re2c/re2c.1 b/tools/re2c/re2c.1
index 05f49b2f0..fe12c0179 100644
--- a/tools/re2c/re2c.1
+++ b/tools/re2c/re2c.1
@@ -1,7 +1,7 @@
./"
-./" $Id: re2c.1.in 523 2006-05-25 13:32:09Z helly $
+./" $Id: re2c.1.in 663 2007-04-01 11:22:15Z helly $
./"
-.TH RE2C 1 "22 April 2005" "Version 0.10.5"
+.TH RE2C 1 "22 April 2005" "Version 0.12.3"
.ds re \fBre2c\fP
.ds le \fBlex\fP
.ds rx regular expression
@@ -10,7 +10,7 @@
re2c \- convert regular expressions to C/C++
.SH SYNOPSIS
-\*(re [\fB-bdefghisvVw1\fP] [\fB-o output\fP] file\fP
+\*(re [\fB-bdefghisuvVw1\fP] [\fB-o output\fP] file\fP
.SH DESCRIPTION
\*(re is a preprocessor that generates C-based recognizers from regular
@@ -26,61 +26,51 @@ For example, given the following code
.in +3
.nf
-#define NULL ((char*) 0)
char *scan(char *p)
{
-#define YYCTYPE char
-#define YYCURSOR p
-#define YYLIMIT p
-#define YYFILL(n)
/*!re2c
- [0-9]+ {return YYCURSOR;}
- [\\000-\\377] {return NULL;}
+ re2c:define:YYCTYPE = "unsigned char";
+ re2c:define:YYCURSOR = p;
+ re2c:yyfill:enable = 0;
+ re2c:yych:conversion = 1;
+ re2c:indent:top = 1;
+ [0-9]+ {return p;}
+ [\000-\377] {return (char*)0;}
*/
}
.fi
.in -3
-\*(re will generate
+\*(re -is will generate
.in +3
.nf
/* Generated by re2c on Sat Apr 16 11:40:58 1994 */
-#line 1 "simple.re"
-#define NULL ((char*) 0)
char *scan(char *p)
{
-#define YYCTYPE char
-#define YYCURSOR p
-#define YYLIMIT p
-#define YYFILL(n)
-{
- YYCTYPE yych;
- unsigned int yyaccept;
- goto yy0;
-yy1: ++YYCURSOR;
-yy0:
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if(yych <= '/') goto yy4;
- if(yych >= ':') goto yy4;
-yy2: yych = *++YYCURSOR;
+ {
+ unsigned char yych;
+
+ yych = (unsigned char)*p;
+ if(yych <= '/') goto yy4;
+ if(yych >= ':') goto yy4;
+ ++p;
+ yych = (unsigned char)*p;
goto yy7;
yy3:
-#line 9
- {return YYCURSOR;}
-yy4: yych = *++YYCURSOR;
-yy5:
-#line 10
- {return NULL;}
-yy6: ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
-yy7: if(yych <= '/') goto yy3;
- if(yych <= '9') goto yy6;
+ {return p;}
+yy4:
+ ++p;
+ yych = (unsigned char)*p;
+ {return char*)0;}
+yy6:
+ ++p;
+ yych = (unsigned char)*p;
+yy7:
+ if(yych <= '/') goto yy3;
+ if(yych <= '9') goto yy6;
goto yy3;
-}
-#line 11
+ }
}
.fi
@@ -123,7 +113,7 @@ Generate a scanner with support for storable state.
For details see below at \fBSCANNER WITH STORABLE STATES\fP.
.TP
\fB-g\fP
-Generate a scanner that utilizes GCC's computed goto feature. That is re2c
+Generate a scanner that utilizes GCC's computed goto feature. That is \*(re
generates jump tables whenever a decision is of a certain complexity (e.g. a
lot of if conditions are otherwise necessary). This is only useable with GCC
and produces output that cannot be compiled with any other compiler. Note that
@@ -132,8 +122,8 @@ inplace configuration "cgoto:threshold".
.TP
\fB-i\fP
Do not output #line information. This is usefull when you want use a CMS tool
-with the re2c output which you might want if you do not require your users to
-have re2c themselves when building from your source.
+with the \*(re output which you might want if you do not require your users to
+have \*(re themselves when building from your source.
\fB-o output\fP
Specify the output file.
.TP
@@ -141,6 +131,12 @@ Specify the output file.
Generate nested \fCif\fPs for some \fCswitch\fPes. Many compilers need this
assist to generate better code.
.TP
+\fB-u\fP
+Generate a parser that supports Unicode chars (UTF-32). This means the
+generated code can deal with any valid Unicode character up to 0x10FFFF. When
+UTF-8 or UTF-16 needs to be supported you need to convert the incoming stream
+to UTF-32 upon input yourself.
+.TP
\fB-v\fP
Show version information.
.TP
@@ -153,11 +149,16 @@ cannot be used together with \fB-e\fP switch.
.TP
\fB-1\fP
Force single pass generation, this cannot be combined with -f and disables
-YYMAXFILL generation prior to last re2c block.
+YYMAXFILL generation prior to last \*(re block.
+.TP
+\fb--no-generation-date\fP
+Suppress date output in the generated output so that it only shows the re2c
+version.
.SH "INTERFACE CODE"
Unlike other scanner generators, \*(re does not generate complete scanners:
the user must supply some interface code.
-In particular, the user must define the following macros:
+In particular, the user must define the following macros or use the
+corresponding inplace configurations:
.TP
\fCYYCTYPE\fP
Type used to hold an input symbol.
@@ -187,26 +188,27 @@ The generated code saves trailing context backtracking information in \fCYYCTXMA
The user only needs to define this macro if a scanner specification uses trailing
context in one or more of its regular expressions.
.TP
-\fCYYFILL(\fP\fIn\fP\fC)\fP
+\fCYYFILL\fP(\fIn\fP\fC\fP)
The generated code "calls" \fCYYFILL\fP(n) when the buffer needs
(re)filling: at least \fIn\fP additional characters should
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 once to insert
-a \fCYYMAXFILL\fP definition that is set to the maximum length value. If -1
-switch is used then YYMAXFILL can be triggered once after the last \fC/*!re2c */\fP
+a \fCYYMAXFILL\fP(n) definition that is set to the maximum length value. If -1
+switch is used then \fCYYMAXFILL\fP can be triggered only once after the
+last \fC/*!re2c */\fP
block.
.TP
-\fCYYGETSTATE()\fP
+\fCYYGETSTATE\fP()
The user only needs to define this macro if the \fB-f\fP flag was specified.
-In that case, the generated code "calls" \fCYYGETSTATE\fP at the very beginning
-of the scanner in order to obtain the saved state. YYGETSTATE must return a signed
+In that case, the generated code "calls" \fCYYGETSTATE\fP() at the very beginning
+of the scanner in order to obtain the saved state. \fCYYGETSTATE\fP() must return a signed
integer. The value must be either -1, indicating that the scanner is entered for the
-first time, or a value previously saved by \fCYYSETSTATE\fP. In the second case, the
+first time, or a value previously saved by \fCYYSETSTATE\fP(s). In the second case, the
scanner will resume operations right after where the last \fCYYFILL\fP(n) was called.
.TP
-\fCYYSETSTATE(\fP\fIn\fP\fC)\fP
+\fCYYSETSTATE(\fP\fIs\fP\fC)\fP
The user only needs to define this macro if the \fB-f\fP flag was specified.
In that case, the generated code "calls" \fCYYSETSTATE\fP just before calling
\fCYYFILL\fP(n). The parameter to \fCYYSETSTATE\fP is a signed integer that uniquely
@@ -214,7 +216,9 @@ identifies the specific instance of \fCYYFILL\fP(n) that is about to be called.
Should the user wish to save the state of the scanner and have \fCYYFILL\fP(n) return
to the caller, all he has to do is store that unique identifer in a variable.
Later, when the scannered is called again, it will call \fCYYGETSTATE()\fP and
-resume execution right where it left off.
+resume execution right where it left off. The generated code will contain
+both \fCYYSETSTATE\fP(s) and \fCYYGETSTATE\fP even if \fCYYFILL\fP(n) is being
+disabled.
.TP
\fCYYDEBUG(\fP\fIstate\fP,\fIcurrent\fC)\fP
This is only needed if the \fB-d\fP flag was specified. It allows to easily debug
@@ -227,11 +231,11 @@ input at the current cursor.
This will be automatically defined by \fC/*!max:re2c */\fP blocks as explained above.
.SH "SCANNER WITH STORABLE STATES"
-When the \fB-f\fP flag is specified, re2c generates a scanner that
+When the \fB-f\fP flag is specified, \*(re generates a scanner that
can store its current state, return to the caller, and later resume
operations exactly where it left off.
-The default operation of re2c is a "pull" model, where the scanner asks
+The default operation of \*(re is a "pull" model, where the scanner asks
for extra input whenever it needs it. However, this mode of operation
assumes that the scanner is the "owner" the parsing loop, and that may
not always be convenient.
@@ -246,9 +250,9 @@ chunk by chunk. When the scanner runs out of data to consume, it just stores
its state, and return to the caller. When more input data is fed to the scanner,
it resumes operations exactly where it left off.
-When using the -f option re2c does not accept stdin because it has to do the
+When using the -f option \*(re does not accept stdin because it has to do the
full generation process twice which means it has to read the input twice. That
-means re2c would fail in case it cannot open the input twice or reading the
+means \*(re would fail in case it cannot open the input twice or reading the
input for the first time influences the second read attempt.
Changes needed compared to the "pull" model.
@@ -286,7 +290,7 @@ Please see examples/push.re for push-model scanner. The generated code can be
tweaked using inplace configurations "\fBstate:abort\fP" and "\fBstate:nextlabel\fP".
.SH "SCANNER SPECIFICATIONS"
-Each scanner specification consists of a set of \fIrules\fP, \fIname
+Each scanner specification consists of a set of \fIrules\fP, \fInamed
definitions\fP and \fIconfigurations\fP.
.LP
\fIRules\fP consist of a regular expression along with a block of C/C++ code that
@@ -302,12 +306,15 @@ Named definitions are of the form:
\fIname\fP \fC=\fP \fIregular expression\fP\fC;\fP
.RE
.LP
-Configurations look like name definitions whose names start
+Configurations look like named definitions whose names start
with "\fBre2c:\fP":
.P
.RS
\fCre2c:\fP\fIname\fP \fC=\fP \fIvalue\fP\fC;\fP
.RE
+.RS
+\fCre2c:\fP\fIname\fP \fC=\fP \fB"\fP\fIvalue\fP\fB"\fP\fC;\fP
+.RE
.SH "SUMMARY OF RE2C REGULAR EXPRESSIONS"
.TP
@@ -345,7 +352,7 @@ one or more \fIr\fP's
zero or one \fIr\fP's (that is, "an optional \fIr\fP")
.TP
name
-the expansion of the "name" definition (see above)
+the expansion of the "named definition" (see above)
.TP
\fC(\fP\fIr\fP\fC)\fP
an \fIr\fP; parentheses are used to override precedence
@@ -385,12 +392,10 @@ and a hexadecimal character is defined by backslash, a lower cased '\fBx\fP'
and its two hexadecimal digits or a backslash, an upper cased \fBX\fP and its
four hexadecimal digits.
.LP
-re2c
-further more supports the c/c++ unicode notation. That is a backslash followed
+\*(re further more supports the c/c++ unicode notation. That is a backslash followed
by either a lowercased \fBu\fP and its four hexadecimal digits or an uppercased
-\fBU\fP and its eight hexadecimal digits. However using the U notation it is
-not possible to support characters greater \fB\\U0000FFFF\fP due to an internal
-limitation of re2c.
+\fBU\fP and its eight hexadecimal digits. However only in \fB-u\fP mode the
+generated code can deal with any valid Unicode character up to 0x10FFFF.
.LP
Since characters greater \fB\\X00FF\fP are not allowed in non unicode mode, the
only portable "\fBany\fP" rules are \fB(.|"\\n")\fP and \fB[^]\fP.
@@ -401,7 +406,7 @@ Those grouped together have equal precedence.
.SH "INPLACE CONFIGURATION"
.LP
-It is possible to configure code generation inside re2c blocks. The following
+It is possible to configure code generation inside \*(re blocks. The following
lists the available configurations:
.TP
\fIre2c:indent:top\fP \fB=\fP 0 \fB;\fP
@@ -423,6 +428,12 @@ Set this to zero to suppress generation of YYFILL(n). When using this be sure
to verify that the generated scanner does not read behind input. Allowing
this behavior might introduce sever security issues to you programs.
.TP
+\fIre2c:yyfill:parameter\fP \fB=\fP 1 \fB;\fP
+Allows to suppress parameter passing to \fBYYFILL\fP calls. If set to zero
+then no parameter is passed to \fBYYFILL\fP. If set to a non zero value then
+\fBYYFILL\fP usage will be followed by the number of requested characters in
+braces.
+.TP
\fIre2c:startlabel\fP \fB=\fP 0 \fB;\fP
If set to a non zero integer then the start label of the next scanner blocks
will be generated even if not used by the scanner itself. Otherwise the normal
@@ -431,6 +442,10 @@ value then a label with that text will be generated regardless of whether the
normal start label is being used or not. This setting is being reset to \fB0\fP
after a start label has been generated.
.TP
+\fIre2c:labelprefix\fP \fB=\fP yy \fB;\fP
+Allows to change the prefix of numbered labels. The default is \fByy\fP and
+can be set any string that is a valid label.
+.TP
\fIre2c:state:abort\fP \fB=\fP 0 \fB;\fP
When not zero and switch -f is active then the \fCYYGETSTATE\fP block will
contain a default case that aborts and a -1 case is used for initialization.
@@ -448,11 +463,77 @@ When -g is active this value specifies the complexity threshold that triggers
generation of jump tables rather than using nested if's and decision bitfields.
The threshold is compared against a calculated estimation of if-s needed where
every used bitmap divides the threshold by 2.
+.TP
+\fIre2c:yych:conversion\fP \fB=\fP 0 \fB;\fP
+When the input uses signed characters and \fB-s\fP or \fB-b\fP switches are
+in effect re2c allows to automatically convert to the unsigned character type
+that is then necessary for its internal single character. When this setting
+is zero or an empty string the conversion is disabled. Using a non zero number
+the conversion is taken from \fBYYCTYPE\fP. If that is given by an inplace
+configuration that value is being used. Otherwise it will be \fB(YYCTYPE)\fP
+and changes to that configuration are no longer possible. When this setting is
+a string the braces must be specified. Now assuming your input is a \fBchar*\fP
+buffer and you are using above mentioned switches you can set \fBYYCTYPE\fP to
+\fBunsigned char\fP and this setting to either \fB1\fP or \fB"(unsigned char)"\fP.
+.TP
+\fIre2c:define:YYCTXMARKER\fP \fB=\fP YYCTXMARKER \fB;\fP
+Allows to overwrite the define YYCTXMARKER and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYCTYPE\fP \fB=\fP YYCTYPE \fB;\fP
+Allows to overwrite the define YYCTYPE and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYCURSOR\fP \fB=\fP YYCURSOR \fB;\fP
+Allows to overwrite the define YYCURSOR and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYDEBUG\fP \fB=\fP YYDEBUG \fB;\fP
+Allows to overwrite the define YYDEBUG and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYFILL\fP \fB=\fP YYFILL \fB;\fP
+Allows to overwrite the define YYFILL and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYGETSTATE\fP \fB=\fP YYGETSTATE \fB;\fP
+Allows to overwrite the define YYGETSTATE and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYLIMIT\fP \fB=\fP YYLIMIT \fB;\fP
+Allows to overwrite the define YYLIMIT and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYMARKER\fP \fB=\fP YYMARKER \fB;\fP
+Allows to overwrite the define YYMARKER and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:define:YYSETSTATE\fP \fB=\fP YYSETSTATE \fB;\fP
+Allows to overwrite the define YYSETSTATE and thus avoiding it by setting the
+value to the actual code needed.
+.TP
+\fIre2c:label:yyFillLabel\fP \fB=\fP yyFillLabel \fB;\fP
+Allows to overwrite the name of the label yyFillLabel.
+.TP
+\fIre2c:label:yyNext\fP \fB=\fP yyNext \fB;\fP
+Allows to overwrite the name of the label yyNext.
+.TP
+\fIre2c:variable:yyaccept\fP \fB=\fP yyaccept \fB;\fP
+Allows to overwrite the name of the variable yyaccept.
+.TP
+\fIre2c:variable:yybm\fP \fB=\fP yybm \fB;\fP
+Allows to overwrite the name of the variable yybm.
+.TP
+\fIre2c:variable:yych\fP \fB=\fP yych \fB;\fP
+Allows to overwrite the name of the variable yych.
+.TP
+\fIre2c:variable:yytarget\fP \fB=\fP yytarget \fB;\fP
+Allows to overwrite the name of the variable yytarget.
.SH "UNDERSTANDING RE2C"
.LP
-The subdirectory lessons of the re2c distribution contains a few step by step
-lessons to get you started with re2c. All examples in the lessons subdirectory
+The subdirectory lessons of the \*(re distribution contains a few step by step
+lessons to get you started with \*(re. All examples in the lessons subdirectory
can be compiled and actually work.
.SH FEATURES
@@ -487,10 +568,10 @@ The \*(re internal algorithms need documentation.
.LP
flex(1), lex(1).
.P
-More information on \fBre2c\fP can be found here:
+More information on \*(re can be found here:
.PD 0
.P
-.B http://sourceforge.net/projects/re2c/
+.B http://re2c.org/
.PD 1
.SH AUTHORS
@@ -511,6 +592,6 @@ Emmanuel Mogenet added storable state
.PD 1
.SH VERSION INFORMATION
-This manpage describes \fBre2c\fP, version 0.10.5.
+This manpage describes \*(re, version 0.12.3.
.fi
diff --git a/tools/re2c/scanner.cc b/tools/re2c/scanner.cc
index ee26a8c78..1a6cbbe7c 100644
--- a/tools/re2c/scanner.cc
+++ b/tools/re2c/scanner.cc
@@ -1,6 +1,5 @@
-/* Generated by re2c 0.12.3 on Tue Jan 22 23:04:51 2008 */
-#line 1 "scanner.re"
-/* $Id:$ */
+/* Generated by re2c 0.12.3 on Fri Jan 25 21:09:48 2008 */
+/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */
#include
#include
#include
@@ -76,7 +75,6 @@ char *Scanner::fill(char *cursor)
return cursor;
}
-#line 95 "scanner.re"
int Scanner::echo()
@@ -92,45 +90,36 @@ int Scanner::echo()
tok = cursor;
echo:
-
-#line 97 "scanner.cc"
{
- YYCTYPE yych;
- unsigned int yyaccept = 0;
- if((YYLIMIT - YYCURSOR) < 16) YYFILL(16);
-(16);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x00: goto yy7;
- case 0x0A: goto yy5;
- case '*': goto yy4;
- case '/': goto yy2;
- default: goto yy9;
- }
-yy2:
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case '*': goto yy16;
- default: goto yy3;
- }
-yy3:
-#line 184 "scanner.re"
{
+ YYCTYPE yych;
+ unsigned int yyaccept = 0;
+
+ if((YYLIMIT - YYCURSOR) < 16) YYFILL(16);
+ yych = *YYCURSOR;
+ if(yych <= ')') {
+ if(yych <= 0x00) goto yy7;
+ if(yych == 0x0A) goto yy5;
+ goto yy9;
+ } else {
+ if(yych <= '*') goto yy4;
+ if(yych != '/') goto yy9;
+ }
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == '*') goto yy16;
+yy3:
+ {
goto echo;
}
-#line 124 "scanner.cc"
yy4:
- yych = *++YYCURSOR;
- switch(yych) {
- case '/': goto yy10;
- default: goto yy3;
- }
+ yych = *++YYCURSOR;
+ if(yych == '/') goto yy10;
+ goto yy3;
yy5:
- ++YYCURSOR;
-#line 167 "scanner.re"
- {
+ ++YYCURSOR;
+ {
if (ignore_eoc) {
ignore_cnt++;
} else {
@@ -139,11 +128,9 @@ yy5:
tok = pos = cursor; cline++;
goto echo;
}
-#line 143 "scanner.cc"
yy7:
- ++YYCURSOR;
-#line 176 "scanner.re"
- {
+ ++YYCURSOR;
+ {
if (!ignore_eoc) {
out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok) - 1); // -1 so we don't write out the \0
}
@@ -151,21 +138,16 @@ yy7:
RETURN(0);
}
}
-#line 155 "scanner.cc"
yy9:
- yych = *++YYCURSOR;
- goto yy3;
+ yych = *++YYCURSOR;
+ goto yy3;
yy10:
- yyaccept = 1;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy14;
- case 0x0D: goto yy12;
- default: goto yy11;
- }
+ yyaccept = 1;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == 0x0A) goto yy14;
+ if(yych == 0x0D) goto yy12;
yy11:
-#line 154 "scanner.re"
- {
+ {
if (ignore_eoc) {
if (ignore_cnt) {
out << "\n" << sourceFileInfo;
@@ -178,23 +160,19 @@ yy11:
tok = pos = cursor;
goto echo;
}
-#line 182 "scanner.cc"
yy12:
- yych = *++YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy14;
- default: goto yy13;
- }
+ yych = *++YYCURSOR;
+ if(yych == 0x0A) goto yy14;
yy13:
- YYCURSOR = YYMARKER;
- switch(yyaccept) {
- case 0: goto yy3;
- case 1: goto yy11;
- }
+ YYCURSOR = YYMARKER;
+ if(yyaccept <= 0) {
+ goto yy3;
+ } else {
+ goto yy11;
+ }
yy14:
- ++YYCURSOR;
-#line 140 "scanner.re"
- {
+ ++YYCURSOR;
+ {
cline++;
if (ignore_eoc) {
if (ignore_cnt) {
@@ -208,62 +186,38 @@ yy14:
tok = pos = cursor;
goto echo;
}
-#line 212 "scanner.cc"
yy16:
- yych = *++YYCURSOR;
- switch(yych) {
- case '!': goto yy17;
- default: goto yy13;
- }
-yy17:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'g': goto yy19;
- case 'i': goto yy18;
- case 'm': goto yy20;
- case 'r': goto yy21;
- default: goto yy13;
- }
+ yych = *++YYCURSOR;
+ if(yych != '!') goto yy13;
+ yych = *++YYCURSOR;
+ switch(yych) {
+ case 'g': goto yy19;
+ case 'i': goto yy18;
+ case 'm': goto yy20;
+ case 'r': goto yy21;
+ default: goto yy13;
+ }
yy18:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'g': goto yy47;
- default: goto yy13;
- }
+ yych = *++YYCURSOR;
+ if(yych == 'g') goto yy47;
+ goto yy13;
yy19:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy34;
- default: goto yy13;
- }
+ yych = *++YYCURSOR;
+ if(yych == 'e') goto yy34;
+ goto yy13;
yy20:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'a': goto yy26;
- default: goto yy13;
- }
+ yych = *++YYCURSOR;
+ if(yych == 'a') goto yy26;
+ goto yy13;
yy21:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy22;
- default: goto yy13;
- }
-yy22:
- yych = *++YYCURSOR;
- switch(yych) {
- case '2': goto yy23;
- default: goto yy13;
- }
-yy23:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'c': goto yy24;
- default: goto yy13;
- }
-yy24:
- ++YYCURSOR;
-#line 111 "scanner.re"
- {
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != '2') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'c') goto yy13;
+ ++YYCURSOR;
+ {
if (bUsedYYMaxFill && bSinglePass) {
fatal("found scanner block after YYMAXFILL declaration");
}
@@ -271,47 +225,21 @@ yy24:
tok = cursor;
RETURN(1);
}
-#line 275 "scanner.cc"
yy26:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'x': goto yy27;
- default: goto yy13;
- }
-yy27:
- yych = *++YYCURSOR;
- switch(yych) {
- case ':': goto yy28;
- default: goto yy13;
- }
-yy28:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'r': goto yy29;
- default: goto yy13;
- }
-yy29:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy30;
- default: goto yy13;
- }
-yy30:
- yych = *++YYCURSOR;
- switch(yych) {
- case '2': goto yy31;
- default: goto yy13;
- }
-yy31:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'c': goto yy32;
- default: goto yy13;
- }
-yy32:
- ++YYCURSOR;
-#line 119 "scanner.re"
- {
+ yych = *++YYCURSOR;
+ if(yych != 'x') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != ':') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'r') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != '2') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'c') goto yy13;
+ ++YYCURSOR;
+ {
if (bUsedYYMaxFill) {
fatal("cannot generate YYMAXFILL twice");
}
@@ -321,148 +249,63 @@ yy32:
bUsedYYMaxFill = true;
goto echo;
}
-#line 325 "scanner.cc"
yy34:
- yych = *++YYCURSOR;
- switch(yych) {
- case 't': goto yy35;
- default: goto yy13;
- }
-yy35:
- yych = *++YYCURSOR;
- switch(yych) {
- case 's': goto yy36;
- default: goto yy13;
- }
-yy36:
- yych = *++YYCURSOR;
- switch(yych) {
- case 't': goto yy37;
- default: goto yy13;
- }
-yy37:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'a': goto yy38;
- default: goto yy13;
- }
-yy38:
- yych = *++YYCURSOR;
- switch(yych) {
- case 't': goto yy39;
- default: goto yy13;
- }
-yy39:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy40;
- default: goto yy13;
- }
-yy40:
- yych = *++YYCURSOR;
- switch(yych) {
- case ':': goto yy41;
- default: goto yy13;
- }
-yy41:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'r': goto yy42;
- default: goto yy13;
- }
-yy42:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy43;
- default: goto yy13;
- }
-yy43:
- yych = *++YYCURSOR;
- switch(yych) {
- case '2': goto yy44;
- default: goto yy13;
- }
-yy44:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'c': goto yy45;
- default: goto yy13;
- }
-yy45:
- ++YYCURSOR;
-#line 129 "scanner.re"
- {
+ yych = *++YYCURSOR;
+ if(yych != 't') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 's') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 't') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'a') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 't') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != ':') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'r') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != '2') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'c') goto yy13;
+ ++YYCURSOR;
+ {
tok = pos = cursor;
genGetState(out, topIndent, 0);
ignore_eoc = true;
goto echo;
}
-#line 401 "scanner.cc"
yy47:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'n': goto yy48;
- default: goto yy13;
- }
-yy48:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'o': goto yy49;
- default: goto yy13;
- }
-yy49:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'r': goto yy50;
- default: goto yy13;
- }
-yy50:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy51;
- default: goto yy13;
- }
-yy51:
- yych = *++YYCURSOR;
- switch(yych) {
- case ':': goto yy52;
- default: goto yy13;
- }
-yy52:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'r': goto yy53;
- default: goto yy13;
- }
-yy53:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'e': goto yy54;
- default: goto yy13;
- }
-yy54:
- yych = *++YYCURSOR;
- switch(yych) {
- case '2': goto yy55;
- default: goto yy13;
- }
-yy55:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'c': goto yy56;
- default: goto yy13;
- }
-yy56:
- ++YYCURSOR;
-#line 135 "scanner.re"
- {
+ yych = *++YYCURSOR;
+ if(yych != 'n') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'o') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'r') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != ':') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'r') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'e') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != '2') goto yy13;
+ yych = *++YYCURSOR;
+ if(yych != 'c') goto yy13;
+ ++YYCURSOR;
+ {
tok = pos = cursor;
ignore_eoc = true;
goto echo;
}
-#line 464 "scanner.cc"
+ }
}
-#line 187 "scanner.re"
}
@@ -484,1154 +327,951 @@ scan:
{
goto value;
}
-
-#line 489 "scanner.cc"
{
- YYCTYPE yych;
- unsigned int yyaccept = 0;
- if((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
-(5);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case ' ': goto yy79;
- case 0x0A: goto yy81;
- case 0x0D: goto yy83;
- case '"': goto yy66;
- case '\'': goto yy68;
- case '(':
- case ')':
- case ';':
- case '=':
- case '\\':
- case '|': goto yy72;
- case '*': goto yy64;
- case '+':
- case '?': goto yy73;
- case '.': goto yy77;
- case '/': goto yy62;
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- case '_':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z': goto yy76;
- case '[': goto yy70;
- case 'r': goto yy74;
- case '{': goto yy60;
- default: goto yy85;
- }
+ static const unsigned char yybm[] = {
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 116, 0, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 116, 112, 48, 112, 112, 112, 112, 80,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 112, 112, 112, 112, 112, 112,
+ 112, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 112, 0, 96, 112, 120,
+ 112, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 120, 120, 120, 120, 120,
+ 120, 120, 120, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112,
+ };
+
+ {
+ YYCTYPE yych;
+ unsigned int yyaccept = 0;
+ if((YYLIMIT - YYCURSOR) < 5) YYFILL(5);
+ yych = *YYCURSOR;
+ if(yych <= ':') {
+ if(yych <= '"') {
+ if(yych <= 0x0C) {
+ if(yych <= 0x08) goto yy85;
+ if(yych <= 0x09) goto yy79;
+ if(yych <= 0x0A) goto yy81;
+ goto yy85;
+ } else {
+ if(yych <= 0x1F) {
+ if(yych <= 0x0D) goto yy83;
+ goto yy85;
+ } else {
+ if(yych <= ' ') goto yy79;
+ if(yych <= '!') goto yy85;
+ goto yy66;
+ }
+ }
+ } else {
+ if(yych <= '*') {
+ if(yych <= '&') goto yy85;
+ if(yych <= '\'') goto yy68;
+ if(yych <= ')') goto yy72;
+ goto yy64;
+ } else {
+ if(yych <= '-') {
+ if(yych <= '+') goto yy73;
+ goto yy85;
+ } else {
+ if(yych <= '.') goto yy77;
+ if(yych <= '/') goto yy62;
+ goto yy85;
+ }
+ }
+ }
+ } else {
+ if(yych <= '\\') {
+ if(yych <= '>') {
+ if(yych == '<') goto yy85;
+ if(yych <= '=') goto yy72;
+ goto yy85;
+ } else {
+ if(yych <= '@') {
+ if(yych <= '?') goto yy73;
+ goto yy85;
+ } else {
+ if(yych <= 'Z') goto yy76;
+ if(yych <= '[') goto yy70;
+ goto yy72;
+ }
+ }
+ } else {
+ if(yych <= 'q') {
+ if(yych == '_') goto yy76;
+ if(yych <= '`') goto yy85;
+ goto yy76;
+ } else {
+ if(yych <= 'z') {
+ if(yych <= 'r') goto yy74;
+ goto yy76;
+ } else {
+ if(yych <= '{') goto yy60;
+ if(yych <= '|') goto yy72;
+ goto yy85;
+ }
+ }
+ }
+ }
yy60:
- yyaccept = 0;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case ',': goto yy126;
- case '0': goto yy123;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy124;
- default: goto yy61;
- }
+ yyaccept = 0;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych <= '/') {
+ if(yych == ',') goto yy126;
+ } else {
+ if(yych <= '0') goto yy123;
+ if(yych <= '9') goto yy124;
+ }
yy61:
-#line 209 "scanner.re"
- { depth = 1;
+ { depth = 1;
goto code;
}
-#line 593 "scanner.cc"
yy62:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '*': goto yy121;
- default: goto yy63;
- }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '*') goto yy121;
yy63:
-#line 239 "scanner.re"
- { RETURN(*tok); }
-#line 603 "scanner.cc"
+ { RETURN(*tok); }
yy64:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '/': goto yy119;
- default: goto yy65;
- }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '/') goto yy119;
yy65:
-#line 241 "scanner.re"
- { yylval.op = *tok;
+ { yylval.op = *tok;
RETURN(CLOSE); }
-#line 614 "scanner.cc"
yy66:
- yyaccept = 1;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy67;
- default: goto yy115;
- }
+ yyaccept = 1;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych != 0x0A) goto yy115;
yy67:
-#line 226 "scanner.re"
- { fatal("unterminated string constant (missing \")"); }
-#line 625 "scanner.cc"
+ { fatal("unterminated string constant (missing \")"); }
yy68:
- yyaccept = 2;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy69;
- default: goto yy110;
- }
+ yyaccept = 2;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych != 0x0A) goto yy110;
yy69:
-#line 227 "scanner.re"
- { fatal("unterminated string constant (missing ')"); }
-#line 636 "scanner.cc"
+ { fatal("unterminated string constant (missing ')"); }
yy70:
- yyaccept = 3;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy71;
- case '^': goto yy101;
- default: goto yy100;
- }
+ yyaccept = 3;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == 0x0A) goto yy71;
+ if(yych == '^') goto yy101;
+ goto yy100;
yy71:
-#line 237 "scanner.re"
- { fatal("unterminated range (missing ])"); }
-#line 648 "scanner.cc"
+ { fatal("unterminated range (missing ])"); }
yy72:
- yych = *++YYCURSOR;
- goto yy63;
+ yych = *++YYCURSOR;
+ goto yy63;
yy73:
- yych = *++YYCURSOR;
- goto yy65;
+ yych = *++YYCURSOR;
+ goto yy65;
yy74:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case 'e': goto yy91;
- default: goto yy90;
- }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == 'e') goto yy91;
+ goto yy90;
yy75:
-#line 268 "scanner.re"
- { cur = cursor;
+ { cur = cursor;
yylval.symbol = Symbol::find(token());
return ID; }
-#line 666 "scanner.cc"
yy76:
- yych = *++YYCURSOR;
- goto yy90;
+ yych = *++YYCURSOR;
+ goto yy90;
yy77:
- ++YYCURSOR;
-#line 272 "scanner.re"
- { cur = cursor;
+ ++YYCURSOR;
+ { cur = cursor;
yylval.regexp = mkDot();
return RANGE;
}
-#line 677 "scanner.cc"
yy79:
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy88;
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy88;
yy80:
-#line 277 "scanner.re"
- { goto scan; }
-#line 685 "scanner.cc"
+ { goto scan; }
yy81:
- ++YYCURSOR;
+ ++YYCURSOR;
yy82:
-#line 279 "scanner.re"
- { if(cursor == eof) RETURN(0);
+ { if(cursor == eof) RETURN(0);
pos = cursor; cline++;
goto scan;
}
-#line 694 "scanner.cc"
yy83:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case 0x0A: goto yy86;
- default: goto yy84;
- }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == 0x0A) goto yy86;
yy84:
-#line 284 "scanner.re"
- { std::ostringstream msg;
+ { std::ostringstream msg;
msg << "unexpected character: ";
prtChOrHex(msg, *tok);
fatal(msg.str().c_str());
goto scan;
}
-#line 709 "scanner.cc"
yy85:
- yych = *++YYCURSOR;
- goto yy84;
+ yych = *++YYCURSOR;
+ goto yy84;
yy86:
- yych = *++YYCURSOR;
- goto yy82;
+ yych = *++YYCURSOR;
+ goto yy82;
yy87:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy88:
- switch(yych) {
- case 0x09:
- case ' ': goto yy87;
- default: goto yy80;
- }
+ if(yybm[0+yych] & 4) {
+ goto yy87;
+ }
+ goto yy80;
yy89:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy90:
- switch(yych) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- case '_':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z': goto yy89;
- default: goto yy75;
- }
+ if(yybm[0+yych] & 8) {
+ goto yy89;
+ }
+ goto yy75;
yy91:
- yych = *++YYCURSOR;
- switch(yych) {
- case '2': goto yy92;
- default: goto yy90;
- }
-yy92:
- yych = *++YYCURSOR;
- switch(yych) {
- case 'c': goto yy93;
- default: goto yy90;
- }
-yy93:
- yyaccept = 4;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case ':': goto yy94;
- default: goto yy90;
- }
+ yych = *++YYCURSOR;
+ if(yych != '2') goto yy90;
+ yych = *++YYCURSOR;
+ if(yych != 'c') goto yy90;
+ yyaccept = 4;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych != ':') goto yy90;
yy94:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- case '_':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z': goto yy96;
- default: goto yy95;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= '^') {
+ if(yych <= '@') goto yy95;
+ if(yych <= 'Z') goto yy96;
+ } else {
+ if(yych == '`') goto yy95;
+ if(yych <= 'z') goto yy96;
+ }
yy95:
- YYCURSOR = YYMARKER;
- switch(yyaccept) {
- case 0: goto yy61;
- case 1: goto yy67;
- case 2: goto yy69;
- case 3: goto yy71;
- case 4: goto yy75;
- case 5: goto yy98;
- case 6: goto yy127;
- }
+ YYCURSOR = YYMARKER;
+ if(yyaccept <= 3) {
+ if(yyaccept <= 1) {
+ if(yyaccept <= 0) {
+ goto yy61;
+ } else {
+ goto yy67;
+ }
+ } else {
+ if(yyaccept <= 2) {
+ goto yy69;
+ } else {
+ goto yy71;
+ }
+ }
+ } else {
+ if(yyaccept <= 5) {
+ if(yyaccept <= 4) {
+ goto yy75;
+ } else {
+ goto yy98;
+ }
+ } else {
+ goto yy127;
+ }
+ }
yy96:
- yyaccept = 5;
- YYMARKER = ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- case '_':
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z': goto yy96;
- case ':': goto yy94;
- default: goto yy98;
- }
+ yyaccept = 5;
+ YYMARKER = ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= 'Z') {
+ if(yych <= '9') {
+ if(yych >= '0') goto yy96;
+ } else {
+ if(yych <= ':') goto yy94;
+ if(yych >= 'A') goto yy96;
+ }
+ } else {
+ if(yych <= '_') {
+ if(yych >= '_') goto yy96;
+ } else {
+ if(yych <= '`') goto yy98;
+ if(yych <= 'z') goto yy96;
+ }
+ }
yy98:
-#line 261 "scanner.re"
- { cur = cursor;
+ { cur = cursor;
tok+= 5; /* skip "re2c:" */
iscfg = 1;
yylval.str = new Str(token());
return CONFIG;
}
-#line 967 "scanner.cc"
yy99:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy100:
- switch(yych) {
- case 0x0A: goto yy95;
- case '\\': goto yy103;
- case ']': goto yy104;
- default: goto yy99;
- }
+ if(yybm[0+yych] & 16) {
+ goto yy99;
+ }
+ if(yych <= '[') goto yy95;
+ if(yych <= '\\') goto yy103;
+ goto yy104;
yy101:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy95;
- case '\\': goto yy106;
- case ']': goto yy107;
- default: goto yy101;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= '[') {
+ if(yych == 0x0A) goto yy95;
+ goto yy101;
+ } else {
+ if(yych <= '\\') goto yy106;
+ if(yych <= ']') goto yy107;
+ goto yy101;
+ }
yy103:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy95;
- default: goto yy99;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy95;
+ goto yy99;
yy104:
- ++YYCURSOR;
-#line 233 "scanner.re"
- { cur = cursor;
+ ++YYCURSOR;
+ { cur = cursor;
yylval.regexp = ranToRE(token());
return RANGE; }
-#line 1003 "scanner.cc"
yy106:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy95;
- default: goto yy101;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy95;
+ goto yy101;
yy107:
- ++YYCURSOR;
-#line 229 "scanner.re"
- { cur = cursor;
+ ++YYCURSOR;
+ { cur = cursor;
yylval.regexp = invToRE(token());
return RANGE; }
-#line 1018 "scanner.cc"
yy109:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy110:
- switch(yych) {
- case 0x0A: goto yy95;
- case '\'': goto yy112;
- case '\\': goto yy111;
- default: goto yy109;
- }
-yy111:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy95;
- default: goto yy109;
- }
+ if(yybm[0+yych] & 32) {
+ goto yy109;
+ }
+ if(yych <= '&') goto yy95;
+ if(yych <= '\'') goto yy112;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy95;
+ goto yy109;
yy112:
- ++YYCURSOR;
-#line 222 "scanner.re"
- { cur = cursor;
+ ++YYCURSOR;
+ { cur = cursor;
yylval.regexp = strToCaseInsensitiveRE(token());
return STRING; }
-#line 1044 "scanner.cc"
yy114:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy115:
- switch(yych) {
- case 0x0A: goto yy95;
- case '"': goto yy117;
- case '\\': goto yy116;
- default: goto yy114;
- }
-yy116:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy95;
- default: goto yy114;
- }
+ if(yybm[0+yych] & 64) {
+ goto yy114;
+ }
+ if(yych <= '!') goto yy95;
+ if(yych <= '"') goto yy117;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy95;
+ goto yy114;
yy117:
- ++YYCURSOR;
-#line 218 "scanner.re"
- { cur = cursor;
+ ++YYCURSOR;
+ { cur = cursor;
yylval.regexp = strToRE(token());
return STRING; }
-#line 1070 "scanner.cc"
yy119:
- ++YYCURSOR;
-#line 215 "scanner.re"
- { tok = cursor;
+ ++YYCURSOR;
+ { tok = cursor;
RETURN(0); }
-#line 1076 "scanner.cc"
yy121:
- ++YYCURSOR;
-#line 212 "scanner.re"
- { depth = 1;
+ ++YYCURSOR;
+ { depth = 1;
goto comment; }
-#line 1082 "scanner.cc"
yy123:
- yych = *++YYCURSOR;
- switch(yych) {
- case ',': goto yy137;
- default: goto yy125;
- }
+ yych = *++YYCURSOR;
+ if(yych == ',') goto yy137;
+ goto yy125;
yy124:
- ++YYCURSOR;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-(2);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
yy125:
- switch(yych) {
- case ',': goto yy130;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy124;
- case '}': goto yy128;
- default: goto yy95;
- }
+ if(yybm[0+yych] & 128) {
+ goto yy124;
+ }
+ if(yych == ',') goto yy130;
+ if(yych == '}') goto yy128;
+ goto yy95;
yy126:
- ++YYCURSOR;
+ ++YYCURSOR;
yy127:
-#line 259 "scanner.re"
- { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
-#line 1115 "scanner.cc"
+ { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
yy128:
- ++YYCURSOR;
-#line 247 "scanner.re"
- { yylval.extop.minsize = atoi((char *)tok+1);
+ ++YYCURSOR;
+ { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = atoi((char *)tok+1);
RETURN(CLOSESIZE); }
-#line 1122 "scanner.cc"
yy130:
- yyaccept = 6;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy133;
- case '}': goto yy131;
- default: goto yy127;
- }
-yy131:
- ++YYCURSOR;
-#line 255 "scanner.re"
- { yylval.extop.minsize = atoi((char *)tok+1);
+ yyaccept = 6;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych <= '/') goto yy127;
+ if(yych <= '9') goto yy133;
+ if(yych != '}') goto yy127;
+ ++YYCURSOR;
+ { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = -1;
RETURN(CLOSESIZE); }
-#line 1146 "scanner.cc"
yy133:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy133;
- case '}': goto yy135;
- default: goto yy95;
- }
-yy135:
- ++YYCURSOR;
-#line 251 "scanner.re"
- { yylval.extop.minsize = atoi((char *)tok+1);
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= '/') goto yy95;
+ if(yych <= '9') goto yy133;
+ if(yych != '}') goto yy95;
+ ++YYCURSOR;
+ { yylval.extop.minsize = atoi((char *)tok+1);
yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
RETURN(CLOSESIZE); }
-#line 1171 "scanner.cc"
yy137:
- yyaccept = 6;
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy133;
- case '}': goto yy138;
- default: goto yy127;
- }
-yy138:
- ++YYCURSOR;
-#line 244 "scanner.re"
- { yylval.op = '*';
+ yyaccept = 6;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych <= '/') goto yy127;
+ if(yych <= '9') goto yy133;
+ if(yych != '}') goto yy127;
+ ++YYCURSOR;
+ { yylval.op = '*';
RETURN(CLOSE); }
-#line 1194 "scanner.cc"
+ }
}
-#line 290 "scanner.re"
code:
-
-#line 1201 "scanner.cc"
{
- YYCTYPE yych;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-(2);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x00: goto yy148;
- case 0x0A: goto yy146;
- case '"': goto yy152;
- case '\'': goto yy153;
- case '{': goto yy144;
- case '}': goto yy142;
- default: goto yy150;
- }
-yy142:
- ++YYCURSOR;
-#line 294 "scanner.re"
- { if(--depth == 0){
+ static const unsigned char yybm[] = {
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 0, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 64, 192, 192, 192, 192, 128,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 0, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ 192, 192, 192, 192, 192, 192, 192, 192,
+ };
+
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych <= '&') {
+ if(yych <= 0x0A) {
+ if(yych <= 0x00) goto yy148;
+ if(yych <= 0x09) goto yy150;
+ goto yy146;
+ } else {
+ if(yych == '"') goto yy152;
+ goto yy150;
+ }
+ } else {
+ if(yych <= '{') {
+ if(yych <= '\'') goto yy153;
+ if(yych <= 'z') goto yy150;
+ goto yy144;
+ } else {
+ if(yych != '}') goto yy150;
+ }
+ }
+ ++YYCURSOR;
+ { if(--depth == 0){
cur = cursor;
yylval.token = new Token(token(), tline);
return CODE;
}
goto code; }
-#line 1225 "scanner.cc"
yy144:
- ++YYCURSOR;
-#line 300 "scanner.re"
- { ++depth;
+ ++YYCURSOR;
+ { ++depth;
goto code; }
-#line 1231 "scanner.cc"
yy146:
- ++YYCURSOR;
-#line 302 "scanner.re"
- { if(cursor == eof) fatal("missing '}'");
+ ++YYCURSOR;
+ { if(cursor == eof) fatal("missing '}'");
pos = cursor; cline++;
goto code;
}
-#line 1239 "scanner.cc"
yy148:
- ++YYCURSOR;
-#line 306 "scanner.re"
- { if(cursor == eof) {
+ ++YYCURSOR;
+ { if(cursor == eof) {
if (depth) fatal("missing '}'");
RETURN(0);
}
goto code;
}
-#line 1249 "scanner.cc"
yy150:
- ++YYCURSOR;
+ ++YYCURSOR;
yy151:
-#line 312 "scanner.re"
- { goto code; }
-#line 1255 "scanner.cc"
+ { goto code; }
yy152:
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy151;
- default: goto yy159;
- }
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == 0x0A) goto yy151;
+ goto yy159;
yy153:
- yych = *(YYMARKER = ++YYCURSOR);
- switch(yych) {
- case 0x0A: goto yy151;
- default: goto yy155;
- }
+ yych = *(YYMARKER = ++YYCURSOR);
+ if(yych == 0x0A) goto yy151;
+ goto yy155;
yy154:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy155:
- switch(yych) {
- case 0x0A: goto yy156;
- case '\'': goto yy150;
- case '\\': goto yy157;
- default: goto yy154;
- }
+ if(yybm[0+yych] & 64) {
+ goto yy154;
+ }
+ if(yych <= '&') goto yy156;
+ if(yych <= '\'') goto yy150;
+ goto yy157;
yy156:
- YYCURSOR = YYMARKER;
- goto yy151;
+ YYCURSOR = YYMARKER;
+ goto yy151;
yy157:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy156;
- default: goto yy154;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy156;
+ goto yy154;
yy158:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy159:
- switch(yych) {
- case 0x0A: goto yy156;
- case '"': goto yy150;
- case '\\': goto yy160;
- default: goto yy158;
- }
-yy160:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy156;
- default: goto yy158;
+ if(yybm[0+yych] & 128) {
+ goto yy158;
+ }
+ if(yych <= '!') goto yy156;
+ if(yych <= '"') goto yy150;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy156;
+ goto yy158;
}
}
-#line 313 "scanner.re"
comment:
-
-#line 1315 "scanner.cc"
{
- YYCTYPE yych;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-(2);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy166;
- case '*': goto yy163;
- case '/': goto yy165;
- default: goto yy168;
- }
+
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych <= ')') {
+ if(yych == 0x0A) goto yy166;
+ goto yy168;
+ } else {
+ if(yych <= '*') goto yy163;
+ if(yych == '/') goto yy165;
+ goto yy168;
+ }
yy163:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case '/': goto yy171;
- default: goto yy164;
- }
+ ++YYCURSOR;
+ if((yych = *YYCURSOR) == '/') goto yy171;
yy164:
-#line 328 "scanner.re"
- { if(cursor == eof) RETURN(0);
+ { if(cursor == eof) RETURN(0);
goto comment; }
-#line 1337 "scanner.cc"
yy165:
- yych = *++YYCURSOR;
- switch(yych) {
- case '*': goto yy169;
- default: goto yy164;
- }
+ yych = *++YYCURSOR;
+ if(yych == '*') goto yy169;
+ goto yy164;
yy166:
- ++YYCURSOR;
-#line 324 "scanner.re"
- { if(cursor == eof) RETURN(0);
+ ++YYCURSOR;
+ { if(cursor == eof) RETURN(0);
tok = pos = cursor; cline++;
goto comment;
}
-#line 1351 "scanner.cc"
yy168:
- yych = *++YYCURSOR;
- goto yy164;
+ yych = *++YYCURSOR;
+ goto yy164;
yy169:
- ++YYCURSOR;
-#line 321 "scanner.re"
- { ++depth;
+ ++YYCURSOR;
+ { ++depth;
fatal("ambiguous /* found");
goto comment; }
-#line 1361 "scanner.cc"
yy171:
- ++YYCURSOR;
-#line 317 "scanner.re"
- { if(--depth == 0)
+ ++YYCURSOR;
+ { if(--depth == 0)
goto scan;
else
goto comment; }
-#line 1369 "scanner.cc"
+ }
}
-#line 330 "scanner.re"
config:
-
-#line 1376 "scanner.cc"
{
- YYCTYPE yych;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-(2);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case ' ': goto yy175;
- case '=': goto yy177;
- default: goto yy179;
- }
+ static const unsigned char yybm[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 128, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ };
+
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych <= 0x1F) {
+ if(yych != 0x09) goto yy179;
+ } else {
+ if(yych <= ' ') goto yy175;
+ if(yych == '=') goto yy177;
+ goto yy179;
+ }
yy175:
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy184;
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy184;
yy176:
-#line 334 "scanner.re"
- { goto config; }
-#line 1395 "scanner.cc"
+ { goto config; }
yy177:
- ++YYCURSOR;
- yych = *YYCURSOR;
- goto yy182;
+ ++YYCURSOR;
+ yych = *YYCURSOR;
+ goto yy182;
yy178:
-#line 335 "scanner.re"
- { iscfg = 2;
+ { iscfg = 2;
cur = cursor;
RETURN('=');
}
-#line 1406 "scanner.cc"
yy179:
- ++YYCURSOR;
-#line 339 "scanner.re"
- { fatal("missing '='"); }
-#line 1411 "scanner.cc"
+ ++YYCURSOR;
+ { fatal("missing '='"); }
yy181:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy182:
- switch(yych) {
- case 0x09:
- case ' ': goto yy181;
- default: goto yy178;
- }
+ if(yybm[0+yych] & 128) {
+ goto yy181;
+ }
+ goto yy178;
yy183:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy184:
- switch(yych) {
- case 0x09:
- case ' ': goto yy183;
- default: goto yy176;
+ if(yych == 0x09) goto yy183;
+ if(yych == ' ') goto yy183;
+ goto yy176;
}
}
-#line 340 "scanner.re"
value:
-
-#line 1438 "scanner.cc"
{
- YYCTYPE yych;
- if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-(2);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0A:
- case 0x0D:
- case ' ':
- case ';': goto yy187;
- case '"': goto yy195;
- case '\'': goto yy197;
- case '-': goto yy190;
- case '0': goto yy188;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy191;
- default: goto yy193;
- }
+ static const unsigned char yybm[] = {
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 192, 0, 248, 248, 192, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 192, 248, 104, 248, 248, 248, 248, 152,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 252, 252, 252, 252, 252, 252, 252, 252,
+ 252, 252, 248, 192, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 8, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ 248, 248, 248, 248, 248, 248, 248, 248,
+ };
+
+ {
+ YYCTYPE yych;
+ if((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if(yych <= '&') {
+ if(yych <= 0x0D) {
+ if(yych <= 0x08) goto yy193;
+ if(yych <= 0x0A) goto yy187;
+ if(yych <= 0x0C) goto yy193;
+ } else {
+ if(yych <= ' ') {
+ if(yych <= 0x1F) goto yy193;
+ } else {
+ if(yych == '"') goto yy195;
+ goto yy193;
+ }
+ }
+ } else {
+ if(yych <= '/') {
+ if(yych <= '\'') goto yy197;
+ if(yych == '-') goto yy190;
+ goto yy193;
+ } else {
+ if(yych <= '9') {
+ if(yych <= '0') goto yy188;
+ goto yy191;
+ } else {
+ if(yych != ';') goto yy193;
+ }
+ }
+ }
yy187:
-#line 349 "scanner.re"
- { cur = cursor;
+ { cur = cursor;
yylval.str = new Str(token());
iscfg = 0;
return VALUE;
}
-#line 1472 "scanner.cc"
yy188:
- ++YYCURSOR;
- switch((yych = *YYCURSOR)) {
- case 0x09:
- case 0x0A:
- case 0x0D:
- case ' ':
- case ';': goto yy189;
- default: goto yy193;
- }
+ ++YYCURSOR;
+ if(yybm[0+(yych = *YYCURSOR)] & 8) {
+ goto yy193;
+ }
yy189:
-#line 344 "scanner.re"
- { cur = cursor;
+ { cur = cursor;
yylval.number = atoi(token().to_string().c_str());
iscfg = 0;
return NUMBER;
}
-#line 1490 "scanner.cc"
yy190:
- yych = *++YYCURSOR;
- switch(yych) {
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy191;
- default: goto yy194;
- }
+ yych = *++YYCURSOR;
+ if(yych <= '0') goto yy194;
+ if(yych >= ':') goto yy194;
yy191:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0A:
- case 0x0D:
- case ' ':
- case ';': goto yy189;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9': goto yy191;
- default: goto yy193;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 4) {
+ goto yy191;
+ }
+ if(yych <= 0x0D) {
+ if(yych <= 0x08) goto yy193;
+ if(yych <= 0x0A) goto yy189;
+ if(yych >= 0x0D) goto yy189;
+ } else {
+ if(yych <= ' ') {
+ if(yych >= ' ') goto yy189;
+ } else {
+ if(yych == ';') goto yy189;
+ }
+ }
yy193:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
yy194:
- switch(yych) {
- case 0x09:
- case 0x0A:
- case 0x0D:
- case ' ':
- case ';': goto yy187;
- default: goto yy193;
- }
+ if(yybm[0+yych] & 8) {
+ goto yy193;
+ }
+ goto yy187;
yy195:
- YYMARKER = ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0D:
- case ' ':
- case ';': goto yy205;
- case 0x0A: goto yy187;
- case '"': goto yy193;
- case '\\': goto yy207;
- default: goto yy195;
- }
+ YYMARKER = ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 16) {
+ goto yy195;
+ }
+ if(yych <= '!') {
+ if(yych == 0x0A) goto yy187;
+ goto yy205;
+ } else {
+ if(yych <= '"') goto yy193;
+ if(yych <= '[') goto yy205;
+ goto yy207;
+ }
yy197:
- YYMARKER = ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0D:
- case ' ':
- case ';': goto yy199;
- case 0x0A: goto yy187;
- case '\'': goto yy193;
- case '\\': goto yy202;
- default: goto yy197;
- }
+ YYMARKER = ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 32) {
+ goto yy197;
+ }
+ if(yych <= '&') {
+ if(yych == 0x0A) goto yy187;
+ } else {
+ if(yych <= '\'') goto yy193;
+ if(yych >= '\\') goto yy202;
+ }
yy199:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy201;
- case '\'': goto yy203;
- case '\\': goto yy204;
- default: goto yy199;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 64) {
+ goto yy199;
+ }
+ if(yych <= '&') goto yy201;
+ if(yych <= '\'') goto yy203;
+ goto yy204;
yy201:
- YYCURSOR = YYMARKER;
- goto yy187;
+ YYCURSOR = YYMARKER;
+ goto yy187;
yy202:
- YYMARKER = ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0D:
- case ' ':
- case ';': goto yy199;
- case 0x0A: goto yy187;
- default: goto yy197;
- }
+ YYMARKER = ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= 0x0D) {
+ if(yych <= 0x09) {
+ if(yych <= 0x08) goto yy197;
+ goto yy199;
+ } else {
+ if(yych <= 0x0A) goto yy187;
+ if(yych <= 0x0C) goto yy197;
+ goto yy199;
+ }
+ } else {
+ if(yych <= ' ') {
+ if(yych <= 0x1F) goto yy197;
+ goto yy199;
+ } else {
+ if(yych == ';') goto yy199;
+ goto yy197;
+ }
+ }
yy203:
- yych = *++YYCURSOR;
- goto yy187;
+ yych = *++YYCURSOR;
+ goto yy187;
yy204:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy201;
- default: goto yy199;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy201;
+ goto yy199;
yy205:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy201;
- case '"': goto yy203;
- case '\\': goto yy208;
- default: goto yy205;
- }
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yybm[0+yych] & 128) {
+ goto yy205;
+ }
+ if(yych <= '!') goto yy201;
+ if(yych <= '"') goto yy203;
+ goto yy208;
yy207:
- YYMARKER = ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x09:
- case 0x0D:
- case ' ':
- case ';': goto yy205;
- case 0x0A: goto yy187;
- default: goto yy195;
- }
+ YYMARKER = ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych <= 0x0D) {
+ if(yych <= 0x09) {
+ if(yych <= 0x08) goto yy195;
+ goto yy205;
+ } else {
+ if(yych <= 0x0A) goto yy187;
+ if(yych <= 0x0C) goto yy195;
+ goto yy205;
+ }
+ } else {
+ if(yych <= ' ') {
+ if(yych <= 0x1F) goto yy195;
+ goto yy205;
+ } else {
+ if(yych == ';') goto yy205;
+ goto yy195;
+ }
+ }
yy208:
- ++YYCURSOR;
- if(YYLIMIT == YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- switch(yych) {
- case 0x0A: goto yy201;
- default: goto yy205;
+ ++YYCURSOR;
+ if(YYLIMIT == YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if(yych == 0x0A) goto yy201;
+ goto yy205;
}
}
-#line 354 "scanner.re"
}
diff --git a/tools/re2c/scanner.re b/tools/re2c/scanner.re
index 743675df6..fde59be72 100644
--- a/tools/re2c/scanner.re
+++ b/tools/re2c/scanner.re
@@ -1,373 +1,373 @@
-/* $Id:$ */
-#include
-#include
-#include
-#include
-#include "scanner.h"
-#include "parser.h"
-#include "y.tab.h"
-#include "globals.h"
-#include "dfa.h"
-
-extern YYSTYPE yylval;
-
-#ifndef MAX
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#endif
-
-#define BSIZE 8192
-
-#define YYCTYPE unsigned char
-#define YYCURSOR cursor
-#define YYLIMIT lim
-#define YYMARKER ptr
-#define YYFILL(n) {cursor = fill(cursor);}
-
-#define RETURN(i) {cur = cursor; return i;}
-
-namespace re2c
-{
-
-Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
- : in(i)
- , out(o)
- , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
- , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
-{
- ;
-}
-
-char *Scanner::fill(char *cursor)
-{
- if(!eof)
- {
- uint cnt = tok - bot;
- if(cnt)
- {
- memcpy(bot, tok, lim - tok);
- tok = bot;
- ptr -= cnt;
- cursor -= cnt;
- pos -= cnt;
- lim -= cnt;
- }
- if((top - lim) < BSIZE)
- {
- char *buf = new char[(lim - bot) + BSIZE];
- memcpy(buf, tok, lim - tok);
- tok = buf;
- ptr = &buf[ptr - bot];
- cursor = &buf[cursor - bot];
- pos = &buf[pos - bot];
- lim = &buf[lim - bot];
- top = &lim[BSIZE];
- delete [] bot;
- bot = buf;
- }
- in.read(lim, BSIZE);
- if ((cnt = in.gcount()) != BSIZE )
- {
- eof = &lim[cnt]; *eof++ = '\0';
- }
- lim += cnt;
- }
- return cursor;
-}
-
-/*!re2c
-zero = "\000";
-any = [\000-\377];
-dot = any \ [\n];
-esc = dot \ [\\];
-istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
-cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
-dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
-sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
-letter = [a-zA-Z];
-digit = [0-9];
-number = "0" | ("-"? [1-9] digit*);
+/* $Id: scanner.re 663 2007-04-01 11:22:15Z helly $ */
+#include
+#include
+#include
+#include
+#include "scanner.h"
+#include "parser.h"
+#include "y.tab.h"
+#include "globals.h"
+#include "dfa.h"
+
+extern YYSTYPE yylval;
+
+#ifndef MAX
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
+
+#define BSIZE 8192
+
+#define YYCTYPE unsigned char
+#define YYCURSOR cursor
+#define YYLIMIT lim
+#define YYMARKER ptr
+#define YYFILL(n) {cursor = fill(cursor);}
+
+#define RETURN(i) {cur = cursor; return i;}
+
+namespace re2c
+{
+
+Scanner::Scanner(const char *fn, std::istream& i, std::ostream& o)
+ : in(i)
+ , out(o)
+ , bot(NULL), tok(NULL), ptr(NULL), cur(NULL), pos(NULL), lim(NULL)
+ , top(NULL), eof(NULL), tchar(0), tline(0), cline(1), iscfg(0), filename(fn)
+{
+ ;
+}
+
+char *Scanner::fill(char *cursor)
+{
+ if(!eof)
+ {
+ uint cnt = tok - bot;
+ if(cnt)
+ {
+ memcpy(bot, tok, lim - tok);
+ tok = bot;
+ ptr -= cnt;
+ cursor -= cnt;
+ pos -= cnt;
+ lim -= cnt;
+ }
+ if((top - lim) < BSIZE)
+ {
+ char *buf = new char[(lim - bot) + BSIZE];
+ memcpy(buf, tok, lim - tok);
+ tok = buf;
+ ptr = &buf[ptr - bot];
+ cursor = &buf[cursor - bot];
+ pos = &buf[pos - bot];
+ lim = &buf[lim - bot];
+ top = &lim[BSIZE];
+ delete [] bot;
+ bot = buf;
+ }
+ in.read(lim, BSIZE);
+ if ((cnt = in.gcount()) != BSIZE )
+ {
+ eof = &lim[cnt]; *eof++ = '\0';
+ }
+ lim += cnt;
+ }
+ return cursor;
+}
+
+/*!re2c
+zero = "\000";
+any = [\000-\377];
+dot = any \ [\n];
+esc = dot \ [\\];
+istring = "[" "^" ((esc \ [\]]) | "\\" dot)* "]" ;
+cstring = "[" ((esc \ [\]]) | "\\" dot)* "]" ;
+dstring = "\"" ((esc \ ["] ) | "\\" dot)* "\"";
+sstring = "'" ((esc \ ['] ) | "\\" dot)* "'" ;
+letter = [a-zA-Z];
+digit = [0-9];
+number = "0" | ("-"? [1-9] digit*);
name = (letter|"_") (letter|digit|"_")*;
cname = ":" name;
-space = [ \t];
-eol = ("\r\n" | "\n");
-config = "re2c" cname+;
-value = [^\r\n; \t]* | dstring | sstring;
-*/
-
-int Scanner::echo()
-{
- char *cursor = cur;
- bool ignore_eoc = false;
- int ignore_cnt = 0;
-
- if (eof && cursor == eof) // Catch EOF
- {
- return 0;
- }
-
- tok = cursor;
-echo:
-/*!re2c
- "/*!re2c" {
- if (bUsedYYMaxFill && bSinglePass) {
- 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" {
- tok = pos = cursor;
- genGetState(out, topIndent, 0);
- ignore_eoc = true;
- goto echo;
- }
- "/*!ignore:re2c" {
- tok = pos = cursor;
- ignore_eoc = true;
- goto echo;
- }
- "*" "/" "\r"? "\n" {
- cline++;
- if (ignore_eoc) {
- if (ignore_cnt) {
- out << sourceFileInfo;
- }
- ignore_eoc = false;
- ignore_cnt = 0;
- } else {
- out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
- }
- tok = pos = cursor;
- goto echo;
- }
- "*" "/" {
- if (ignore_eoc) {
- if (ignore_cnt) {
- out << "\n" << sourceFileInfo;
- }
- ignore_eoc = false;
- ignore_cnt = 0;
- } else {
- out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
- }
- tok = pos = cursor;
- goto echo;
- }
- "\n" {
- if (ignore_eoc) {
- ignore_cnt++;
- } else {
- out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
- }
- tok = pos = cursor; cline++;
- goto echo;
- }
- zero {
- 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(cursor == eof) {
- RETURN(0);
- }
- }
- any {
- goto echo;
- }
-*/
-}
-
-
-int Scanner::scan()
-{
- char *cursor = cur;
- uint depth;
-
-scan:
- tchar = cursor - pos;
- tline = cline;
- tok = cursor;
- if (iscfg == 1)
- {
- goto config;
- }
- else if (iscfg == 2)
- {
- goto value;
- }
-/*!re2c
- "{" { depth = 1;
- goto code;
- }
- "/*" { depth = 1;
- goto comment; }
-
- "*/" { tok = cursor;
- RETURN(0); }
-
- dstring { cur = cursor;
- yylval.regexp = strToRE(token());
- return STRING; }
-
- sstring { cur = cursor;
- yylval.regexp = strToCaseInsensitiveRE(token());
- return STRING; }
-
- "\"" { fatal("unterminated string constant (missing \")"); }
- "'" { fatal("unterminated string constant (missing ')"); }
-
- istring { cur = cursor;
- yylval.regexp = invToRE(token());
- return RANGE; }
-
- cstring { cur = cursor;
- yylval.regexp = ranToRE(token());
- return RANGE; }
-
- "[" { fatal("unterminated range (missing ])"); }
-
- [()|=;/\\] { RETURN(*tok); }
-
- [*+?] { yylval.op = *tok;
- RETURN(CLOSE); }
-
- "{0,}" { yylval.op = '*';
- RETURN(CLOSE); }
-
- "{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
- yylval.extop.maxsize = atoi((char *)tok+1);
- RETURN(CLOSESIZE); }
-
- "{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
- yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
- RETURN(CLOSESIZE); }
-
- "{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
- yylval.extop.maxsize = -1;
- RETURN(CLOSESIZE); }
-
- "{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
-
- config { cur = cursor;
- tok+= 5; /* skip "re2c:" */
- iscfg = 1;
- yylval.str = new Str(token());
- return CONFIG;
- }
-
- name { cur = cursor;
- yylval.symbol = Symbol::find(token());
- return ID; }
-
- "." { cur = cursor;
- yylval.regexp = mkDot();
- return RANGE;
- }
-
- space+ { goto scan; }
-
- eol { if(cursor == eof) RETURN(0);
- pos = cursor; cline++;
- goto scan;
- }
-
- any { std::ostringstream msg;
- msg << "unexpected character: ";
- prtChOrHex(msg, *tok);
- fatal(msg.str().c_str());
- goto scan;
- }
-*/
-
-code:
-/*!re2c
- "}" { if(--depth == 0){
- cur = cursor;
- yylval.token = new Token(token(), tline);
- return CODE;
- }
- goto code; }
- "{" { ++depth;
- goto code; }
- "\n" { if(cursor == eof) fatal("missing '}'");
- pos = cursor; cline++;
- goto code;
- }
- zero { if(cursor == eof) {
- if (depth) fatal("missing '}'");
- RETURN(0);
- }
- goto code;
- }
- dstring | sstring | any { goto code; }
-*/
-
-comment:
-/*!re2c
- "*/" { if(--depth == 0)
- goto scan;
- else
- goto comment; }
- "/*" { ++depth;
- fatal("ambiguous /* found");
- goto comment; }
- "\n" { if(cursor == eof) RETURN(0);
- tok = pos = cursor; cline++;
- goto comment;
- }
- any { if(cursor == eof) RETURN(0);
- goto comment; }
-*/
-
-config:
-/*!re2c
- space+ { goto config; }
- "=" space* { iscfg = 2;
- cur = cursor;
- RETURN('=');
- }
- any { fatal("missing '='"); }
-*/
-
-value:
-/*!re2c
- number { cur = cursor;
- yylval.number = atoi(token().to_string().c_str());
- iscfg = 0;
- return NUMBER;
- }
- value { cur = cursor;
- yylval.str = new Str(token());
- iscfg = 0;
- return VALUE;
- }
-*/
-}
-
-void Scanner::fatal(uint ofs, const char *msg) const
-{
- out.flush();
-#ifdef _MSC_VER
- std::cerr << filename << "(" << tline << "): error : "
- << "column " << (tchar + ofs + 1) << ": "
- << msg << std::endl;
-#else
- std::cerr << "re2c: error: "
- << "line " << tline << ", column " << (tchar + ofs + 1) << ": "
- << msg << std::endl;
-#endif
- exit(1);
-}
+space = [ \t];
+eol = ("\r\n" | "\n");
+config = "re2c" cname+;
+value = [^\r\n; \t]* | dstring | sstring;
+*/
+
+int Scanner::echo()
+{
+ char *cursor = cur;
+ bool ignore_eoc = false;
+ int ignore_cnt = 0;
+
+ if (eof && cursor == eof) // Catch EOF
+ {
+ return 0;
+ }
+
+ tok = cursor;
+echo:
+/*!re2c
+ "/*!re2c" {
+ if (bUsedYYMaxFill && bSinglePass) {
+ 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" {
+ tok = pos = cursor;
+ genGetState(out, topIndent, 0);
+ ignore_eoc = true;
+ goto echo;
+ }
+ "/*!ignore:re2c" {
+ tok = pos = cursor;
+ ignore_eoc = true;
+ goto echo;
+ }
+ "*" "/" "\r"? "\n" {
+ cline++;
+ if (ignore_eoc) {
+ if (ignore_cnt) {
+ out << sourceFileInfo;
+ }
+ ignore_eoc = false;
+ ignore_cnt = 0;
+ } else {
+ out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
+ }
+ tok = pos = cursor;
+ goto echo;
+ }
+ "*" "/" {
+ if (ignore_eoc) {
+ if (ignore_cnt) {
+ out << "\n" << sourceFileInfo;
+ }
+ ignore_eoc = false;
+ ignore_cnt = 0;
+ } else {
+ out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
+ }
+ tok = pos = cursor;
+ goto echo;
+ }
+ "\n" {
+ if (ignore_eoc) {
+ ignore_cnt++;
+ } else {
+ out.write((const char*)(tok), (const char*)(cursor) - (const char*)(tok));
+ }
+ tok = pos = cursor; cline++;
+ goto echo;
+ }
+ zero {
+ 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(cursor == eof) {
+ RETURN(0);
+ }
+ }
+ any {
+ goto echo;
+ }
+*/
+}
+
+
+int Scanner::scan()
+{
+ char *cursor = cur;
+ uint depth;
+
+scan:
+ tchar = cursor - pos;
+ tline = cline;
+ tok = cursor;
+ if (iscfg == 1)
+ {
+ goto config;
+ }
+ else if (iscfg == 2)
+ {
+ goto value;
+ }
+/*!re2c
+ "{" { depth = 1;
+ goto code;
+ }
+ "/*" { depth = 1;
+ goto comment; }
+
+ "*/" { tok = cursor;
+ RETURN(0); }
+
+ dstring { cur = cursor;
+ yylval.regexp = strToRE(token());
+ return STRING; }
+
+ sstring { cur = cursor;
+ yylval.regexp = strToCaseInsensitiveRE(token());
+ return STRING; }
+
+ "\"" { fatal("unterminated string constant (missing \")"); }
+ "'" { fatal("unterminated string constant (missing ')"); }
+
+ istring { cur = cursor;
+ yylval.regexp = invToRE(token());
+ return RANGE; }
+
+ cstring { cur = cursor;
+ yylval.regexp = ranToRE(token());
+ return RANGE; }
+
+ "[" { fatal("unterminated range (missing ])"); }
+
+ [()|=;/\\] { RETURN(*tok); }
+
+ [*+?] { yylval.op = *tok;
+ RETURN(CLOSE); }
+
+ "{0,}" { yylval.op = '*';
+ RETURN(CLOSE); }
+
+ "{" [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
+ yylval.extop.maxsize = atoi((char *)tok+1);
+ RETURN(CLOSESIZE); }
+
+ "{" [0-9]+ "," [0-9]+ "}" { yylval.extop.minsize = atoi((char *)tok+1);
+ yylval.extop.maxsize = MAX(yylval.extop.minsize,atoi(strchr((char *)tok, ',')+1));
+ RETURN(CLOSESIZE); }
+
+ "{" [0-9]+ ",}" { yylval.extop.minsize = atoi((char *)tok+1);
+ yylval.extop.maxsize = -1;
+ RETURN(CLOSESIZE); }
+
+ "{" [0-9]* "," { fatal("illegal closure form, use '{n}', '{n,}', '{n,m}' where n and m are numbers"); }
+
+ config { cur = cursor;
+ tok+= 5; /* skip "re2c:" */
+ iscfg = 1;
+ yylval.str = new Str(token());
+ return CONFIG;
+ }
+
+ name { cur = cursor;
+ yylval.symbol = Symbol::find(token());
+ return ID; }
+
+ "." { cur = cursor;
+ yylval.regexp = mkDot();
+ return RANGE;
+ }
+
+ space+ { goto scan; }
+
+ eol { if(cursor == eof) RETURN(0);
+ pos = cursor; cline++;
+ goto scan;
+ }
+
+ any { std::ostringstream msg;
+ msg << "unexpected character: ";
+ prtChOrHex(msg, *tok);
+ fatal(msg.str().c_str());
+ goto scan;
+ }
+*/
+
+code:
+/*!re2c
+ "}" { if(--depth == 0){
+ cur = cursor;
+ yylval.token = new Token(token(), tline);
+ return CODE;
+ }
+ goto code; }
+ "{" { ++depth;
+ goto code; }
+ "\n" { if(cursor == eof) fatal("missing '}'");
+ pos = cursor; cline++;
+ goto code;
+ }
+ zero { if(cursor == eof) {
+ if (depth) fatal("missing '}'");
+ RETURN(0);
+ }
+ goto code;
+ }
+ dstring | sstring | any { goto code; }
+*/
+
+comment:
+/*!re2c
+ "*/" { if(--depth == 0)
+ goto scan;
+ else
+ goto comment; }
+ "/*" { ++depth;
+ fatal("ambiguous /* found");
+ goto comment; }
+ "\n" { if(cursor == eof) RETURN(0);
+ tok = pos = cursor; cline++;
+ goto comment;
+ }
+ any { if(cursor == eof) RETURN(0);
+ goto comment; }
+*/
+
+config:
+/*!re2c
+ space+ { goto config; }
+ "=" space* { iscfg = 2;
+ cur = cursor;
+ RETURN('=');
+ }
+ any { fatal("missing '='"); }
+*/
+
+value:
+/*!re2c
+ number { cur = cursor;
+ yylval.number = atoi(token().to_string().c_str());
+ iscfg = 0;
+ return NUMBER;
+ }
+ value { cur = cursor;
+ yylval.str = new Str(token());
+ iscfg = 0;
+ return VALUE;
+ }
+*/
+}
+
+void Scanner::fatal(uint ofs, const char *msg) const
+{
+ out.flush();
+#ifdef _MSC_VER
+ std::cerr << filename << "(" << tline << "): error : "
+ << "column " << (tchar + ofs + 1) << ": "
+ << msg << std::endl;
+#else
+ std::cerr << "re2c: error: "
+ << "line " << tline << ", column " << (tchar + ofs + 1) << ": "
+ << msg << std::endl;
+#endif
+ exit(1);
+}
Scanner::~Scanner()
{
@@ -376,6 +376,6 @@ Scanner::~Scanner()
delete [] bot;
}
}
-
-} // end namespace re2c
-
+
+} // end namespace re2c
+
diff --git a/tools/re2c/stream_lc.h b/tools/re2c/stream_lc.h
index 92a56c309..cc6682291 100644
--- a/tools/re2c/stream_lc.h
+++ b/tools/re2c/stream_lc.h
@@ -2,7 +2,7 @@
Author: Marcus Boerger
*/
-/* $Id: stream_lc.h,v 1.10 2006/02/26 20:36:09 helly Exp $ */
+/* $Id: stream_lc.h 767 2007-06-26 15:21:10Z helly $ */
#ifndef _stream_lc_h
#define _stream_lc_h
diff --git a/tools/re2c/substr.cc b/tools/re2c/substr.cc
index be667f290..7796c1dc0 100644
--- a/tools/re2c/substr.cc
+++ b/tools/re2c/substr.cc
@@ -1,4 +1,4 @@
-/* $Id: substr.cc,v 1.11 2006/02/26 20:30:54 helly Exp $ */
+/* $Id: substr.cc 546 2006-05-25 13:40:14Z helly $ */
#include
#include
#include "substr.h"
diff --git a/tools/re2c/substr.h b/tools/re2c/substr.h
index eec50614a..7b56e0042 100644
--- a/tools/re2c/substr.h
+++ b/tools/re2c/substr.h
@@ -1,4 +1,4 @@
-/* $Id: substr.h,v 1.10 2006/01/01 13:42:10 helly Exp $ */
+/* $Id: substr.h 530 2006-05-25 13:34:33Z helly $ */
#ifndef _substr_h
#define _substr_h
diff --git a/tools/re2c/token.h b/tools/re2c/token.h
index b0bb6cc25..4abfbff01 100644
--- a/tools/re2c/token.h
+++ b/tools/re2c/token.h
@@ -1,4 +1,4 @@
-/* $Id: token.h,v 1.4 2004/11/01 04:35:57 nuffer Exp $ */
+/* $Id: token.h 547 2006-05-25 13:40:35Z helly $ */
#ifndef _token_h
#define _token_h
diff --git a/tools/re2c/translate.cc b/tools/re2c/translate.cc
index 3955622eb..0393856fa 100644
--- a/tools/re2c/translate.cc
+++ b/tools/re2c/translate.cc
@@ -1,4 +1,4 @@
-/* $Id: translate.cc,v 1.5 2005/12/28 18:33:37 helly Exp $ */
+/* $Id: translate.cc 713 2007-04-29 15:33:47Z helly $ */
#include "globals.h"
namespace re2c
diff --git a/tools/xlatcc/gen.c b/tools/xlatcc/gen.c
index a022933c7..010dec693 100644
--- a/tools/xlatcc/gen.c
+++ b/tools/xlatcc/gen.c
@@ -250,7 +250,7 @@ int main (int argc, char **argv)
printf ("Usage: %s