当语法错误发生时,是否存在生成“预期令牌”列表的已知方法?我使用Lemon作为解析器生成器。
答案 0 :(得分:9)
这似乎有效:
%syntax_error {
int n = sizeof(yyTokenName) / sizeof(yyTokenName[0]);
for (int i = 0; i < n; ++i) {
int a = yy_find_shift_action(yypParser, (YYCODETYPE)i);
if (a < YYNSTATE + YYNRULE) {
printf("possible token: %s\n", yyTokenName[i]);
}
}
}
它会尝试所有可能的令牌并打印那些适用于当前解析器状态的令牌。
请注意,当出现错误的令牌时,解析器不会立即调用syntax_error,但它会尝试减少堆栈上的内容,希望之后可以移动令牌。只有当其他任何东西都无法减少且当前令牌无法移动时,解析器才会调用syntax_error。减少将改变解析器状态,这意味着您可能会看到比减少之前适用的令牌更少的令牌。但它应该足以进行错误报告。
答案 1 :(得分:1)
在Lemon中没有直接的方法来生成这样的列表。但是你可以尝试使用Lemon工具的调试输出和调试生成的解析器的跟踪。调用ParseTrace函数后,生成的解析器打印Shifts和Reduces列表,它适用于输入流。语法错误之前的最后一次Shift包含错误之前的当前状态数。在* .out文件中为您的解析器找到此状态,并查看它的预期令牌列表。