术语解析树和派生树之间的任何差异?

时间:2011-04-20 12:07:35

标签: parsing grammar lex abstract-syntax-tree

术语AST(抽象语法树),解析树和派生树在引用解析符合语法的文本的结果时由不同的人围绕。假设我们正在谈论解析计算机语言,他们的差异是否足够小,我们可以互换使用这些术语?如果没有,我们如何正确使用这些术语?

3 个答案:

答案 0 :(得分:8)

AFAIK,“派生树”和“解析树”是相同的。

Abstract syntax tree

  

在计算机科学中,抽象语法树(AST)或语法树是用编程语言编写的源代码的抽象语法结构的树表示。树的每个节点表示在源代码中出现的构造。语法是“抽象的”,因为它不代表真实语法中出现的每个细节。

Parse tree

  

具体的语法树或解析树或解析树是(有序的,有根的)树,它根据某种形式语法表示字符串的句法结构。在解析树中,内部节点由语法的非终端标记,而叶节点由语法的终端标记。

以源a = (1 + 2) * 3;为例。 解析树可能如下所示:

    ASSIGNMENT
   / / |      \
  / /  |       \ 
 a = expression ;
       /   \
 expression \ 
   / | \     \
  (  +  )     *
    / \        \
   1   2        3

,而抽象语法树可能如下所示:

ASSIGNMENT
  /    \
 a   expression 
      /     \
 expression  *
     |        \ 
     +         3 
    / \
   1   2

答案 1 :(得分:3)

Parse / Derivation /具体语法树都是同一概念的同义词。

这些树通常仅用于理论讨论,因为它们包含许多细节,这些细节似乎不需要进行语言处理;在表达式树中,您真的需要一个节点来表示“(”和另一个表示“)”?

“抽象语法”树的概念是将程序结构表示为足以在实践中处理的详细程度的树;您通常不会找到“(...)”的节点。

一个有趣的问题:是否可以从CST直接计算AST?答案应该是肯定的,但人们几乎不会这样做。他们倾向于做的是在解析器运行时构造“抽象语法”节点,并使用ad hoc(规则缩减程序附件)来组装来自子解析的节点和父节点的粘合节点。恕我直言,他们这样做是因为我们都被YACC所吸引,这就是传统上的做法。 (我们过去常常用燧石点火。)有一个较小的借口;这样做可以让编译器构建器完全控制AST的结构,并且他可以生成一个在额外细节方面非常小的一个。 除了嵌入在解析器操作中的相同ad-hoc计算之外,这样的ad-hoc树不能从CST计算。

我使用了一种不同的方法:my tools直接从CST计算AST,字面意思是删除不相关的细节,例如,遗漏代表非值承载令牌的节点(例如,那些无意义的'('') '标记以及关键字),压缩一元制作的字符串,并将等同于列表的右倾或左倾树转换为实际列表节点。这样做的好处是解析器可以直接从语法规则计算AST。没有摆弄程序附件。没有弄错。不再担心our COBOL grammar有3500条规则的事实,否则我会为每一条规则都需要程序性的goo,而且我必须改变我的语法数百次才能使它正确并且每次都要弄乱goo 。我们的工具就好像它们直接在CST上运行一样,这使得很容易思考树操作,特别是如果你直接盯着语法规则。 (这也使得使用表面语法的模式匹配更容易:对于任何模式片段,都有一个可直接计算的AST对应)。

因此,AST和CST之间的区别在实用性方面是真实的。但我认为它们应该被视为只是同构的表示。

答案 2 :(得分:3)

当通过解析生成树时,我将使用术语解析树,即在评估给定输入序列是否属于该语言时,以及确定必须使用哪个生成以重新生成的顺序顺序。

派生树具有完全相同的形状,但是会从给定生产中导出序列的过程中产生。

解析的正式定义是找到给定输入序列的派生,所以难怪派生树和解析树是相同的。

具体抽象语法树的不同之处在于前者为输入序列中的每个标记都有一个叶节点,而后者省略了可以通过其知道的任何标记。检查语法。 if <expr> then <statement> else <statement> end的具体语法子树将包含的叶子,如果然后 else end 而抽象的不会。 (2+3)的具体语法树是:

  e
  |
( e )
 /|\        
| | |  
n + n

抽象的只是:

  +
 | |  
 n n