【问题标题】:Why is an abstract syntax tree necessary? Why cant a recursive descent parser parse as it goes?为什么需要抽象语法树?为什么递归下降解析器无法解析?
【发布时间】:2018-06-24 00:15:43
【问题描述】:

我是解释器设计的初学者,在学习了一点语言设计(语法、语言、词法分析器、解析器)之后,我不明白为什么解析器需要构建一个抽象语法树作为它去了。为什么不直接使用递归调用的函数来执行操作呢。

这是我发现的最简单的例子。 https://www.youtube.com/watch?v=N55XNj8KjC4.

【问题讨论】:

  • 这并不总是必要的,您可以为某些语言编写编译器而无需编译器,尤其是对于解释性目标。但是,当您想要优化时,您就开始需要一个。
  • 重新标题问题:递归下降解析器确实“按原样解析”。您似乎要问的是:为什么它不能执行
  • 事实上,在过去糟糕的日子里,一些编译器确实确​​实在运行时发出代码(使用智能汇编器或回补分支到尚未生成的机器代码)。此类编译器的机器代码质量普遍较差。
  • 你说的例子不是编译器。它是一个表达式求值器。
  • 这不仅仅是所谓的“糟糕的过去”。现在有编译器可以做到这一点。 @torek

标签: parsing compiler-construction interpreter


【解决方案1】:

James:您可能对 Java 很熟悉。想象一下,您的 Java 递归解析器只有源代码文本,没有其他内容……它看到文本“x+y”。它究竟应该执行哪些操作?

您需要的不仅仅是 AST;您还需要符号表、从代码片段到范围的映射以及存储变量值的位置。如果您遵循@EJP 的思路,如果您想要聪明的答案/更快的解释器(例如每次遇到符号表时不要在符号表中查找标识符),则需要缓存一堆关于代码结构和标识符含义的事实.

一旦你同意你必须缓存一些信息以使你的“解释器”更有效率,唯一的争论是关于要缓存的东西的种类。 AST 会缓存解析文本的结果,因此您不必每次都解析它。想象一下在每次迭代中解析内部循环的源代码;你会有一个异常缓慢的解释器。

所有其他的东西基本上也是对所提供文本的推理结果的缓存。但在尝试使您的语言处理器足够高效以在实践中使用时,它们确实很有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 2011-08-20
    • 2016-10-28
    相关资源
    最近更新 更多