12

问题:

什么是 Zephyr ASDL,它与其他编译器技术(如词法分析器和解析器生成器)有何关系?

(如果您相当完整,我将不胜感激,但是当它变得相当技术性时,请在网上指出其他参考资料,因为我对编译器的大部分了解来自使用 yacc 和 flex,用 C 编写一个简单的最大 munch 词法分析器,并查看起来并在线阅读东西)

问题背景:

我一直在阅读http://docs.python.org/devguide/compiler.html并且遇到了以下行:

AST 节点的规范是使用 Zephyr 抽象语法定义语言 (ASDL) 指定的。

我按照底部的引文找到: http ://www.cs.princeton.edu/research/techreps/TR-554-97 。

我对这篇文章的第一次阅读相当混乱,我希望在重试之前能够先更好地理解 ASDL 的目的是什么(在编译过程的背景下)。

4

3 回答 3

8

Lexer 和 Parser 生成器接受词位和语法的描述,并生成实现相应工件的代码。Lex 需要一个正则表达式来描述标记。解析器生成器采用各种扩展的 BNF 符号。

您引用的论文非常清楚恕我直言:ASDL 是一种用于抽象描述一组树节点(它们的类型和签名)的小语言。使用这种语言,人们可以编写(论文的作者也这样做了)一个工具,将这些描述转换为一组记录类型,您需要实现与解析器一起使用的树。所以 ADSL 有点像正则表达式和 BNF,因为它的目的是提供给生成编译器一部分的代码生成器。

一个广泛的观点是,编译器是一种非常容易理解的技术,应该能够从各个部分的描述中生成它们。Regex/BNF/ADSL 是解析阶段的关键。

理想情况下,您会喜欢目标指令集的描述语言、流分析、从抽象树到目标指令集的翻译(您提到最大咀嚼),以及描述优化的方法。然后为每个部分使用相应的工具,您可以从“规范”构建整个编译器。在这个领域实际上有很多工作;人们分别和一起完成了所有这些工作。不出所料,其中一些来自以前在普林斯顿的“Zephyr”项目(似乎那里的 Zephyr 网站现在已经死了),其目标就是做这种事情。

无论如何,请尝试在 Google Scholar 下查找“编译器生成器”。

于 2012-01-16T02:25:54.293 回答
2

当您需要在模块中生成树并在其他模块中输入相同的树(或几乎相同的树,以某种方式优化)时,使用 ASDL。

为此,您需要具有构造功能(最好使用类型检查器),打印树的功能,以便将其可视化以确保您正确生成了它。

ASDL 将一些树作为输入,其语法几乎与代数数据类型的语法(如在 haskell 或 ml 中)或 BNF 中的语法相同,但更简化,并自动生成所有构造函数,打印以一棵树的简单描述。

例如,如果您有一个词法分析器,它必须生成具有类型的词位。您还需要查看词位的输出流(这是线性形式,因此是一个非常简单的树)。无需编写用于打印、构建词位的函数,而是将它们定义为类似的东西

   lexeme=
       ID(STRING)
     | INT(num_integer)
     | FLOAT(num_float)
     attributes(int coord_x, int coord_y)
   num_integer:
     ....
   num_float:
     ....

你从你的词法分析器中调用构造函数 ID、INT、FLOAT 等。ASDL 将在您需要的所有函数中转换这种简单的语法,为 AST 构造节点,或打印,或任何您需要的。ASDL 不对生成的代码施加限制。

如果您添加attributes到一个类型,例如令牌的坐标,这些属性将附加到该类型的每个构造函数的参数中。

由解析器创建的更复杂的树看起来像这样

expr:  SUM(expr, expr)
      |PRODUCT(expr, expr)
      |number
number: num_integer

在这种情况下,asdl 将检查解析器对 SUM(__) 的调用是否将传递给使用 expr 的构造函数之一创建的 sum 节点。num_integer是在外部定义的,可能是由词法分析器的 asdl 树定义的。

请注意,您不能定义包含正则表达式的构造函数,例如number: [0-9]+. ASDL 比 EBNF 简单。

这些构造函数将被定义为构建您需要的内容,并且不仅如此,它们还会进行类型检查,以确保您的词法分析器/解析器/代码生成器输出符合 asdl 定义的语言的树。

要很好地理解 ASDL,您需要编写 3-4 个解析器并查看它们生成的代码中的共同点。该公共部分实际上是 ASDL,因此这是特别是解析器输出的抽象。

于 2016-12-06T09:54:21.347 回答
0

您的问题是关于具体语法抽象语法之间的区别。

  • 当你使用一种编程语言时,具体的语法是你知道并且需要尊重的。这个具体的语法也被解析器验证,检查你是否尊重语法语言。解析器有第二个角色,对程序员来说是隐藏的:在内存中构建一个专用的数据结构,代表您的输入源。许多算法将应用于此数据结构。这个数据结构被命名为“抽象语法树”。
  • 抽象语法:这是一组类(在面向对象范式中或在功能范式中的类型),从中详细说明了 AST。例如,您可能有一个名为“Program”的类,它捕捉了程序的本质。您还可以有一个“If”类来表示“if”语句的结构(由一个条件、一个常规主体和可能的“else”部分的第二个主体组成)。

像 Zephyr 这样的 ASDL 是关于如何为抽象语法描述这组类,而不是语法本身。

一旦类集被完全描述(甚至生成),它就可以在解析器中使用,该解析器详细说明了 AST。

于 2021-04-14T13:48:31.850 回答