【问题标题】:Zephyr ASDL (Abstract Syntax Description Language)Zephyr ASDL(抽象语法描述语言)
【发布时间】:2012-01-15 20:30:30
【问题描述】:

问题:

什么是 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 的目的是什么(在编译过程的上下文中),然后再试一次。

【问题讨论】:

    标签: python syntax compiler-construction definition asdl


    【解决方案1】:

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

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

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

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

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

    【讨论】:

      【解决方案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,因此这是特别是解析器输出的抽象。

      【讨论】:

        【解决方案3】:

        你的问题是关于具体语法抽象语法的区别。

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-05-08
          • 1970-01-01
          • 2011-02-22
          • 1970-01-01
          • 1970-01-01
          • 2019-08-08
          • 1970-01-01
          相关资源
          最近更新 更多