它们是否由编译过程的不同阶段生成?或者它们只是同一个东西的不同名称?
答案 0 :(得分:87)
这是基于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)
解析树
解析树是输入的具体表示。解析树保留输入的所有信息。空框表示空格,即行尾。
AST
AST是输入的抽象表示。请注意,AST中不存在parens,因为关联可以从树结构中派生。
有关详细说明,请参阅Compilers and Compiler Generators pg。 23个
或者Abstract Syntax Trees on pg。 Syntax and Semantics of Programming Languages
答案 1 :(得分:16)
根据我的理解,AST更多地关注源代码组件之间的抽象关系,而解析树则侧重于语言使用的语法的实际实现,包括挑剔的细节。它们肯定不一样,因为“解析树”的另一个术语是“具体语法树”。
我发现这个page试图解决这个问题。
答案 2 :(得分:10)
Martin Fowler的DSL book很好地解释了这一点。 AST仅包含将用于进一步处理的所有“有用”元素,而解析树包含您解析的原始文档中的所有工件(空格,括号,...)
答案 3 :(得分:4)
进行pascal分配 年龄:= 42;
语法树看起来就像源代码一样。下面我在节点周围放置括号。 [年龄] [:=] [42] [;]
抽象树看起来像这样 [=] [年龄] [42]
赋值变成一个包含2个元素的节点,Age和42.想法是你可以执行赋值。
另请注意,pascal语法会消失。因此,可以使用多种语言生成相同的AST。这对跨语言脚本引擎很有用。
答案 4 :(得分:1)
在解析树中,内部节点是非终端,叶子是终端。 在语法树中,内部节点是运算符,叶子是操作数。