算符优先文法的构造
- 算符优先文法属于自底向上的文法分析,需要不断的进行移进-规约操作,让一个输入的句子通过不断的移进-规约,最终变成文法的开始符号。
- 在移进-规约的过程中我们需要知道先对什么进行规约,得有个先后关系,故需要构造文法的算符优先表,来帮助规约分析时的规约对象。
构造FirstVT集和LastVT集
FirstVT和LastVT分别代表某个非终结符所产生的句型中第一个和最后一个终结符的集合。具体产生规则如下:
Firstvt
找Firstvt的三条规则:如果要找A的Firstvt,A的候选式中出现:
A->a.......,即以终结符开头,该终结符入Firstvt
A->B.......,即以非终结符开头,该非终结符的Firstvt入A的Firstvt
A->Ba.....,即先以非终结符开头,紧跟终结符,则终结符入Firstvt
Lastvt
找Lastvt的三条规则:如果要找A的Lastvt,A的候选式中出现:
A->.......a,即以终结符结尾,该终结符入Lastvt
A->.......B,即以非终结符结尾,该非终结符的Lastvt入A的Lastvt
A->.....aB,即先以非终结符结尾,前面是终结符,则终结符入Firstvt
构造算符优先表
算符优先关系表即确定各个终结符的优先关系,以便之后寻找最左素短语。
算符优先表分以下几种情况:
E->...aBc...
和E->...ac...
,在产生式中存在类似关系的终结符优先级相等,即a和c的优先级相等。E->Ab
,在产生式中存在一个非终结符在前一个终结符在后的情况,则A的LastVT集合中的终结符优先级都高于终结符b的优先级E->aB
,在产生式中存在一个终结符在前和一个非终结符在后的情况,则B的FirstVT集合中的终结符优先级都高于终结符a的优先级
其实大白话说起来就遵循一种就行:就是产生式中哪些终结符一起能规约成左部非终结符,则两者优先级相等,而终结符和非终结符在同一个产生式中,非终结符的终结符集合需要先规约成非终结符,所以那些非终结符的终结符的优先级要高于与非终结符在同一产生式中的终结符
寻找待规约串
寻找规约串即寻找最左素短语。
在分析过程中,需要用到分析栈和符号串,通过比较栈顶终结符和符号串的首字符,若是小于或者等于则把符号串的首字符加入符号栈,若是大于则从符号栈顶向下寻找,直到找到优先级更小的终结符停止。
即需要找到一个字符串,它的优先级比前后的优先级都要高。
找到之后把规约串进行规约即可。
重复上述的操作,直至字符串为#
例子
文法:
S->aAcBe
A->b|Ab
B->d
输入的测试用例:
abbcde#
经过计算得出优先关系表:
-------------------------------------------
| | a | c | e | b | d | # |
-------------------------------------------
| a | | = | | < | | |
-------------------------------------------
| c | | | = | | < | |
-------------------------------------------
| e | | | | | | > |
-------------------------------------------
| b | | > | | > | | |
-------------------------------------------
| d | | | > | | | |
-------------------------------------------
| # | < | | | | | = |
-------------------------------------------
结果
----------------------------------------------------------------------
|Step | SymbolStack | InputString | usedproduc |
----------------------------------------------------------------------
| 1 | # | abbcde# | Start |
| 2 | #a | bbcde# | Move in |
| 3 | #ab | bcde# | Move in |
| 4 | #aA | bcde# | Statute, A->b |
| 5 | #aAb | cde# | Move in |
| 6 | #aA | cde# | Statute, A->Ab |
| 7 | #aAc | de# | Move in |
| 8 | #aAcd | e# | Move in |
| 9 | #aAcB | e# | Statute, B->d |
| 10 | #aAcBe | # | Move in |
| 11 | #S | # | Statute, S->aAcBe |
| 12 | #S# | | Accept |
----------------------------------------------------------------------
分析:
step1:比较#和a,# < a,故把a入栈
step2:比较a和b,a < b,故把b入栈
step3:比较b和b,b > b,故从栈顶去寻找比其优先级更低的终结符,即a,故规约串即b自己,将b规约成A
step4:比较a和b,a < b,故把b入栈
step5:比较b和c,b > c,故从栈顶开始寻找优先级更低的终结符,即a,故规约串为Ab,将其规约成A
step6:比较a和c,a = c,故把c入栈
step7:比较c和d,c < d,故把d入栈
step8:比较d和e,d > e,故寻找规约串,因为 d > c 故规约串为d,规约成B
step9:比较c和e,c = e,故把e入栈
step10:比较e和#,c > #,从栈顶开始寻找规约串,# < e = c = a > #,故规约串为aAcBe,规约成S