Bison 解析器不报告 case 语句中的错误
Bison parser not reporting error within case statement
我得到 运行 野牛解析器的以下输出:
Bison parser output on a file
在上图中,我给出了使用 bison 生成的 compile 可执行文件,并提供了 syntax5.txt 。
如果你看到它在 => 2 时捕获了错误;适当地
它应该类似于 when 1 => 2;
但在它下面还有一个 which 也缺少文字。它出于某种原因没有选择它。错误总数应为 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;
}
Bison 与 yacc 一样,在错误恢复后抑制前三个标记的错误消息。这避免了由于不精确的恢复而导致的级联错误。
您可以使用 yyerrok
宏重新启用错误报告,但只能在操作的上下文中使用。 (因此您不能在 yyerror
的定义中使用它。)解析器操作通常是错误恢复操作;也就是说,包含 error
伪令牌的产品的操作。
有关如何编写错误恢复产品的更多信息和示例,请参阅 error recovery chapter of the bison manual。
我得到 运行 野牛解析器的以下输出: Bison parser output on a file
在上图中,我给出了使用 bison 生成的 compile 可执行文件,并提供了 syntax5.txt 。 如果你看到它在 => 2 时捕获了错误;适当地 它应该类似于 when 1 => 2; 但在它下面还有一个 which 也缺少文字。它出于某种原因没有选择它。错误总数应为 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;
}
Bison 与 yacc 一样,在错误恢复后抑制前三个标记的错误消息。这避免了由于不精确的恢复而导致的级联错误。
您可以使用 yyerrok
宏重新启用错误报告,但只能在操作的上下文中使用。 (因此您不能在 yyerror
的定义中使用它。)解析器操作通常是错误恢复操作;也就是说,包含 error
伪令牌的产品的操作。
有关如何编写错误恢复产品的更多信息和示例,请参阅 error recovery chapter of the bison manual。