Compiler construction 什么';解析树和AST之间的区别是什么?

Compiler construction 什么';解析树和AST之间的区别是什么?,compiler-construction,terminology,compiler-theory,abstract-syntax-tree,parse-tree,Compiler Construction,Terminology,Compiler Theory,Abstract Syntax Tree,Parse Tree,它们是由编译过程的不同阶段生成的吗?或者它们只是同一事物的不同名称?据我所知,AST更关注源代码组件之间的抽象关系,而解析树则关注该语言使用的语法的实际实现,包括挑剔的细节。它们肯定不一样,因为“解析树”的另一个术语是“具体语法树” 我发现了这一点,试图解决这个确切的问题。马丁·福勒的文章很好地解释了这一点。AST只包含将用于进一步处理的所有“有用”元素,而解析树包含您解析的原始文档中的所有工件(空格、括号等)这是基于Terrence Parr的语法 本例的语法: grammar Expr002

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

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

我发现了这一点,试图解决这个确切的问题。

马丁·福勒的文章很好地解释了这一点。AST只包含将用于进一步处理的所有“有用”元素,而解析树包含您解析的原始文档中的所有工件(空格、括号等)

这是基于Terrence Parr的语法

本例的语法:

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(); } ;
输入

解析树

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

AST

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

更多详细解释请参见第23页

或者在解析树的第21页,内部节点是非末端的,叶子是末端的。 在语法树中,内部节点是运算符,叶子是操作数。

接受pascal赋值 年龄:=42岁

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

抽象的树应该是这样的 [=][年龄][42]

分配成为一个节点,包含2个元素,年龄和42岁。这个想法是你可以执行任务


还要注意,pascal语法消失了。因此,可以让多种语言生成相同的AST。这对于跨语言脚本引擎非常有用。

解析树是语法及其工件的结果(您可以为同一语言编写无限多个语法),AST将解析树尽可能减少到与该语言最接近的程度。同一语言的多个语法将给出不同的解析树,但结果应该是相同的AST。(您还可以将不同的脚本(来自相同语法的不同解析树)简化为相同的AST)因此,这个答案详细讨论了数据引用:如何从解析树派生AST的可能重复?将解析树简化为AST的方法是什么?没有从解析树派生AST的特定算法。AST中的内容更多的是个人偏好,但必须包含足够的信息以完成任务。我通过在语法中使用ANTLR从AST中排除了paren,因为它们是不需要的,但是默认情况下ANTLR会包含它们。我认为解析树为您提供了一切,无论您是否需要它,而AST为您提供了最基本的功能。请记住,您将经常遍历树,因此大小很重要。您的意思是,像CST(具体语法树)与AST(抽象语法树)一样,嵌入解析器或解析器生成器语法文件中的语义操作/规则是语义分析和创建AST的常用方法,而解析树如果由用户代码构造或使用,则很少,可能除了解析器正确性验证。有趣的是:
x=1
y=2
3*(x+y)