bison 在检测到解析错误时不调用 yyerror
bison doesn't call yyerror when detecting a parsing error
我正在用野牛写一个解析器。我 运行 遇到一个问题,bison 检测到解析错误但没有调用 yyerror
.
这是我的脚本片段来处理 class 定义:
%{ ...
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(); }
;
class_list
: class /* single class */
{ $$ = single_Classes();
parse_results = $$; }
| class_list class /* several classes */
{ $$ = append_Classes(,single_Classes());
parse_results = $$; }
| class_list error
{
$$ = ;
}
;
/* If no parent is specified, the class inherits from the Object class. */
class : CLASS TYPEID '{' dummy_feature_list '}' ';'
{ @$ = @2;
SET_NODELOC(@2);
$$ = class_(,idtable.add_string("Object"),,
stringtable.add_string(curr_filename)); }
| CLASS TYPEID INHERITS TYPEID '{' dummy_feature_list '}' ';'
{
@$ = @2;
SET_NODELOC(@2);
$$ = class_(,,,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 和解析错误而停止
不显示第三个错误inherits的拼写错误。
我查看了调试信息。错误 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):
= nterm class_list (: )
= 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 (: )
之后,bison 检测到解析错误所以它调用 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
没有被调用。
我只是很困惑为什么会发生这种情况,因为以上三个错误几乎相同。任何帮助将不胜感激。
Chspter six of the bison manual,其中解释了错误恢复,包括此文本:
Error recovery strategies are necessarily guesses. When they guess wrong, one syntax error often leads to another.…
To prevent an outpouring of error messages, the parser will output no error message for another syntax error that happens shortly after the first; only after three consecutive input tokens have been successfully shifted will error messages resume.
正如您从跟踪中看到的,在遇到拼写错误的标记之前,只有两个标记被成功转移。
为了测试错误恢复,通常最好为每个要测试的错误使用单独的文件。或者至少用大量有效的程序文本来分隔错误。
我正在用野牛写一个解析器。我 运行 遇到一个问题,bison 检测到解析错误但没有调用 yyerror
.
这是我的脚本片段来处理 class 定义:
%{ ...
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(); }
;
class_list
: class /* single class */
{ $$ = single_Classes();
parse_results = $$; }
| class_list class /* several classes */
{ $$ = append_Classes(,single_Classes());
parse_results = $$; }
| class_list error
{
$$ = ;
}
;
/* If no parent is specified, the class inherits from the Object class. */
class : CLASS TYPEID '{' dummy_feature_list '}' ';'
{ @$ = @2;
SET_NODELOC(@2);
$$ = class_(,idtable.add_string("Object"),,
stringtable.add_string(curr_filename)); }
| CLASS TYPEID INHERITS TYPEID '{' dummy_feature_list '}' ';'
{
@$ = @2;
SET_NODELOC(@2);
$$ = class_(,,,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 和解析错误而停止
不显示第三个错误inherits的拼写错误。
我查看了调试信息。错误 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):
= nterm class_list (: )
= 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 (: )
之后,bison 检测到解析错误所以它调用 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
没有被调用。
我只是很困惑为什么会发生这种情况,因为以上三个错误几乎相同。任何帮助将不胜感激。
Chspter six of the bison manual,其中解释了错误恢复,包括此文本:
Error recovery strategies are necessarily guesses. When they guess wrong, one syntax error often leads to another.…
To prevent an outpouring of error messages, the parser will output no error message for another syntax error that happens shortly after the first; only after three consecutive input tokens have been successfully shifted will error messages resume.
正如您从跟踪中看到的,在遇到拼写错误的标记之前,只有两个标记被成功转移。
为了测试错误恢复,通常最好为每个要测试的错误使用单独的文件。或者至少用大量有效的程序文本来分隔错误。