编译原理 LALR中搜索符的传播

编译原理龙书中,介绍了LALR搜索符的传播算法,这里给出更详细的实现方式.

 

计算搜索符
生成搜索符的两种方式
1.项目[S'-> . S,$],自动生成搜索符$
2.从项目[A->α.Bβ,?]生成项目[B->...,first(β)],
  自动生成搜索符first(β)
搜索符的两种传播方式
1.项目[A->α.Bβ,a],当β能导出空串时,该项目的
  搜索符a传播到项目[B->...,a],称为纵向传播
2.项目[A->α.B β,a],搜索符a传播到项目[A->αB .β,a]
  称为横向传播

 

按如下顺序处理搜索符的生成、传播问题
1.处理项目[A->.Bβ]的自动生成和纵向传播,其中dot在最前面
  对每个NT生成的dot在最前面的核心状态,确定它能null转移到
  哪些NT,并确定每个null转移的搜索符。
  即A null to B,lookahead=#???
      null to C,lookahead=#???
  #是一个特殊的搜索符,其作用见编译原理龙书,如果[A->.Bβ]
  中的β能导出空串,则A null to B的转移中包含#搜索符;
  当β不能导出空串,则A null to B的转移中不包含#搜索符。
  后面将 A null to B,lookahead=#??? 记成[A,B,#???]
2.处理项目[A->α.Bβ]的自动生成和纵向传播,其中dot不在最前面
3.在生成LALR或LR1状态时处理横向传播

 

步骤1的详细过程如下,基于图来描述
1.将所有的NT做为节点,加入图中
2.对于[A->.Bβ]
  如果β能导出空串,则将边(A,B,#)加入图中,其中#为边的属性
  如果first(β)不为空,则将边(A,B,first(β))加入图中
3.对每个节点,计算从该节点出发能够到达的节点,另外保存
4.根据图中带#属性的边计算闭包,将得到的边加入图中
  例如,如果有(A,B,#)和(B,C,#),则将边(A,C,#)加入图中
5.根据第3步计算结果,可以直到从S能够到达X1,X2,X3...
5.1 如果图中有(S,Y,#),则生成 [S,Y,#]
5.2 如果图中有(S,Y,a),则生成 [S,Y,a]
    在上面基础上,如果有(Y,Z,#)则生成 [S,Z,a]
5.3 如果图中有(Xi,Y,a),则生成 [S,Y,a]
    在上面基础上,如果有(Y,Z,#)则生成 [S,Z,a]

 

举例文法
  S->L=R | R | R+
  L->*R | id
  R->L
步骤1.1:
  将节点S' S L R加入图中
步骤1.2:
  因为[S->.L=R],所以将(S,L,=)加入图中
  因为[S->.R], 所以将(S,R,#)加入图中
  下面是最终得到的图
  (S', S, #)
  (S , L, =) (S , R, #+)
  (R , L, #)
步骤1.3:
  从S'能到达 S L R
  从S 能到达 L R
  从R 能到达 L
  从L 不能到达任何地方
步骤1.4:
  因为(S', S, #)和(S, R, #),所以将(S', R, #)加入图中
  下面是最终得到的图
  (S', S, #) (S', R, #) (S', L, #)
  (S, L, #=) (S, R, #+)
  (R, L, #)
步骤1.5:
  以S为例,从S能到达R L
  图中有(S,L,#),因此生成[S,L,#]
  图中有(S,R,#),因此生成[S,R,#]
  图中有(S,L,=),因此生成[S,L,=]
  图中有(S,R,+),因此生成[S,R,+];又因为有(R,L,#),因此生成[S,L,+]
  最终得到 [S,L,#=+] [S,R,#+]

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值