使用柠檬解析器生成器的“预期令牌”

时间:2012-07-29 00:30:22

标签: parsing generator lemon

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

2 个答案:

答案 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文件中为您的解析器找到此状态,并查看它的预期令牌列表。