LR(0)分析表的构造

文法规范句型的活前缀

  • 字符串的前缀是指字符串的任意首部,例如字符串"abc"的前缀有 ϵ \epsilon aababc
  • 规范语句活前缀是指规范语句的前缀,这种前缀不包括句柄右边的任何符号

在LR分析工作过程中的任何时刻,栈中的文法符号应是某一规范句型的活前缀。这是因为一旦句型句柄在栈的顶部形成,就会立即被规约,因此只要输入串已扫描过得部分保持可规约成一个活前缀,那就意味着所扫描过的部分是正确的。这样一来,我们对句柄的识别就变成对规范句型活前缀的识别

LR(0)项目

活前缀与句柄之间的关系存在三种情况:

  1. 活前缀中已经含有句柄的全部符号,表明此时某一规则 A α A\rightarrow{\alpha} 的右部符号串 α \alpha 已经出现在栈顶,其相应的分析动作使用此规则进行规约
  2. 活前缀中只含有句柄的一部分符号,此时意味着形如 A α 1 α 2 A\rightarrow{\alpha_1\alpha_2} 规则的右部子串 α 1 ! \alpha_1! 已出现在栈顶,正期待着从剩余的输入串中进行规约得到 α 2 \alpha_2
  3. 活前缀中全然不含有句柄的任何符号,此时意味着期望从剩余输入串中能看到由某规则 A α A\rightarrow{\alpha} 的右部 α \alpha 所推出的符号串

为了刻画在分析过程中,文法的一个规则右部符号串已有多大一部分被识别,我们可在文法中每个规则右部适当位置加一个圆点来表示。针对上述3中情况,标有圆点的规则分别为:

A α A \rightarrow{\alpha·}
A α 1 α 2 A \rightarrow{\alpha_1·\alpha_2}
A α A \rightarrow{·\alpha}

文法G中右部标有圆点的规则称为G的一个LR(0)项目

注:规则 A ϵ A\rightarrow{\epsilon} 仅有LR(0)项目 A A\rightarrow{·}

不同的LR(0)项目反映了在分析过程中栈顶的不同情况,因此,可以根据圆点后是终结符还是非终结符,将一个文法的全部LR(0)项目进行分类:

  1. 规约项目:形如 A α A \rightarrow{\alpha·} ,其中 α ( V N V T ) \alpha \in (V_N \cup V_T)^* ,即圆点在最右端的项目,它表示一个规则的右部已经分析完成,句柄已形成,应该按此规则进行规约。
  2. 移进项目:形如 A α a β A \rightarrow{\alpha·a\beta} ,其中 α β ( V N V T ) \alpha,\beta \in (V_N \cup V_T)^* a V T a \in V_T ,即圆点后面为终结符的项目,它表示期待从输入串中移入一个符号,以待形成句柄。
  3. 待约项目:形如 A α B β A \rightarrow{\alpha·B\beta} ,其中 α β ( V N V T ) \alpha,\beta \in (V_N \cup V_T)^* B V N B \in V_N ,即圆点后面为非终结符的项目,它表示期待从剩余的输入串中进行规约而得到B,然后才能继续分析A的右部
  4. 接受项目:形如 S S S^{'}\rightarrow{S·} ,其中 S S^{'} 为文法的开始符号,即文法开始符号的规约项目。 S S^{'} 为左部的规则仅有一个,它是规约项目的特殊情况,它表示整个句子已经分析完毕,可以接受。

构造识别文法所有规范举行活前缀DFA的方法

构成识别文法规范句型活前缀DFA的每一个状态是由若干个LR(0)项目所组成的集合,称为LR(0)项目集。

在这个项目集中,所有的LR(0)项目识别的活前缀是相同的可以利用闭包函数(CLOSURE)来求DFA一个状态的项目集。

定义闭包函数(CLOSURE)

I是拓广文法 G G^{'} 的一个LR(0项目集,I的闭包CLOSURE(I)的定义如下:

  1. I中的任何一个项目都属于CLOSURE(I)
  2. A α B β A\rightarrow{\alpha·B\beta} 属于CLOSURE(I),则每一形如 B r B\rightarrow{·r} 的项目也属于CLOSURE(I)
  3. 重复第二步直到CLOSURE(I)不再增大为止。

定义状态转移函数(GO)

I是拓广文法 G G^{'} 的任一项目集,X为一文法符号,定义状态转移函数GO(I,X)如下:

G O ( I , X ) = C L O S U R E ( J ) GO(I,X) = CLOSURE(J)

J = { A α X β A α X β I } J = \{A \rightarrow{\alpha X·\beta} | A \rightarrow{\alpha·X\beta} \in I\}

构造识别文法规范语句活前缀DFA的方法

  1. C L O S U R E ( { S S } ) CLOSURE(\{S^{'} \rightarrow{·S}\}) ,得到初态项目集
  2. 对初态项目集或其他已构造的项目集,应用状态转移函数GO(I,X)求出新的项目集(后继状态)
  3. 重复第二步制导不出现新的项目集为止

构成识别一个文法活前缀的DFA的状态(项目集)的全体称为这个文法的LR(0)项目集规范族。

LR(0)分析表的构造

用整数0、1、2、…、n分别表示状态 I 0 , I 1 , I 2 , . . . , I n I_0,I_1,I_2,...,I_n ,令包含 S S S^{'} \rightarrow{·S} 项目的集合 I k I_k 的下标为分析器的初始状态。

  1. 若项目 A α x β A \rightarrow{\alpha·x\beta} 属于 I k I_k ,且转换函数 G O ( I k , x ) = I j GO(I_k,x) = I_j ,当x为终结符时,则置 A C T I O N [ k , x ] = S j ACTION[k,x] = S_j
  2. 若项目 A α A \rightarrow{\alpha·} 属于 I k I_k ,**则对任何终结符和结束符 a (统一记为a)置 ACTION[k,a]=r_j **(假定 A \rightarrow{\alpha}$为文法的第j条规则)
  3. G O ( I k , A ) = I j GO(I_k,A) = I_j A为非终结符,则置GOTO[k,A] = j
  4. 若项目 S S S^{'}\rightarrow{S·} 属于 I k I_k ,则置ACTION[k,$] = acc

根据这种方法构造的LR(0)分析表不含多重定义时,称这样的分析表为LR(0)分析表,能构造LR(0)分析表的文法称为LR(0)文法。同一个项目集中不存在移进项目和规约项目同时并存或多个规约项目同时并存

猜你喜欢

转载自blog.csdn.net/hjc256/article/details/90572695