5

发生语法错误时,是否有一种已知的方法可以生成“预期令牌”列表?我使用 Lemon 作为解析器生成器。

4

2 回答 2

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。缩减将更改解析器状态,这意味着您可能会看到比缩减之前适用的令牌更少。不过,它应该足以用于错误报告。

于 2012-10-22T11:04:18.857 回答
1

在 Lemon 中没有直接的方法来生成这样的列表。但是您可以尝试使用 Lemon 工具的调试输出和生成的解析器的调试跟踪来执行此操作。在调用 ParseTrace 函数生成解析器打印 Shift 和 Reduces 列表后,它适用于输入流。语法错误之前的最后一个 Shift 包含错误之前的当前状态数。在您的解析器的 *.out 文件中找到此状态,并查看它的预期标记列表。

于 2012-08-07T13:13:45.313 回答