Skip to content

模型Model

语法树

Parse tree · Derivation tree

用有序树记录产生式层次,以完整例子区分推导顺序、文法歧义、优先级及抽象语法树。

形式陈述 ​

给定上下文无关文法 G=(V,Σ,R,S),一棵完整语法树以有限非空的无向树为底层图,再指定根、孩子次序与符号标签:根标记为开始符号 S;每个非终结符节点 A 的子节点从左到右组成所用产生式 A→X1⋯Xk 的右侧;最终叶节点是终结符,或用于表示空产生式的 ε。

本页把 A→ε 画成一个带 ε 叶子的节点。另一些教材将它画成没有孩子的非终结符节点,两种画法约定不同,表达的空串相同。

从左到右读取所有终结符叶,忽略 ε,得到树的产出 w,也称 yield。于是

w∈L(G)⟺存在产出为 w 的完整语法树.

尚有未展开非终结符叶子的树是部分语法树,其前沿给出一个句型,还不是完整的终结符字符串。树的孩子顺序不可丢掉,否则 ab 与 ba 可能被错误地视为同一产出。

直觉

推导序列记录“先做哪一步替换”,语法树记录“哪一部分由哪条规则产生”。前者包含操作顺序,后者保留最终的层次和分组。两次推导若只是交换彼此独立的子树的展开顺序,可以得到完全相同的树。

每一步推导都能在待展开的叶子处接上对应产生式,逐步建成树;反过来,按某个合法顺序展开树中的非终结符,就能得到产出相同的推导。这解释了上面的等价关系。固定一棵树后,总展开最左非终结符便得到唯一最左推导,总展开最右者则得到唯一最右推导。

两棵树的叶序同为 a + a * a,但根使用不同产生式,因此文法有歧义。
例子与边界

从局部产生式还原整个字符串 ​

对文法 S→aSb∣ε,字符串 aabb 的语法树为:

text
        S
      / | \
     a  S  b
       /|\
      a S b
        |
        ε

外层 S 和中层 S 都使用 S→aSb,最内层使用空产生式。叶从左到右是 a a ε b b,删去 ε 得到 aabb。对应推导为

S⇒aSb⇒aaSbb⇒aabb.

这个例子每一步只有一个待展开的非终结符,适合说明嵌套结构,却不能用来展示“两个独立子树可以交换展开顺序”。

两个不同推导,可以是同一棵树 ​

改用文法 S→AB、A→a、B→b。下面两个推导不同:

S⇒AB⇒aB⇒ab,S⇒AB⇒Ab⇒ab.

前者先展开 A,后者先展开 B;最终都得到同一棵树:

text
    S
   / \
  A   B
  |   |
  a   b

因此,发现两个一般推导序列不足以证明文法有歧义。这里的差别只在完成独立工作的先后,并不改变句子的结构。

真正的歧义:分组发生变化 ​

取文法 E→E+E∣E∗E∣a。同一个字符串 a+a*a 有两棵不同的完整语法树:

text
      E                      E
    / | \                  / | \
   E  +  E                E  *  E
   |    /|\              /|\    |
   a   E * E            E + E   a
       |   |            |   |
       a   a            a   a

左树的根使用加法产生式,右侧子树是乘法,对应分组 a+(a∗a);右树的根使用乘法产生式,左侧子树是加法,对应 (a+a)∗a。两棵树的终结符叶序列相同,内部组合却不同,这才构成文法歧义。

这里的括号只用于说明分组,并没有出现在原字符串中。语法树表达组合结构;它是否对应数值加乘、如何求值,还需要给运算符指定语义。

用文法表达优先级 ​

希望乘法比加法结合得更紧,可以把文法分层:

E→E+T∣T,T→T∗F∣F,F→a∣(E).

表达式 E 由加法连接“项” T,项内部再由乘法连接“因子” F。因此 a+a*a 的右侧乘法必须先组成一个项,再与左侧相加;左递归的结构还确定了同级运算的左结合。括号作为因子允许显式改变分组。

这是一种针对算术表达式的文法设计,不是把任何歧义文法自动变成无歧义文法的通用步骤。解析工具也可以在原文法之外使用优先级、结合性声明来选择解析结果,需要区分“文法本身无歧义”和“解析器有消歧规则”。

推论与应用

语法树也常称为具体语法树。它严格对应所选文法,可能保留括号、分隔符及 E,T,F 这样的辅助层次。抽象语法树则突出程序结构,通常把纯辅助节点和可由结构恢复的标点省掉。二者不是同义词,也不必与源代码字符逐个对应:经过词法分析后,语法树叶子通常是 token,token 再携带原始词素与源位置。

从输入串构造本页的树,可以使用预测栈或移进归约栈;若文法有歧义,共享打包森林会在同一输入区间下保留不同分组。类型、变量绑定与符号表信息不会由一棵未加注解的树自动出现,仍需语义动作、属性传播或后续遍历。

对已经给定的候选树,有限树自动机可以自底向上检查固定文法的局部展开。接入固定秩字母表前,需要按“符号、孩子数”区分可能具有不同元数的标签;本页的空产生式仍保留零元的 ε 叶子,其非终结符父节点有一个孩子。这是检查树,不是把其产出字符串改用字 DFA 解析。

Chomsky 范式的非终结符展开主要为 A→BC,终结符产生式为 A→a,另按约定处理开始符号的空串。因此分割非空区间的骨架是二叉的,但完整语法树仍含 A→a 的单孩子节点,不能笼统说“每个内部节点都有两个孩子”。CYK 算法利用这个二分骨架,按子串区间记录哪些非终结符能作为根;保存分割点与产生式后,还可以恢复相应语法树。

参考资料
  • Stanford CS143, Introduction to Parsing,Derivations and Parse Trees、Ambiguity、Precedence and Associativity 各节。
  • Michael Sipser, Introduction to the Theory of Computation, 3rd ed., Cengage, 2013,§2.1 “Context-Free Grammars”,语法树、歧义与 Chomsky 范式。
  • John E. Hopcroft, Rajeev Motwani, and Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation, 3rd ed., Pearson, 2006,Chapter 5 “Context-Free Grammars and Languages”。
关系图谱17 个相邻概念 · 4 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
分类位置

上位 / 更一般

下位 / 直接特例

暂未标注直接特例。

类型化关系