parsing树和抽象语法树有什么区别?

我在一本编译器devise书中find了这两个术语,我想知道它们各自的含义,以及它们的不同之处。

我在互联网上search,发现parsing树也被称为具体语法树(CST)。

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

编辑

有关更多的解释,请参阅PD 编译器和编译器生成器 。 23.另请参阅作者主页以获取更多项目,例如源代码。

下面是在编译器构build的上下文中对parsing树 (具体语法树,CST)和抽象语法树 (AST)的解释。 它们是相似的数据结构,但它们构造不同,用于不同的任务。

parsing树木

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

它们是树形数据结构,显示input的terminalstring(源代码标记)是如何由所述语言的语法生成的。 分析树的根是语法的最一般的符号 – 起始符号(例如语句 ),内部节点代表起始符号扩展到的非终止符号(可以包括起始符号本身),例如expression式声明术语函数调用 。 叶子是语法的terminal,在语言/inputstring中显示为标识符,关键字和常量的实际符号,例如, 9if等等

parsing编译器还执行各种检查以确保语法的正确性 – 并且可以将语法错误报告embedded到parsing器代码中。

通过语法导向的定义或翻译scheme,可以将它们用于语法指导的翻译,例如将中缀expression式转换为后缀expression式。

下面是expression式9 - 5 + 2的parsing树的graphics表示(注意树中terminal的位置以及expression式string中的实际符号):

在这里输入图像说明

抽象语法树

AST表示一些代码的语法结构 。 程序devise树,如expression式,stream程控制语句等 – 分组成运算符(内部节点)和操作数(叶)。 例如,expression式i + 9的语法树将以操作符+作为根,variablesi作为操作符的左侧子元素,数字9作为右侧子元素。

这里的区别在于,非终结者和terminal不起作用,因为AST不处理语法和string生成,而是编程构造,因此它们表示这样的构造之间的关系,而不是它们由语法生成的方式。

请注意,操作符本身是给定语言的编程结构,并不一定是实际的计算操作符(如+ ): for循环也可以这样处理。 例如, for [ expr, expr, expr, stmnt ] (表示为inline),您可以有一个语法树,其中for是一个运算符 ,方括号内的元素是它的子元素(表示C语法) – 也由运营商等组成

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

这里是一个AST的graphics表示:

在这里输入图像说明

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

分析树更接近地表示源代码。

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

  • 条件
  • 如果情况
  • 其他案例

对于类C语言,parsing树将需要包含“if”关键字,圆括号和大括号的节点。

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

分析树是用于匹配某些input文本的规则(和令牌)的logging,而语法树logging了input的结构,并且对产生它的语法不敏感。 请注意,任何单一语言都有无数的语法,因此,由于所有不同的中间规则,每个语法对于给定的input语句将导致不同的语法树forms。 抽象语法树是一个非常优越的中间forms,正是因为这种不敏感性,并且因为它强调了语言的结构而不是语法。