解析树和AST有什么区别?

时间:2011-02-17 08:19:19

标签: compiler-construction terminology compiler-theory abstract-syntax-tree parse-tree

它们是否由编译过程的不同阶段生成?或者它们只是同一个东西的不同名称?

5 个答案:

答案 0 :(得分:87)

这是基于Terrence Parr的Expression Evaluator语法。

此示例的语法:

grammar Expr002;

options 
{
    output=AST;
    ASTLabelType=CommonTree; // type of $stat.tree ref etc...
}

prog    :   ( stat )+ ;

stat    :   expr NEWLINE        -> expr
        |   ID '=' expr NEWLINE -> ^('=' ID expr)
        |   NEWLINE             ->
        ;

expr    :   multExpr (( '+'^ | '-'^ ) multExpr)*
        ; 

multExpr
        :   atom ('*'^ atom)*
        ; 

atom    :   INT 
        |   ID
        |   '('! expr ')'!
        ;

ID      : ('a'..'z' | 'A'..'Z' )+ ;
INT     : '0'..'9'+ ;
NEWLINE : '\r'? '\n' ;
WS      : ( ' ' | '\t' )+ { skip(); } ;

输入

x=1
y=2
3*(x+y)

解析树

解析树是输入的具体表示。解析树保留输入的所有信息。空框表示空格,即行尾。

Parse Tree

AST

AST是输入的抽象表示。请注意,AST中不存在parens,因为关联可以从树结构中派生。

AST

有关详细说明,请参阅Compilers and Compiler Generators pg。 23个
或者Abstract Syntax Trees on pg。 Syntax and Semantics of Programming Languages

中的21

答案 1 :(得分:16)

根据我的理解,AST更多地关注源代码组件之间的抽象关系,而解析树则侧重于语言使用的语法的实际实现,包括挑剔的细节。它们肯定不一样,因为“解析树”的另一个术语是“具体语法树”。

我发现这个page试图解决这个问题。

答案 2 :(得分:10)

Martin Fowler的DSL book很好地解释了这一点。 AST仅包含将用于进一步处理的所有“有用”元素,而解析树包含您解析的原始文档中的所有工件(空格,括号,...)

答案 3 :(得分:4)

进行pascal分配 年龄:= 42;

语法树看起来就像源代码一样。下面我在节点周围放置括号。 [年龄] [:=] [42] [;]

抽象树看起来像这样 [=] [年龄] [42]

赋值变成一个包含2个元素的节点,Age和42.想法是你可以执行赋值。

另请注意,pascal语法会消失。因此,可以使用多种语言生成相同的AST。这对跨语言脚本引擎很有用。

答案 4 :(得分:1)

在解析树中,内部节点是非终端,叶子是终端。 在语法树中,内部节点是运算符,叶子是操作数。