Lemon update 2015-09-07 19:52:55 on branch lemon-update

- Change the parser engine so that it (once again) waits for a lookahead token before reducing, even in a SHIFTREDUCE action. (user: drh)
This commit is contained in:
Randy Heit 2016-03-20 12:02:31 -05:00
parent 3d5867d29e
commit fd3507c4c3

View file

@ -170,9 +170,13 @@ static const YYCODETYPE yyFallback[] = {
** + The semantic value stored at this level of the stack. This is ** + The semantic value stored at this level of the stack. This is
** the information used by the action routines in the grammar. ** the information used by the action routines in the grammar.
** It is sometimes called the "minor" token. ** It is sometimes called the "minor" token.
**
** After the "shift" half of a SHIFTREDUCE action, the stateno field
** actually contains the reduce action for the second half of the
** SHIFTREDUCE.
*/ */
struct yyStackEntry { struct yyStackEntry {
YYACTIONTYPE stateno; /* The state-number */ YYACTIONTYPE stateno; /* The state-number, or reduce action in SHIFTREDUCE */
YYCODETYPE major; /* The major token value. This is the code YYCODETYPE major; /* The major token value. This is the code
** number for the token at this stack level */ ** number for the token at this stack level */
YYMINORTYPE minor; /* The user-supplied minor token value. This YYMINORTYPE minor; /* The user-supplied minor token value. This
@ -401,6 +405,7 @@ static int yy_find_shift_action(
int i; int i;
int stateno = pParser->yystack[pParser->yyidx].stateno; int stateno = pParser->yystack[pParser->yyidx].stateno;
if( stateno>=YY_MIN_REDUCE ) return stateno;
if( stateno>YY_SHIFT_COUNT if( stateno>YY_SHIFT_COUNT
|| (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
return yy_default[stateno]; return yy_default[stateno];
@ -504,10 +509,32 @@ static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
} }
/*
** Print tracing information for a SHIFT action
*/
#ifndef NDEBUG
static void yyTraceShift(yyParser *yypParser, int yyNewState){
if( yyTraceFILE ){
int i;
if( yyNewState<YYNSTATE ){
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");
}else{
fprintf(yyTraceFILE,"%sShift *\n",yyTracePrompt);
}
}
}
#else
# define yyTraceShift(X,Y)
#endif
/* /*
** Perform a shift action. Return the number of errors. ** Perform a shift action. Return the number of errors.
*/ */
static int yy_shift( static void yy_shift(
yyParser *yypParser, /* The parser to be shifted */ yyParser *yypParser, /* The parser to be shifted */
int yyNewState, /* The new state to shift in */ int yyNewState, /* The new state to shift in */
int yyMajor, /* The major token to shift in */ int yyMajor, /* The major token to shift in */
@ -523,14 +550,14 @@ static int yy_shift(
#if YYSTACKDEPTH>0 #if YYSTACKDEPTH>0
if( yypParser->yyidx>=YYSTACKDEPTH ){ if( yypParser->yyidx>=YYSTACKDEPTH ){
yyStackOverflow(yypParser, yypMinor); yyStackOverflow(yypParser, yypMinor);
return 1; return;
} }
#else #else
if( yypParser->yyidx>=yypParser->yystksz ){ if( yypParser->yyidx>=yypParser->yystksz ){
yyGrowStack(yypParser); yyGrowStack(yypParser);
if( yypParser->yyidx>=yypParser->yystksz ){ if( yypParser->yyidx>=yypParser->yystksz ){
yyStackOverflow(yypParser, yypMinor); yyStackOverflow(yypParser, yypMinor);
return 1; return;
} }
} }
#endif #endif
@ -538,21 +565,7 @@ static int yy_shift(
yytos->stateno = (YYACTIONTYPE)yyNewState; yytos->stateno = (YYACTIONTYPE)yyNewState;
yytos->major = (YYCODETYPE)yyMajor; yytos->major = (YYCODETYPE)yyMajor;
yytos->minor = *yypMinor; yytos->minor = *yypMinor;
#ifndef NDEBUG yyTraceShift(yypParser, yyNewState);
if( yyTraceFILE && yypParser->yyidx>0 ){
int i;
if( yyNewState<YYNSTATE ){
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");
}else{
fprintf(yyTraceFILE,"%sShift *\n",yyTracePrompt);
}
}
#endif
return 0;
} }
/* The following table contains information about every rule that /* The following table contains information about every rule that
@ -623,7 +636,8 @@ static void yy_reduce(
yysize = yyRuleInfo[yyruleno].nrhs; yysize = yyRuleInfo[yyruleno].nrhs;
yypParser->yyidx -= yysize; yypParser->yyidx -= yysize;
yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto); yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
if( yyact < YY_MAX_SHIFTREDUCE ){ if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yyact>YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
/* If the reduce action popped at least /* If the reduce action popped at least
** one element off the stack, then we can push the new element back ** 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(). ** onto the stack here, and skip the stack overflow test in yy_shift().
@ -634,16 +648,9 @@ static void yy_reduce(
yymsp->stateno = (YYACTIONTYPE)yyact; yymsp->stateno = (YYACTIONTYPE)yyact;
yymsp->major = (YYCODETYPE)yygoto; yymsp->major = (YYCODETYPE)yygoto;
yymsp->minor = yygotominor; yymsp->minor = yygotominor;
#ifndef NDEBUG yyTraceShift(yypParser, yyact);
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyact);
}
#endif
}else{ }else{
if( yy_shift(yypParser,yyact,yygoto,&yygotominor) ) yyact = 0; yy_shift(yypParser,yyact,yygoto,&yygotominor);
}
if( yyact>=YY_MIN_SHIFTREDUCE ){
yy_reduce(yypParser, yyact - YY_MIN_SHIFTREDUCE);
} }
}else{ }else{
assert( yyact == YY_ACCEPT_ACTION ); assert( yyact == YY_ACCEPT_ACTION );
@ -767,13 +774,10 @@ void Parse(
do{ do{
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor); yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
if( yyact <= YY_MAX_SHIFTREDUCE ){ if( yyact <= YY_MAX_SHIFTREDUCE ){
if( yy_shift(yypParser,yyact,yymajor,&yyminorunion)==0 ){ if( yyact > YY_MAX_SHIFT ) yyact += YY_MIN_REDUCE - YY_MIN_SHIFTREDUCE;
yypParser->yyerrcnt--; yy_shift(yypParser,yyact,yymajor,&yyminorunion);
yymajor = YYNOCODE; yypParser->yyerrcnt--;
if( yyact > YY_MAX_SHIFT ){ yymajor = YYNOCODE;
yy_reduce(yypParser, yyact-YY_MIN_SHIFTREDUCE);
}
}
}else if( yyact <= YY_MAX_REDUCE ){ }else if( yyact <= YY_MAX_REDUCE ){
yy_reduce(yypParser,yyact-YY_MIN_REDUCE); yy_reduce(yypParser,yyact-YY_MIN_REDUCE);
}else{ }else{