LR(0)分析表的构造

活前缀

  • 活前缀:是指规范句型的一个前缀,这种前缀不含句柄之后的任何符号。即,对于规范句型 α β δ \alpha \beta \delta αβδ β \beta β为句柄,如果 α β = u 1 u 2 … u r \alpha \beta = u_1u_2\dots u_r αβ=u1u2ur,则符号串 u 1 u 2 … u i ( 1 ≤ i ≤ r ) u_1u_2\dots u_i(1 \leq i \leq r) u1u2ui(1ir) α β δ \alpha \beta \delta αβδ的活前缀。( δ \delta δ必为终结符串)
  • 规范规约过程中,保证分析栈中总是活前缀,就说明分析采取的移进/归约动作是正确的。

构造识别活前缀的DFA

文法的拓广

将文法 G ( S ) G(S) G(S)拓广为 G ′ ( S ′ ) G'(S') G(S)

  • 构造文法 G ′ G' G,它包含了整个 G G G,并引进不出现在 G G G中的非终结符 S ′ S' S、以及产生式 S ′ → S S' \rightarrow S SS S ′ S' S G ′ G' G的开始符号
  • G ′ G' G G G G的拓广文法

LR(0)项目

  • LR(0)项目:
    • 在每个产生式的右部添加一个圆点
    • 表示我们在分析过程中看到了产生式多大部分
  • A → X Y Z A \rightarrow XYZ AXYZ有四个项目: A → ⋅ X Y Z A \rightarrow \cdot XYZ AXYZ A → X ⋅ Y Z A \rightarrow X\cdot YZ AXYZ A → X Y ⋅ Z A \rightarrow XY\cdot Z AXYZ A → X Y Z ⋅ A \rightarrow XYZ \cdot AXYZ
    • A → α ⋅ A \rightarrow \alpha \cdot Aα称为“归约项目”
    • 归约项目 S ′ → α ⋅ S' \rightarrow \alpha \cdot Sα称为“接受项目”
    • A → α ⋅ a β ( a ∈ V T ) A \rightarrow \alpha \cdot a \beta(a \in V_T) Aαaβ(aVT)称为“移进项目”
    • A → α ⋅ B β ( B ∈ V N ) A \rightarrow \alpha \cdot B \beta(B \in V_N) AαBβ(BVN)称为“待约项目”

构造识别文法所有活前缀的DFA

  • 构造识别文法所有活前缀的NFA
    • 若状态 i i i X → X 1 … X i − 1 ⋅ X i … X n X \rightarrow X_1 \dots X_{i - 1} \cdot X_i\dots X_n XX1Xi1XiXn,状态 j j j X → X 1 … X i − 1 X i ⋅ X i + 1 … X n X \rightarrow X_1 \dots X_{i-1} X_i \cdot X_{i + 1} \dots X_n XX1Xi1XiXi+1Xn,则从状态 i i i画一条标志为 X i X_i Xi的有向边到状态 j j j
    • 若状态 i i i X → α ⋅ A β X \rightarrow \alpha \cdot A \beta XαAβ A A A为非终结符,则从状态 i i i画一条 ϵ \epsilon ϵ边到所有状态 A → ⋅ γ A \rightarrow \cdot \gamma Aγ
  • 把识别文法所有活前缀的NFA确定化

实例:
先生成NFA
识别活前缀的NFA
再将NFA转化为DFA
识别活前缀的DFA

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

通过计算项目集规范族构造识别活前缀的DFA

有效项目

  • 项目 A → β 1 ⋅ β 2 A \rightarrow \beta_1 \cdot \beta_2 Aβ1β2对活前缀 α β 1 \alpha \beta_1 αβ1是有效的,其条件是存在规范推导:
    S ′ ⇒ ∗ R α A ω ⇒ R α β 1 β 2 ω S' \xRightarrow{*}_R\alpha A \omega \Rightarrow_R \alpha \beta_1\beta_2\omega S RαAωRαβ1β2ω
  • 在任何时候,分析栈中的活前缀 X 1 X 2 … X m X_1X_2\dots X_m X1X2Xm的有效项目集正式从识别活前缀的DFA的初态出发,读出 X 1 X 2 … X m X_1X_2\dots X_m X1X2Xm后到达的那个项目集(状态)

有效项目的性质

  • 若项目 A → α ⋅ B β A \rightarrow \alpha \cdot B\beta AαBβ对活前缀 η = δ α \eta = \delta \alpha η=δα是有效的且 B → γ B \rightarrow \gamma Bγ是一个产生式,则项目 B → ⋅ γ B \rightarrow \cdot \gamma Bγ η = δ α \eta = \delta \alpha η=δα也是有效的

