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中,因为这些关联可以从树结构中导出。
编辑
有关更多的解释,请参阅PD 编译器和编译器生成器 。 23.另请参阅作者主页以获取更多项目,例如源代码。
下面是在编译器构build的上下文中对parsing树 (具体语法树,CST)和抽象语法树 (AST)的解释。 它们是相似的数据结构,但它们构造不同,用于不同的任务。
parsing树木
parsing树通常是在词法分析之后的下一步生成的(将源代码转换为一系列可以被视为有意义单元的令牌,而不仅仅是一系列字符)。
它们是树形数据结构,显示input的terminalstring(源代码标记)是如何由所述语言的语法生成的。 分析树的根是语法的最一般的符号 – 起始符号(例如语句 ),内部节点代表起始符号扩展到的非终止符号(可以包括起始符号本身),例如expression式 , 声明 , 术语 , 函数调用 。 叶子是语法的terminal,在语言/inputstring中显示为标识符,关键字和常量的实际符号,例如, 9 , if等等
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,正是因为这种不敏感性,并且因为它强调了语言的结构而不是语法。