bison - 我必须手动修复 Yacc 中的移位/减少问题吗?
问题描述
我最难尝试消除语法中的两个移位/减少问题。我无法在任何地方找到解决方案。我看到 Yacc 显然更喜欢这种转变,但如果是这样,那为什么我的不编译呢?我知道其中一个问题是悬空的 if-else,但另一个我不知道。我希望 Yacc 为我处理它。错误消息说2 shift reduce conflicts
void yyerror (char *s);
#include <stdio.h>
#include <stdlib.h>
int yylex();
extern int yytext[];
extern FILE *yyin;
%}
%start program
%token LTE GTE BEQUALS NOTEQUALS BEGCOMMENT ENDCOMMENT COMMENT GREATER LESS COMMA PLUS SUB MULT DIV EQUAL LP RP LB RB LC RC SEMICOLON INT FLOAT VOID IF WHILE RETURN ID NUM
%nonassoc IFX
%nonassoc ELSE
%%
program : declaration_list { printf("\nACCEPT\n"); };
declaration_list : declaration_list declaration
| declaration
;
declaration : var_declaration
| fun_declaration
;
var_declaration : type_specifier ID SEMICOLON
| type_specifier ID LB NUM RB SEMICOLON
;
type_specifier : INT
| VOID
;
fun_declaration : type_specifier ID LP params RP compound_stmt ;
params : param_list | VOID ;
param_list : param_list COMMA param
| param
;
param : type_specifier ID
| type_specifier ID LB RB
;
compound_stmt : LC local_declarations statement_list RC
;
local_declarations : local_declarations var_declaration
| /* empty */ ;
statement_list : statement_list statement
| /* empty */ ;
statement : expression_stmt
| compound_stmt
| selection_stmt
| iteration_stmt
| return_stmt ;
expression_stmt : expression SEMICOLON
| SEMICOLON
;
selection_stmt : ifsubroutine statement
| ifsubroutine statement ELSE
;
ifsubroutine : IF LP expression RP
;
iteration_stmt : whilesubroutine LP expression RP statement
;
whilesubroutine : WHILE ;
return_stmt : RETURN SEMICOLON
| RETURN expression SEMICOLON
;
expression : var EQUAL expression
| simple_expression
;
var : ID
| ID LB expression RB
;
simple_expression : additive_expression relop additive_expression
| additive_expression
;
relop : LTE | LESS | GREATER | GTE | EQUAL| NOTEQUALS ;
additive_expression : additive_expression addop term
| term
;
addop : PLUS
| SUB
;
term : term mulop factor
| factor
;
mulop : MULT
| DIV
;
factor : LP expression RP
| var
| call
| NUM
;
call : ID LP args RP
;
args : arg_list | /* empty */ ;
arg_list : arg_list COMMA expression
| expression
;
%%
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
if (!yyin)
{
printf("no file\n");
exit(0);
}
yyparse();
}
void yyerror(char *s)
{
printf("\nREJECT\n");
// printf("error from yyerror\n");
exit(0);
}
int yywrap()
{
// printf("in yywarp\n");
exit(0);
}```
解决方案
您的yywrap()
实现调用exit()
. 这意味着一旦扫描仪看到文件结尾,应用程序就会终止。因此解析器将无法完成其工作。
通常,您应该%option noyywrap
在 (f)lex 文件中使用,以避免需要提供yywrap
. 或者使用-lfl
. 但是如果你坚持要实现它,它应该返回 1 表示没有什么要读的了。
另外,extern int yytext[];
是不必要的,因为您没有yytext
在解析器中引用任何地方。而且您不应该yytext
在解析器中引用;这种用法几乎总是一个错误。但是,如果您确实使用yytext
了,则声明将是错误的:它是指向(不是)的指针char
(不是数组int
)。您的 C 编译器可能不会标记该错误。
推荐阅读
- javascript - 如何从 java 脚本对象中获取值的键?
- python - 如何编写一个无限循环来接收UDP数据?
- r - 隔离协变量
- php - 将 laravel 用户创建数据传递到存储过程
- css - 在另一个 flex 中对齐 flex
- pandas - 如何在除交叉表之外的 Pandas 中进行 groupby 语句
- c++ - 在主文件中声明命名空间不会延续到头文件:“使用命名空间标准;”
- java - 为什么在打印空引用时不调用覆盖的 toString
- android - 查询文档时,任务在 Firestore 中重复
- python - UnicodeDecodeError:“utf-8”编解码器无法解码位置 0-1 中的字节:无效的继续字节