parsing树和AST有什么区别?

它们是由编译过程的不同阶段产生的吗? 或者他们只是同一个事物的不同名称?

这是基于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(); } ; 

input

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

parsing树

分析树是input的具体表示。 parsing树保留了input的所有信息。 空框表示空白,即行结束。

解析树

AST

AST是input的抽象表示。 请注意,parens不存在于AST中,因为这些关联可以从树结构中导出。

AST

有关更多的解释,请参见编译器和编译器生成器页。 23
或pg上的抽象语法树 。 21 程序devise语言的语法和语义

据我所知,AST更多地关注源代码组件之间的抽象关系,而parsing树着重于语言所使用的语法的实际实现,包括细节的细节。 它们绝对不一样,因为“parsing树”的另一个术语是“具体语法树”。

我发现这个网页试图解决这个确切的问题。

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

以帕斯卡作业年龄:= 42;

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

一棵抽象树会像这样[=] [Age] [42]

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

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

在parsing树内部节点是非terminal的,叶子是terminal。 在语法树内部节点是运算符,叶子是操作数。