问题描述
我得到以下运行野牛解析器的输出: Bison parser output on a file
在上图中,我给出了使用 bison 生成的 compile 可执行文件,并提供了 Syntax5.txt 。 如果您看到它在=> 2时捕获了错误;适当地 它应该类似于1 => 2时; 但是在它下面还有一个缺少该文字的情况。由于某种原因,它没有选择它。错误总数应为5,显示为4。
这可能是什么原因。 这是我正在使用的parser.y文件。这与我定义语法的方式有关。
%{
#include <string>
using namespace std;
#include "listing.h"
int yylex();
void yyerror(const char* message);
%}
%define parse.error verbose
%token IDENTIFIER
%token INT_LIteraL
%token ADDOP MULOP RELOP ANDOP
%token IF BOOL_LIteraL ARROW EXPOP REMOP OROP NOTOP CASE
%token ELSE ENDCASE ENDIF OTHERS REAL THEN WHEN REAL_LIteraL
%token BEGIN_ BOOLEAN END ENDREDUCE FUNCTION INTEGER IS REDUCE RETURNS
%%
function:
function_header variable body ;
function_header:
FUNCTION IDENTIFIER RETURNS type ';' |
FUNCTION IDENTIFIER parameters RETURNS type ';' |
error ';';
variable:
IDENTIFIER ':' type IS statement_ variable |
;
parameters: parameter |
parameter ',' parameters |
;
parameter: IDENTIFIER ':' type ;
type:
INTEGER |
REAL |
BOOLEAN ;
body:
BEGIN_ statement_ END ';' ;
statement_:
statement ';' |
error ';' ;
statement:
REDUCE operator reductions ENDREDUCE |
IF expression THEN statement_ ELSE statement_ ENDIF |
expression |
CASE expression IS when OTHERS ARROW statement_ ENDCASE
;
when: WHEN INT_LIteraL ARROW expression ';'|
when WHEN INT_LIteraL ARROW expression ';' |
error ';'|
;
operator:
ADDOP |
MULOP ;
reductions:
reductions statement_ |
;
expression:
expression OROP expression2 |
expression2;
;
expression2:
expression2 ANDOP expression3 |
expression3;
;
expression3: NOTOP expression3 |
expression4
;
expression4: relation;
relation:
relation RELOP term |
term;
term:
term ADDOP factor |
factor ;
factor:
factor MULOP factor2 |
factor REMOP factor2 |
factor2;
factor2:
factor3 EXPOP factor2 |
factor3
;
factor3: primary;
primary:
'(' expression ')' |
INT_LIteraL |
BOOL_LIteraL |
REAL_LIteraL |
IDENTIFIER ;
%%
void yyerror(const char* message)
{
appendError(Syntax,message);
}
int main(int argc,char *argv[])
{
firstLine();
yyparse();
lastLine();
return 0;
}
解决方法
野牛像yacc一样,在错误恢复后会抑制前三个令牌的错误消息。这样可以避免由于恢复不精确而导致的一系列错误。
您可以使用yyerrok
宏重新启用错误报告,但只能在操作的上下文中。 (因此,不能在yyerror
的定义中使用它。)解析器动作通常是错误恢复动作;也就是说,包含error
伪令牌的生产操作。
有关如何编写错误恢复结果的更多信息和示例,请参见error recovery chapter of the bison manual。