它们是编译过程的不同阶段生成的吗?还是只是指称同一件事情的不同名称?
它们是编译过程的不同阶段生成的吗?还是只是指称同一件事情的不同名称?
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中没有括号,因为关联性可以从树结构中推导出来。
如需更详细的解释,请参见编译器和编译器生成器第23页
或抽象语法树在编程语言的语法和语义中的第21页
9-5+2
(注意终端在树中的位置和来自表达式字符串的实际符号):
抽象语法树(AST)代表了一些代码的语法结构。编程结构的树形式如表达式、流控制语句等被分为运算符(内部节点)和操作数(叶节点)。例如,表达式 i+9
的语法树将以 +
运算符作为根节点,变量 i
作为左儿子,数字 9
作为右儿子。
这里的区别在于非终结符和终结符不起作用,因为 AST 不处理语法和字符串生成,而是处理编程结构,因此它们表示这些结构之间的关系,而不是它们由语法生成的方式。
请注意,运算符本身是给定语言中的编程结构,不必是实际的计算运算符(如 +
),例如:for 循环也会以这种方式处理。例如,您可以拥有类似于 for [ expr, expr, expr, stmnt ]
的语法树(内联表示),其中 for
是一个 运算符,方括号内的元素是其子元素(表示 C 的 for
语法),还由运算符等组成。
AST 通常由编译器在语法分析(解析)阶段生成,并在后续用于语义分析、中间表示、代码生成等。
以下是抽象语法树的图形表示:
据我所了解,AST更关注源代码组件之间的抽象关系,而解析树则更关注语言所使用的语法实现,包括细节方面。它们绝对不是相同的,因为“解析树”的另一个术语是“具体语法树”。
抽象语法树(AST)描述源代码的概念,它不需要包含解析某些源代码所需的所有语法元素(大括号、关键字、括号等)。
语法分析树更加贴近源代码。
在AST中,IF语句的节点可能只包含三个子节点:
对于类C语言,语法分析树需要包含 'if' 关键字、括号和大括号等节点。
维基百科表示
解析树具体地反映了输入语言的语法,使其与用于计算机编程的抽象语法树不同。
Quora上的答案说
解析树是记录用于匹配某些输入文本的规则(和令牌)的记录,而语法树记录输入的结构并对生成它的语法不敏感。
结合上述两个定义,
抽象语法树
在逻辑上描述解析树。它不需要包含解析某些源代码所需的所有语法结构(空格、花括号、关键字、括号等)。这就是为什么解析树
也被称为具体语法树
,而AST被称为语法树
。因此,语法分析器的输出实际上是语法树。
进行pascal任务分配
Age:= 42;
语法树看起来就像源代码一样。下面我将在节点周围放置括号。 [Age][:=][42][;]
抽象树如下所示 [=][Age][42]
该赋值成为一个具有两个元素的节点,即Age和42。其想法是可以执行该赋值。
还要注意Pascal语法消失的事实。因此,可以有多种语言生成相同的AST。对于跨语言脚本引擎很有用。