LR0和LR1转移图的有效计算方法

 

LR0转移图的计算
       先计算处带空转换的NFA,再根据NFA计算DFA,例如文法:
       E* -> E (拓广文法)

       E -> E + E | ( E ) | id

LR0和LR1转移图的有效计算方法_第1张图片

       计算的过程如下:
(1)为每个非终结符独立地计算转移图,得到核心项目集,计算过程中遇到形如E -> a . F a的项目时,不将从F起的项目加如项目集。上图就是计算得到的核心项目集。
(2)根据核心项目集得到NFA,每个核心项目集对应NFA中一个状态。
(3)给NFA添加空转换,检查每个状态,如果状态s1中有形如E -> a . F b的项目(其中a、b可以为空),非终结符F的第一个状态为s2,则添加s1到s2的空转换。例如上图state 5中有项目E -> E + . E,并且E的第一个状态为state 3,则添加state 5到state 3的空转移。
(4)从拓广文法的起始符开始,根据NFA计算DFA。
LR1转移图的计算
(1)为每个非终结符独立地计算转移图,得到核心项目集,和计算LR0转移图是相同的。
(2)根据核心项目集得到NFA,NFA的状态由核心项目集和向前看字符共同决定。例如(state 3、a)表示核心项目集3且向前看字符为a,简单记为3a,将多个状态3a、3b、3c简单记为3abc。要表示和某项目集相关的任意状态时,只记项目集的编号,不记向前看字符。
(3)给NFA添加空转换。检查每个核心项目集,如果项目集X中有形如 E -> a . F B的项目,非终结符F的第一个项目集为Y,字符b属于First(B),则添加X到Yb的空转换,表示和X相关的任意状态都可以转换到状态Yb。如果ε属于First(B),则添加X到Yε的空转换,表示和X相关的每个状态Xa可以转换到Ya,a为任意字符。
       LR0转移图的例子中,状态1中存在项目E* -> . E,E的起始状态为3,则添加1到3ε的空转换;状态5中存在项目E -> E + . E,添加5到3ε的空转换;状态7中存在项目E -> ( . E ),添加7到3)的空转换;状态3中存在项目E -> . E + E,则添加3到3+的空转换。
(4)从拓广文法的起始符开始,根据NFA计算DFA。
       LR0转移图的例子中,开始状态为1$,因为向前看字符是文件尾。计算得到的DFA如下图所示,图中虚线框表示其它地方出现过的状态。
LR0和LR1转移图的有效计算方法_第2张图片

你可能感兴趣的:(LR0和LR1转移图的有效计算方法)