Compiler construction 什么';解析树和抽象语法树之间的区别是什么?

Compiler construction 什么';解析树和抽象语法树之间的区别是什么?,compiler-construction,abstract-syntax-tree,parse-tree,Compiler Construction,Abstract Syntax Tree,Parse Tree,我在一本编译器设计书中找到了这两个术语,我想知道它们各自代表什么,以及它们之间的区别 我在互联网上搜索发现,解析树也称为具体语法树(CST)。AST从概念上描述源代码,它不需要包含解析某些源代码(大括号、关键字、括号等)所需的所有语法元素 解析树更紧密地表示源代码 在AST中,IF语句的节点只能包含三个子节点: 状况 如果情况 其他情况 对于类C语言,解析树需要包含“if”关键字的节点、括号和花括号。这是基于Terrence Parr的语法 本例的语法: grammar Expr002;

我在一本编译器设计书中找到了这两个术语,我想知道它们各自代表什么,以及它们之间的区别


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

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

解析树更紧密地表示源代码

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

  • 状况
  • 如果情况
  • 其他情况
对于类C语言,解析树需要包含“if”关键字的节点、括号和花括号。

这是基于Terrence Parr的语法

本例的语法:

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(); } ;
输入

解析树

解析树是输入的具体表示。解析树保留输入的所有信息。空框表示空白,即行尾

AST

AST是输入的抽象表示。请注意,在AST中不存在paren,因为关联可以从树结构派生

编辑


更多详细解释,请参见p.D.Terry第23页。有关源代码等更多项目,请参见作者。

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

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

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

在解析时,编译器还执行各种检查,以确保语法和语法错误报告的正确性可以嵌入到解析器代码中

它们可以通过语法定向定义或翻译方案用于语法定向翻译,也可以用于简单任务,例如将中缀表达式转换为后缀表达式

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

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

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

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

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

以下是AST的图形表示:


我在网上找到了这个,也许有帮助:

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

维基百科说

解析树具体地反映了输入语言的语法,使它们不同于计算机编程中使用的抽象语法树

关于Quora的回答是

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

结合上述两种定义

抽象语法树
从逻辑上描述解析树。它不需要包含解析某些源c所需的所有语法结构
x=1
y=2
3*(x+y)