擅长:python、mysql、java
<p>当您需要在一个模块中生成一个树,并在另一个模块中输入相同的树(或者几乎相同的树,以某种方式优化)时,可以使用ASDL。在</p>
<p>为此,你需要有构造的功能(最好是用类型检查器),打印树的功能,这样你就可以确定你生成的树是正确的。在</p>
<p>ASDL将一些树作为输入,这些树的语法与代数数据类型(如haskell或ml)的语法几乎相同,或BNF中的语法更为简化,并自动生成所有的构造器,从树的简单描述开始打印函数。在</p>
<p>例如,如果您有一个lexer,它将必须生成具有类型的lexem。您还需要查看词素的输出流(这是线性形式,因此是一个非常简单的树)。与其编写用于打印、构造词素的函数,不如像这样定义它们</p>
<pre><code> lexeme=
ID(STRING)
| INT(num_integer)
| FLOAT(num_float)
attributes(int coord_x, int coord_y)
num_integer:
....
num_float:
....
</code></pre>
<p>从lexer调用构造函数ID、INT、FLOAT等。ASDL将在您需要的所有函数中转换这个简单语法,或者为AST构造节点,或者打印,或者您需要的任何东西。ASDL不对生成的代码施加限制。在</p>
<p>如果将<code>attributes</code>添加到某个类型,例如令牌的坐标,则此类属性将附加到该类型的每个构造函数的参数中。在</p>
<p>由解析器创建的更复杂的树应该是这样的</p>
^{pr2}$
<p>在本例中,asdl将检查解析器对SUM(\uu)的调用是否会传递给使用expr的一个构造函数创建的SUM节点。<code>num_integer</code>是在外部定义的,可能是由lexer的asdl树定义的。在</p>
<p>请注意,不允许定义包含正则表达式的构造函数,例如<code>number: [0-9]+</code>。ASDL比EBNF简单。在</p>
<p>这些构造函数将被定义为,为了构建您所需要的内容,并且除此之外,它们还会进行类型检查,以确保lexer/parser/code generator输出的树符合asdl定义的语言。在</p>
<p>为了更好地理解ASDL,您需要编写3-4个解析器,看看它们生成的代码中有什么共同之处。这个公共部分实际上是ASDL,因此这是对解析器输出的抽象。在</p>