LR(0)项目集规范族的构造

项目集的闭包CLOSURE

假定 I I I是文法 G ′ G' G的任一项目集,定义和构造 I I I的闭包CLOSURE( I I I)如下:

  • I I I的任何项目都属于CLOSURE( I I I)
  • A → α ⋅ B β A \rightarrow \alpha \cdot B \beta AαBβ属于CLOSURE( I I I),那么,对任何关于 A A A的产生式 B → γ B \rightarrow \gamma Bγ,项目 B → ⋅ γ B \rightarrow \cdot \gamma Bγ也属于CLOSURE( I I I)
  • 重复执行上述两步骤直至CLOSURE( I I I)不再增大为止。

状态转换函数

  • 为了识别活前缀,我们定义一个状态转换函数,GO是一个状态转换函数。 I I I是一个项目集, X X X是一个文法符号。函数值GO( I , X I,X I,X)定义为:
    GO( I , X I,X I,X) = CLOSURE( J J J)
    其中 J J J = {任何形如 A → α X ⋅ β A \rightarrow \alpha X \cdot \beta AαXβ的项目| A → α ⋅ X β A \rightarrow \alpha \cdot X \beta AαXβ属于 I I I}。
  • 直观上说,若 I I I是对某个活前缀 γ \gamma γ有效的项目集,那么,GO( I , X I,X I,X)便是对 γ X \gamma X γX有效的项目集。

示例

文法 G ( S ′ ) G(S') G(S)
S ′ → E S' \rightarrow E SE
E → a A ∣ b B E \rightarrow aA|bB EaAbB
A → c A ∣ d A \rightarrow cA|d AcAd
B → c B ∣ d B \rightarrow cB|d BcBd
I 0 = { S ′ → ⋅ E , E → ⋅ a A , E → ⋅ b B } I_0 = \{S' \rightarrow \cdot E,E \rightarrow \cdot aA,E \rightarrow \cdot bB\} I0={SE,EaA,EbB}
GO( I 0 , E I_0,E I0,E) = CLOSURE( { S ′ → ⋅ E } \{S' \rightarrow \cdot E\} {SE}) = I 1 I_1 I1
GO( I 0 , a I_0,a I0,a) = CLOSURE( { E → a ⋅ A } \{E \rightarrow a\cdot A\} {EaA}) = { E → a ⋅ A , A → ⋅ c A , A → ⋅ d } \{E \rightarrow a \cdot A, A \rightarrow \cdot cA, A \rightarrow \cdot d\} {EaA,AcA,Ad} = I 2 I_2 I2
GO( I 0 , b I_0,b I0,b) = CLOSURE( { E → b ⋅ B } \{E \rightarrow b\cdot B\} {EbB} = { E → b ⋅ B , B → ⋅ c B , B → ⋅ d } \{E \rightarrow b \cdot B, B \rightarrow \cdot cB, B \rightarrow \cdot d\} {EbB,BcB,Bd} = I 3 I_3 I3

LR(0)项目集规范族的构造算法示例

大致流程:先从 S ′ → ⋅ E S' \rightarrow \cdot E SE开始,求闭包,然后根据GO转移。然后对每一个转移后的状态,求闭包,根据GO转移。以此类推!
构造算法

构造LR(0)分析表的算法

LR(0)分析表的构造

假若一个文法 G G G的拓广文法 G ′ G' G的活前缀识别自动机中的每个状态(项目集)不存在下述情况:

  • 既含移进项目又含归约项目
  • 含有多个归约项目
    则称 G G G是一个LR(0)文法

构造LR(0)分析表的算法

  • 令每个项目集 I k I_k Ik的下标 k k k作为分析器的状态,包含项目 S ′ → ⋅ S S' \rightarrow \cdot S SS的集合 I k I_k Ik的下标 k k k为分析器的初态。
  • 构造LR(0)分析表的ACTION和GOTO子表。因为文字描述比较复杂和繁琐,因此不再罗列,而是直接给出实例

示例

文法 G ( S ′ ) G(S') G(S)
S ′ → E S' \rightarrow E SE
E → a A ∣ b B E \rightarrow aA|bB EaAbB
A → c A ∣ d A \rightarrow cA|d AcAd
B → c B ∣ d B \rightarrow cB|d BcBd
识别活前缀的DFA见前图

ACTIONGOTO
状态abcd#EAB
0s2s31
1acc
2s4s106
3s5s117
4s4s108
5s5s119
6r1r1r1r1r1
7r2r2r2r2r2
8r3r3r3r3r3
9r5r5r5r5r5
10r4r4r4r4r4
11r6r6r6r6r6
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值