bison - 检测到解析错误时,bison 不调用 yyerror
问题描述
我正在用野牛编写解析器。我遇到了一个问题,野牛检测到解析错误但没有调用yyerror
.
这是我处理类定义的脚本片段:
%{ ...
void yyerror(char *s);
Program ast_root; /* the result of the parse */
Classes parse_results;
}%
...
%%
/*
Save the root of the abstract syntax tree in a global variable.
*/
program : class_list { @$ = @1; ast_root = program($1); }
;
class_list
: class /* single class */
{ $$ = single_Classes($1);
parse_results = $$; }
| class_list class /* several classes */
{ $$ = append_Classes($1,single_Classes($2));
parse_results = $$; }
| class_list error
{
$$ = $1;
}
;
/* If no parent is specified, the class inherits from the Object class. */
class : CLASS TYPEID '{' dummy_feature_list '}' ';'
{ @$ = @2;
SET_NODELOC(@2);
$$ = class_($2,idtable.add_string("Object"),$4,
stringtable.add_string(curr_filename)); }
| CLASS TYPEID INHERITS TYPEID '{' dummy_feature_list '}' ';'
{
@$ = @2;
SET_NODELOC(@2);
$$ = class_($2,$4,$6,stringtable.add_string(curr_filename));
}
;
测试文件如下:
(* no error *)
class A {
};
(* error 1: b is not a type identifier *)
Class b inherits A {
};
(* error 2: a is not a type identifier *)
Class C inherits a {
};
(* error 3: keyword inherits is misspelled *)
Class D inherts A {
};
(* error 4: closing brace is missing *)
Class E inherits A {
;
运行结果如下图:
“bad.cl”,第 15 行:OBJECTID = b 处或附近的语法错误
“bad.cl”,第 19 行:OBJECTID = a 处或附近的语法错误
“bad.cl”,第 28 行:';' 处或附近的语法错误
由于 lex 和解析错误,编译停止
不显示第三个继承拼写错误的错误。
我检查调试信息。错误2就像:
Stack now 0
Entering state 3
Reading a token: Next token is token CLASS (: )
Shifting token CLASS (: )
Entering state 1
Reading a token: Next token is token TYPEID (: )
Shifting token TYPEID (: )
Entering state 5
Reading a token: Next token is token INHERITS (: )
Shifting token INHERITS (: )
Entering state 9
Reading a token: Next token is token OBJECTID (: )
"bad.cl", line 19: syntax error at or near OBJECTID = a
Error: popping token INHERITS (: )
Stack now 0 3 1 5
Error: popping token TYPEID (: )
Stack now 0 3 1
Error: popping token CLASS (: )
Stack now 0 3
Shifting token error (: )
Entering state 7
Reducing stack by rule 4 (line 165):
$1 = nterm class_list (: )
$2 = token error (: )
-> $$ = nterm class_list (: )
Stack now 0
Entering state 3
Next token is token OBJECTID (: )
Error: discarding token OBJECTID (: )
Shifting token error (: )
我看到之后Reading a token: Next token is token OBJECTID (: )
,野牛检测到解析错误,因此它调用yyerror
并打印"bad.cl", line 19: syntax error at or near OBJECTID = a
但是错误3的信息是这样的:
Stack now 0
Entering state 3
Reading a token: Next token is token CLASS (: )
Shifting token CLASS (: )
Entering state 1
Reading a token: Next token is token TYPEID (: )
Shifting token TYPEID (: )
Entering state 5
Reading a token: Next token is token OBJECTID (: )
Error: popping token TYPEID (: )
Stack now 0 3 1
Error: popping token CLASS (: )
Stack now 0 3
Shifting token error (: )
Entering state 7
显然,当遇到 时Reading a token: Next token is token OBJECTID (: )
,bison 检测到错误但没有打印错误消息,因此yyerror
没有调用。
我只是很困惑为什么会发生这种情况,因为上述三个错误几乎相同。任何帮助,将不胜感激。
解决方案
解释错误恢复的野牛手册第六章包括以下文本:
错误恢复策略必然是猜测。当他们猜错时,一个语法错误通常会导致另一个......</p>
为了防止错误消息的大量涌现,解析器不会为在第一个语法错误之后不久发生的另一个语法错误输出错误消息;只有在三个连续的输入令牌成功转移后,错误消息才会恢复。
从跟踪中可以看出,在遇到拼写错误的标记之前,只有两个标记已成功移动。
对于测试错误恢复,通常最好为每个要测试的错误使用单独的文件。或者至少将错误与大量有效的程序文本分开。
推荐阅读
- jquery-ui-datepicker - 法语语言的jQuery datepicker中的屏蔽输入问题
- sql - 选择 Union ALL...哪一个以及如何
- python - tf.keras.backend.random_normal 的问题?
- android - androidx.camera.view.CameraView 如何检测相机是否有闪光灯/手电筒?
- android - 使用 adb connect 将设备列为未经授权的设备
- debugging - Testcafe:选择器的评估器/调试器
- javascript - 如何通过 ssh2 Node.js 模块(在 Electron 应用程序中)使用 SFTP 一次下载/上传多个文件?
- vue.js - 如何使用 Vuetify/Vue.js 绑定到我的输入上的数组?
- php - Laravel 5.8 Symlink 没有链接
- python - 用 4300 万行文本文件的计数创建字典的更简单方法?