Index: src/parse.y ================================================================== --- src/parse.y +++ src/parse.y @@ -214,10 +214,14 @@ QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT +%ifndef SQLITE_OMIT_WINDOWFUNC + CURRENT FILTER FOLLOWING ?OVER PARTITION + PRECEDING RANGE UNBOUNDED ?WINDOW +%endif SQLITE_OMIT_WINDOWFUNC REINDEX RENAME CTIME_KW IF . %wildcard ANY. // Define operator precedence early so that this is the first occurrence Index: tool/lemon.c ================================================================== --- tool/lemon.c +++ tool/lemon.c @@ -270,10 +270,11 @@ int dtnum; /* The data type number. In the parser, the value ** stack is a union. The .yy%d element of this ** union is the correct data type for this object */ int bContent; /* True if this symbol ever carries content - if ** it is ever more than just syntax */ + int bWeakFallback; /* True for a weak fallback */ /* The following fields are used by MULTITERMINALs only */ int nsubsym; /* Number of constituent symbols in the MULTI */ struct symbol **subsym; /* Array of constituent symbols */ }; @@ -2207,10 +2208,11 @@ RESYNC_AFTER_RULE_ERROR, RESYNC_AFTER_DECL_ERROR, WAITING_FOR_DESTRUCTOR_SYMBOL, WAITING_FOR_DATATYPE_SYMBOL, WAITING_FOR_FALLBACK_ID, + WAITING_FOR_WEAK_FALLBACK_ID, WAITING_FOR_WILDCARD_ID, WAITING_FOR_CLASS_ID, WAITING_FOR_CLASS_TOKEN, WAITING_FOR_TOKEN_NAME }; @@ -2665,10 +2667,16 @@ psp->errorcnt++; psp->state = RESYNC_AFTER_DECL_ERROR; } break; case WAITING_FOR_FALLBACK_ID: + if( x[0]=='?' ){ + psp->state = WAITING_FOR_WEAK_FALLBACK_ID; + break; + } + /* Fall through */ + case WAITING_FOR_WEAK_FALLBACK_ID: if( x[0]=='.' ){ psp->state = WAITING_FOR_DECL_OR_RULE; }else if( !ISUPPER(x[0]) ){ ErrorMsg(psp->filename, psp->tokenlineno, "%%fallback argument \"%s\" should be a token", x); @@ -2681,10 +2689,12 @@ ErrorMsg(psp->filename, psp->tokenlineno, "More than one fallback assigned to token %s", x); psp->errorcnt++; }else{ sp->fallback = psp->fallback; + sp->bWeakFallback = (psp->state==WAITING_FOR_WEAK_FALLBACK_ID); + psp->state = WAITING_FOR_FALLBACK_ID; psp->gp->has_fallback = 1; } } break; case WAITING_FOR_TOKEN_NAME: @@ -4491,10 +4501,13 @@ lemp->tablesize += (mx+1)*szCodeType; for(i=0; i<=mx; i++){ struct symbol *p = lemp->symbols[i]; if( p->fallback==0 ){ fprintf(out, " 0, /* %10s => nothing */\n", p->name); + }else if( p->bWeakFallback ){ + fprintf(out, " %4d, /* %10s => %s (weak) */\n", + -p->fallback->index, p->name, p->fallback->name); }else{ fprintf(out, " %3d, /* %10s => %s */\n", p->fallback->index, p->name, p->fallback->name); } lineno++; @@ -5110,22 +5123,16 @@ sp = Symbol_find(x); if( sp==0 ){ sp = (struct symbol *)calloc(1, sizeof(struct symbol) ); MemoryCheck(sp); + memset(sp, 0, sizeof(*sp)); sp->name = Strsafe(x); sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL; - sp->rule = 0; - sp->fallback = 0; sp->prec = -1; sp->assoc = UNK; - sp->firstset = 0; sp->lambda = LEMON_FALSE; - sp->destructor = 0; - sp->destLineno = 0; - sp->datatype = 0; - sp->useCnt = 0; Symbol_insert(sp,sp->name); } sp->useCnt++; return sp; } Index: tool/lempar.c ================================================================== --- tool/lempar.c +++ tool/lempar.c @@ -88,10 +88,11 @@ # define INTERFACE 1 #endif /************* Begin control #defines *****************************************/ %% /************* End control #defines *******************************************/ +#define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. ** ** Applications can choose to define yytestcase() in the %include section @@ -170,11 +171,11 @@ ** This feature can be used, for example, to cause some keywords in a language ** to revert to identifiers if they keyword does not apply in the context where ** it appears. */ #ifdef YYFALLBACK -static const YYCODETYPE yyFallback[] = { +static const int yyFallback[] = { %% }; #endif /* YYFALLBACK */ /* The following structure represents a single element of the @@ -517,28 +518,38 @@ yycoverage[stateno][iLookAhead] = 1; #endif do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); - assert( i+YYNTOKEN<=(int)sizeof(yy_lookahead)/sizeof(yy_lookahead[0]) ); + /*assert( i+YYNTOKEN<=YY_NLOOKAHEAD );*/ assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - if( yy_lookahead[i]!=iLookAhead ){ + if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead + ){ #ifdef YYFALLBACK - YYCODETYPE iFallback; /* Fallback token */ + int iFallback; /* Fallback token */ if( iLookAhead %s\n", - yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); - } -#endif - assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ - iLookAhead = iFallback; - continue; + && (iFallback = yyFallback[iLookAhead])!=0 + ){ + if( iFallback<0 && yy_default[stateno]==YY_ERROR_ACTION ){ + /* A weak fallback only happens if current lookahead is a + ** syntax error */ + iFallback = -iFallback; + } + if( iFallback>0 ){ + /* A strong fallback happens regardless */ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + assert( yyFallback[iFallback]==0 ); /* Fallback loop must terminate */ + iLookAhead = iFallback; + continue; + } } #endif #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD;