解析树和AST有什么区别?


90

它们是在编译过程的不同阶段生成的吗?还是它们只是同一事物的不同名称?


语法分析树是您的语法及其人工产物的结果(您可以为同一种语言编写无限的语法),AST可以将语法分析树尽可能地缩小到与该语言最接近的程度。同一语言的几种语法将提供不同的语法分析树,但应产生相同的AST。(您也可以将不同的脚本(同一语法的不同分析树)减少到相同的AST)
Guillaume86

1
这样的SO答案将详细讨论差异:stackoverflow.com/a/1916687/120163
Ira Baxter

Answers:


95

这基于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)

解析树

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

解析树

AST

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

AST

有关详细的解释,请参见编译器和编译器生成器 pg。第23页
摘要语法树编程语言的语法和语义中的 21


5
您如何从解析树中导出AST?将解析树简化为AST的方法是什么?
CMCDragonkai 2015年

3
没有特定的算法可以从解析树中导出AST。AST的使用更多是个人喜好,但必须包含足够的信息才能完成任务。我通过使用ANTLR从AST中排除了parens 语法中的运算符,因为它们不是必需的,但默认情况下,ANTLR会将它们包括在内。我认为解析树为您提供了一切,无论您是否需要它,而AST则为您提供了最低要求。请记住,您将经常遍历树木,因此大小很重要。
Guy Coder

2
您是说像CST(具体语法树)还是AST(抽象语法树)?
CMCDragonkai

解析器或解析器生成器的语法文件中嵌入的语义动作/规则是语义分析和创建AST的常用方式,而解析树很少(如果曾经由用户代码构造或使用过),除非用于解析器正确性验证。

有趣的是:抽象语义图
Guy Coder

16

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

我发现这个页面,它试图解决这一确切的问题。


11

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


4

取Pascal作业Age:= 42;

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

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

分配成为一个节点,其中包含2个元素,即Age和42。想法是您可以执行分配。

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.