解析树和抽象语法树之间有什么区别?

时间:2011-05-11 16:55:55

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

我在编译器设计书中找到了这两个术语,我想知道每个术语的含义,以及它们的不同之处。

我在互联网上搜索,发现解析树也称为具体语法树(CST)。

5 个答案:

答案 0 :(得分:29)

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

编辑

如需更多解释,请参阅P.D.的Compilers and Compiler Generators。特里pg。 23.另请参阅作者home page了解更多项目,例如源代码。

答案 1 :(得分:14)

在编译器构造的上下文中,解释了解析树(具体语法树,CST)和抽象语法树(ASTs)。它们是类似的数据结构,但它们的构造方式不同,用于不同的任务。

解析树

解析树通常是在词法分析之后的下一步生成的(它将源代码转换为一系列令牌,可以被视为有意义的单位,而不仅仅是一系列字符)。

它们是树状数据结构,显示了如何通过所讨论语言的语法生成输入的终端字符串(源代码令牌)。解析树的根是语法的最通用符号 - 起始符号(例如,语句),内部节点表示起始符号扩展到的非终结符号(可包括开头)符号本身),例如表达式语句 term 函数调用。叶子是语法的终端,实际符号在语言/输入字符串中表示为标识符,关键字和常量,例如, 9 如果

虽然解析编译器也会执行各种检查以确保语法的正确性 - 并且语法错误报告可以嵌入到解析器代码中。

对于简单的任务,例如将中缀表达式转换为后缀表达式,它们可用于通过语法导向定义或转换方案进行语法导向转换。

这是表达式9 - 5 + 2的解析树的图形表示(注意树中终端的位置和表达式字符串中的实际符号):

enter image description here

抽象语法树

AST表示某些代码的语法结构。编程结构的树,如表达式,流控制语句等 - 分为运算符(内部节点)和操作数(叶子)。例如,表达式i + 9的语法树将以操作符+作为根,变量i作为运算符的左子项,数字9作为右侧子。

这里的区别在于非终结符和终端不起作用,因为AST不处理语法和字符串生成,而是编程构造,因此它们表示这些结构之间的关系,而不是它们的生成方式通过语法。

请注意,运算符本身是给定语言的编程结构,并且不必是实际的计算运算符(如+那样):for循环也将以这种方式处理。例如,您可以使用语法树,例如for [ expr, expr, expr, stmnt ](内联表示),其中for运算符,方括号内的元素是其子元素(表示C的for语法) - 也由运算符等组成。

AST通常由语法分析(解析)阶段的编译器生成,稍后用于语义分析,中间表示,代码生成等。

这是AST的图形表示:

enter image description here

答案 2 :(得分:5)

AST在概念上描述了源代码,它不需要包含解析某些源代码所需的所有语法元素(花括号,关键字,括号等)。

Parse树更紧密地代表源代码。

在AST中,IF语句的节点只能包含三个子节点:

  • 条件
  • If Case
  • 其他案例

对于类C语言,Parse Tree需要包含'if'关键字,括号,花括号的节点。

答案 3 :(得分:3)

我在网上发现了这个,也许有用:

  

解析树是用于匹配某些规则(和令牌)的记录   输入文本,而语法树记录输入的结构   并且对产生它的语法不敏感。请注意那里   对于任何单一语言都是无限数量的语法,因此   每个语法都会为给定的结果生成不同的解析树形式   因为所有不同的中间规则而输入句子。一个   抽象语法树是一种非常优秀的中间形式   因为这种不敏感,因为它突出了结构   语言而不是语法。

答案 4 :(得分:0)

维基百科说

  

Parse树具体反映了输入语言的语法,使它们与计算机编程中使用的抽象语法树不同。

Quora的答案说

  

解析树是用于匹配某些输入文本的规则(和标记)的记录,而语法树记录输入的结构,并且对生成它的语法不敏感。

结合以上两个定义,

Abstract Syntax Tree逻辑地描述了解析树。它不需要包含解析某些源代码所需的所有语法结构(空格,大括号,关键字,括号等)。这就是为什么Parse Tree也称为Concrete Syntax Tree,而AST被称为Syntax TreeNumber |MobileNumber|FirstName|LastName|Voucher|MessageContent|MessageStatus --------+------------+---------+--------+-------+--------------+------------- 340046 |1158963214 |trisha |govender|NULL |Hello | 0 354252 |1124589630 |Peter |Ngcobo |NULL |Hello | 0 385603 |2587465974 |Chris |Pat |NULL |Hello | 0 385674 |1256559878 |chris |pat |NULL |Hello | 0 385679 |4485484656 |john |doe |NULL |hello | 0 因此,语法分析器的输出实际上是语法树。