自底向上的语法分析有两大类算法:一是算符优先分析,二是LR分析。本文将讨论算符优先分析。
基础概念
- 含义:根据给定文法产生式,能将给定的字符串反向推导出文法开始符的过程被称为自底向上的语法分析。
- 从语法树的角度看,该过程是由叶子结点一路向上遍历,直到到达根节点的过程。
以下是一个例子: 第一列是栈,第二列是输入字符串。
在这个过程中:
- 形如把栈顶的b替换为A的过程被称为归约(reduce),而将右部字符串首部字符移入左边栈中的过程被称为移进(shift)。
算符优先分析算法
为什么需要该算法?因为文法存在二义性问题。而算符优先分析算法可理解为人类约定俗成的“先乘除、后加减”等等规则。
算符优先级
接下来介绍算符优先级的概念:
- a<*b(在书写时是<里面包含了一个点):表示左边的a优先级小于右边的b。
为什么要强调左边右边?因为算符优先级是位置敏感的,它和初等数学中的大于小于不是一个概念。后续在写算符优先表时读者会对这一问题有更直观的理解。
在产生式中,这体现为:
- 若P->aR... 且R->b...|Qb...
同理,
- a>*b:表示左边的a优先级大于右边的b。
- 产生式中体现为:若P->...Rb 且R->...a|...aQ
同理,
- a=*b:表示左边的a优先级等于右边的b。
- 产生式中体现为:P->ab
FIRSTVT和LASTVT
相信读者也留意到了上文中的R->b...|Qb...和R->...a|...aQ,实际上,这是一块很特殊的区域:
其中的FIRSTVT、LASTVT刚好与优先级低于、优先级高于两个符号的定义对应。
VT:vector terminal 。所以是终结符的集合
附加条件:
若P->Q,则FIRSTVT(Q)的元素∈FIRSTVT(P) 若P->(...)Q,(此处表示前缀可有也可无)则LASTVT(Q)的元素∈LASTVT(P)
构造算符优先表
以下以一道例题作为例子:
- 先找出对应的FIRSTVT集和LASTVT集:
- 写出对应的算符优先表。其中行表示左边的元素集合,列表示右边的元素集合。
举个例子:
E+中,显然E>*+,>*对应的是LASTVT,所以找LASTVT(E)对应的元素并对应于左边(也就是行),并在对应+这一列中填入>*。
进行算法分析
又回到开始的问题,只需要三列:栈、输入的字符串和规则。
规则如下:
- 若当前栈顶元素比输入串头元素优先级更高,则执行归约操作;
- 若输入串头元素优先级更高或相等,则执行移进操作。
具体操作示例和文章开头的图类似,只是多了符号,这里不再赘述。
感谢你能看到这里!