Bison 解析器处理 for 循环的问题(语法错误)

问题描述 投票:0回答:1

我正在使用上下文无关语法和 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 设置可能有什么问题吗?任何帮助将不胜感激!

compiler-construction bison yacc lex context-free-grammar
1个回答
0
投票

由于存在移位归约冲突,因此 LALR(1) 解析器无法识别该语法。 因此,bison 将通过在每个冲突状态中选择转移(而不是减少)来“解决”冲突,从而产生一个解析器,该解析器可以识别语法指定的语言的“子集”。 为了准确地了解正在发生的情况,您需要检查存在冲突的状态,以了解冲突的解决如何影响解析器识别事物的方式。

© www.soinside.com 2019 - 2024. All rights reserved.