我正在使用上下文无关语法和 Bison 和 Flex 编写一个解析器来处理包含 for 循环的简单语言。但是,当我尝试解析有效的 for 循环语句时遇到语法错误。下面是我的 .l 和 .y 文件,以及我收到的输出和错误消息。
Flex 文件(for.l):
%option noyywrap
%{
#include "for2.tab.h" // Include the header generated by Bison
%}
alpha [A-Za-z]
digit [0-9]
%%
[ \t\n] ; // Ignore whitespace
for return FOR;
printf return ID;
{digit}+ { yylval = atoi(yytext); return NUM; }
{alpha}({alpha}|{digit})* { return ID; }
\"([^\\\"]|\\.)*\" { return STRING; }
"++" return INC;
"--" return DEC;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
[-+*/()=<>!;{},%] return yytext[0];
. { fprintf(stderr, "Unrecognized character: %s\n", yytext); }
%%
野牛文件(for.y):
%{
#include <stdio.h>
#include <stdlib.h>
int yylex(void);
void yyerror(const char *s) {
fprintf(stderr, "Error: %s\n", s);
}
%}
%token ID NUM FOR STRING
%token LE GE EQ NE OR AND
%token INC DEC
%left OR
%left AND
%left EQ NE
%left '<' '>' LE GE
%%
Program : Statement { printf("Input accepted\n"); exit(0); }
;
Statement : ForStatement
| Expression ';'
| FunctionCall ';'
;
ForStatement: FOR '(' AssignmentExpression ';' LogicalExpression ';' IncrementExpression ')' Block
;
Block : '{' StatementList '}'
| Statement
| /* empty */
;
StatementList : StatementList Statement
| Statement
;
Expression : AssignmentExpression
| ArithmeticExpression
;
AssignmentExpression
: ID '=' ArithmeticExpression
;
ArithmeticExpression
: ArithmeticExpression '+' Term
| ArithmeticExpression '-' Term
| Term
;
Term : Term '*' Factor
| Term '/' Factor
| Factor
;
Factor : '(' ArithmeticExpression ')'
| ID
| NUM
| '-' Factor
;
IncrementExpression
: ID INC
| ID DEC
| AssignmentExpression
;
LogicalExpression
: LogicalExpression OR LogicalTerm
| LogicalTerm
;
LogicalTerm : LogicalTerm AND LogicalFactor
| LogicalFactor
;
LogicalFactor
: RelationalExpression
| '!' LogicalFactor
| '(' LogicalExpression ')'
;
RelationalExpression
: ArithmeticExpression '<' ArithmeticExpression
| ArithmeticExpression '>' ArithmeticExpression
| ArithmeticExpression LE ArithmeticExpression
| ArithmeticExpression GE ArithmeticExpression
| ArithmeticExpression EQ ArithmeticExpression
| ArithmeticExpression NE ArithmeticExpression
;
FunctionCall: ID '(' ArgumentList ')'
;
ArgumentList: Expression
| ArgumentList ',' Expression
| STRING
| /* empty */
;
%%
int main() {
printf("Enter the expression:\n");
yyparse();
return 0;
}
输出和错误:
当我尝试解析以下输入时:
for ( i = 0 ; i < 5 ; i++ ) { a = a + i; }
我得到以下输出:
Enter the expression:
for ( i = 0 ; i < 5 ; i ++ ) { a = a + i; }
(null) = 0
Error: syntax error
运行以下命令时:
bison -dv for2.y
我明白:
for2.y: conflicts: 5 shift/reduce
我的问题: 我不明白为什么解析器会抛出语法错误。 for 循环输入看起来有效,并且我已经定义了处理 for 循环和增量表达式(如 i++)所需的标记和规则。
我尝试了各种更改,但错误仍然存在。有人能指出我的语法或 Flex/Bison 设置可能有什么问题吗?任何帮助将不胜感激!
由于存在移位归约冲突,因此 LALR(1) 解析器无法识别该语法。 因此,bison 将通过在每个冲突状态中选择转移(而不是减少)来“解决”冲突,从而产生一个解析器,该解析器可以识别语法指定的语言的“子集”。 为了准确地了解正在发生的情况,您需要检查存在冲突的状态,以了解冲突的解决如何影响解析器识别事物的方式。