shift/reduce 冲突错误
shift/reduce conflicts error
我收到 20 shift/reduce 冲突错误。我通过单独声明来处理运算符的优先级。我不确定 exprList 和 propertyList,我尝试了它们的不同版本,但错误不会改变。
%#include<studio.h>
void yyerror( const char *s)
{
printf("%s\n",s);
}
%}
%token tFOR tIN tFUNCTION tSEMICOLON tLPAR tLBRKT tLBRACE tCOLON tINT
tREAL tSTRING tWHILE tVAR tELSE tCOMMA tRPAR tRBRKT tRBRACE tEQ tNOT tIF
tIDENT
%token tGT
%token tLT
%token tEQCHECK
%left tPLUS tMINUS
%left tSTAR
%%
statementList:statement|statementList statement | statementList
tSEMICOLON statement;
statement: assign | if | expr |statementBlock | while |for | functionCall
| functionDeclaration;
assign: tIDENT tEQ expr | tVAR tIDENT tEQ expr;
if: ifPart elsePart;
ifPart: tIF tLPAR expr tRPAR statementBlock;
elsePart: tELSE statementBlock;
while: tWHILE tLPAR expr tRPAR statementBlock;
for: tFOR tLPAR tVAR tIDENT tIN expr tRPAR statementBlock | tFOR tLPAR
expr tRPAR statementBlock;
functionDeclaration: tFUNCTION tIDENT tLPAR exprList tRPAR statementBlock
| tFUNCTION tIDENT tLPAR tRPAR statementBlock;
statementBlock: tLBRACE statementList tRBRACE;
functionCall:tIDENT tLPAR exprList tRPAR | tIDENT tLPAR tRPAR;
expr: tIDENT | tSTRING |tLBRKT tRBRKT | tLBRKT exprList tRBRKT
|tLBRACE tRBRACE | tLBRACE propertyList tRBRACE | tNOT expr |
expr tPLUS term | expr tMINUS term | term |
expr tEQCHECK expr | expr tLT expr | expr tGT expr;
exprList: expr | exprList tCOMMA expr;
propertyList: tIDENT tCOLON expr
| propertyList tCOMMA tIDENT tCOLON expr;
term:term tSTAR factor | factor;
factor: tREAL| tINT;
%%
%token
不声明运算符的优先级值。所以 tLT
、tGT
和 tEQCHECK
没有优先声明。 (我后来意识到 tNOT
也没有。)
另一方面,您已经声明了 tPLUS
、tMINUS
和 tSTAR
的优先级,但这些定义是不必要的(也未使用),因为您的语法已经明确了它们的含义优先级。
但是,我认为您对 factor
的定义有误:它位于优先链的底部,因此它应该包括所有操作数语法。情况似乎并非如此。实际上,我没有看到任何接受带括号的表达式(例如 2 * (3 + 4)
)的产生式,而且我不知道您如何期望表达式包含函数调用。
您可能应该决定是否使用优先级声明,并且始终如一地使用(这通常更容易)或者根本不使用。回顾你关于这个主题的课程 material 可能会有帮助;如果没有,网上有很多例子。
我收到 20 shift/reduce 冲突错误。我通过单独声明来处理运算符的优先级。我不确定 exprList 和 propertyList,我尝试了它们的不同版本,但错误不会改变。
%#include<studio.h>
void yyerror( const char *s)
{
printf("%s\n",s);
}
%}
%token tFOR tIN tFUNCTION tSEMICOLON tLPAR tLBRKT tLBRACE tCOLON tINT
tREAL tSTRING tWHILE tVAR tELSE tCOMMA tRPAR tRBRKT tRBRACE tEQ tNOT tIF
tIDENT
%token tGT
%token tLT
%token tEQCHECK
%left tPLUS tMINUS
%left tSTAR
%%
statementList:statement|statementList statement | statementList
tSEMICOLON statement;
statement: assign | if | expr |statementBlock | while |for | functionCall
| functionDeclaration;
assign: tIDENT tEQ expr | tVAR tIDENT tEQ expr;
if: ifPart elsePart;
ifPart: tIF tLPAR expr tRPAR statementBlock;
elsePart: tELSE statementBlock;
while: tWHILE tLPAR expr tRPAR statementBlock;
for: tFOR tLPAR tVAR tIDENT tIN expr tRPAR statementBlock | tFOR tLPAR
expr tRPAR statementBlock;
functionDeclaration: tFUNCTION tIDENT tLPAR exprList tRPAR statementBlock
| tFUNCTION tIDENT tLPAR tRPAR statementBlock;
statementBlock: tLBRACE statementList tRBRACE;
functionCall:tIDENT tLPAR exprList tRPAR | tIDENT tLPAR tRPAR;
expr: tIDENT | tSTRING |tLBRKT tRBRKT | tLBRKT exprList tRBRKT
|tLBRACE tRBRACE | tLBRACE propertyList tRBRACE | tNOT expr |
expr tPLUS term | expr tMINUS term | term |
expr tEQCHECK expr | expr tLT expr | expr tGT expr;
exprList: expr | exprList tCOMMA expr;
propertyList: tIDENT tCOLON expr
| propertyList tCOMMA tIDENT tCOLON expr;
term:term tSTAR factor | factor;
factor: tREAL| tINT;
%%
%token
不声明运算符的优先级值。所以 tLT
、tGT
和 tEQCHECK
没有优先声明。 (我后来意识到 tNOT
也没有。)
另一方面,您已经声明了 tPLUS
、tMINUS
和 tSTAR
的优先级,但这些定义是不必要的(也未使用),因为您的语法已经明确了它们的含义优先级。
但是,我认为您对 factor
的定义有误:它位于优先链的底部,因此它应该包括所有操作数语法。情况似乎并非如此。实际上,我没有看到任何接受带括号的表达式(例如 2 * (3 + 4)
)的产生式,而且我不知道您如何期望表达式包含函数调用。
您可能应该决定是否使用优先级声明,并且始终如一地使用(这通常更容易)或者根本不使用。回顾你关于这个主题的课程 material 可能会有帮助;如果没有,网上有很多例子。