grammar - 如何在编译器内编码 FIRST 和 FOLLOW 集

标签 grammar recursive-descent compiler-construction

我正在为我正在学习的编译器设计类(class)编写一个编译器,目前我正在语法分析中,我需要编写一个解析器。

我需要 FIRST 和 FOLLOW 集来处理源文本中可能出现的任何错误。我已经预先计算了语法中所有非终结符的 FIRST 和 FOLLOW 集,但我无法决定在程序中实际编码它们的位置。

我应该将它们放在一个映射中,其中键是非终端的名称吗?

任何建议都会有帮助

这篇文章可能看起来有点不清楚,如果需要的话我可以澄清任何要点。

最佳答案

如果你想保留它们,你需要将它们附加到它们代表的非终结符上。您可能还需要一个反转,例如,从集合成员返回到它们是第一个或后续的非终结符的映射。

然后,您的错误恢复例程可以使用上一个或更可能的“下一个”输入标记(即导致您报告错误的输入标记)来决定您可以将哪些内容插入到输入流中。

我实际上并不存储这些。我使用 GLR 解析器,其解析表本质上是 LALR 解析表,并简单地构建一个递归算法来爬行表以查看哪些标记可能允许解析器继续进行。我间接地利用了 FIRST 和 FOLLOW,因为它们被用来构造解析表。

如果您正在学习编译器设计类(class),我建议您重点关注解析后问题。您可能会花费大量时间尝试“修补”源代码以响应错误,而您将了解到的只是a)这很困难,b)没有人会特别喜欢您提供的选择。你可以把精力花在语法修复上,直到你脸色发青,但我会等到有人要求你这样做。同时,对于编译器类,我会让编译器简单地说“第 N 行有语法错误”并中止。 虽然很糟糕,但足以让你继续更有趣的部分。

关于grammar - 如何在编译器内编码 FIRST 和 FOLLOW 集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9753282/

相关文章:

parsing - LL 和递归下降解析器之间的区别?

c++ - C 编译器可以重新排列堆栈变量吗?

javascript - 将 Fortran 语言转换为 Javascript

ANTLR 用于可选键值

java - java中动态追加语音识别的语法文件

c++ - 解析完全括号表达式

c++ - 在 Visual C++ 中使用预编译 header 的最不显眼的方式是什么?

_Atomic 类型说明符和限定符之间的 C11 语法歧义

python - 我的语法或解析器生成工具是否存在错误?

parsing - 是否可以使用递归下降解析器来验证语法并同时构建解析树?