一个简单实例的LR分析过程

  经过前面两篇文章。已经讲清楚了LR语法分析中最重要的分析表的构造过程。先补充一个小问题,就是LR(0)项目的分类
  
  根据圆点所在的位置和圆点后是终结符还是非终结符或为空把项目分为以下几种:
  
  移进项目: 形如 A→α .a β ,a是终结符, a ,b∈V* 以下同
  待约项目:A→α .B β , 其中B是非终结符 
  归约项目:A→α . 表明产生式已分析完成。 
  接受项目:形如 S’→S .  
  特别的。A→ε的LR(0)项目只有A→ • 是归约项目
  
  因为LR分析表的构造前面两篇文章已经讲的很清楚了,所以这个题目重要是解释一下如何使用分析表来构造,分析表的构造也许你得自己参考前面两篇文章来构造了。题目来自网络。
  
  好,下面看题目,已知文法G[S]:
  
  (1) S → aAcBe
  (2) A → b 
  (3) A → Ab  
  (4) B → d
  
  写出对输入串 abbcde#的LR分析 过程。
  
  在分析的时候,因为我们的手工分析,所以还需要一个表来记录我们的步骤。否则记不住啊。该表共需7列。行数不定。做到哪是哪。
  

步骤符号栈输入符号栈动作状态栈ACTIONGOTO

  
  其中,步骤就是从1向下递增。符号栈用来保存运算中的结果,初始为#,输入符号栈保存输入串,初始值为给定的。动作里面就是用来注释是进行移进,还是规约。状态栈就是保持LR分析表的那个状态了。Action 和Goto同理
  
  通过前两篇文章的步骤,此题可以构造出如下的一张LR分析表
  
  


  
  分析表中有Si和rj大家都知道的。s是shift的缩写,也就是移进,r是reduce的缩写,也就是规约。规约是推导的逆操作,大家都懂。
  
  先来看看在进行分析的时候s和j操作的规则
  
  Si:移进,把i移入到状态栈,把a移入到文法符号栈。其中i,j表示状态号。
  
  ri:归约,用第i个产生式归约,同时状态栈与符号栈退出相应个符号,并把GOTO表相应状态和第i个产生式的左部非终结符入栈。
  
  文法中有A→β的产生式,若β的长度为r(即|β|=r),则从状态栈和文法符号栈中自栈顶向下去掉r个符号,即栈指针P减去r。并把A移入文法符号栈内,Sj=GOTO[Si,A]移进状态栈,其中Si为修改指针后的栈顶状态。
  
  当归约到文法符号栈中只剩文法的开始符号S时,并且输入符号串已结束即当前输入符是’#',则为分析成功。
  
  然后使用我们将要使用的辅助表来分析吧,为了简单。我还是直接给出答案。然后分析一下典型的情况。
  
  


  
  第一步,符号栈中是#,输入符号串就是给定的要分析的串,状态栈因为从0开始,所以状态栈直接填0,大家都知道,LR分析是从左到右扫描的。所以心里想着一根指针p,p首先指向输入串的a,然后我们查分析表的(0,a),0就是状态0,a就是指针的当前字符。分析表中的(0,a)是s2,填入第一步的action,并且动作列填入移进,根据规则,将2入状态栈,a入符号栈,
  
  进入第二步,指针p肯定要前进一步了,所以输入符号串就进入b了。此步同上一步,不多解释。
  
  关键是进入第三步后,此时,符号栈中为#ab,输入符号串是bcde#,状态栈是024,此时去查表,差的是(4,b),4是状态栈顶,b是p指针的当前位置。发现是r2,根据规则,用第二条产生式(2) A → b来规约。把动作栏先填了,同时状态栈与符号栈退出相应个符号,也即是说,把状态栏的栈顶4,退出来,同时符号栈的b也退出,心里想着,不填表,并把GOTO表相应状态和第i个产生式的左部非终结符入栈。Goto表需要查的是(2,A)=3,2是r2的2,A是第二个产生式的左部嘛。所以,就把3入状态栈,A入符号栈。
  
  后面的都是一样的。不解释了。要想学懂编译原理。多动手是必需的。你也手工试试吧。

参考:
   http://leaver.me/archives/574.html
   http://leaver.me/archives/548.html

转载于:https://www.cnblogs.com/lazycoding/archive/2012/05/14/2499130.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LR(0)文法是一种自底向上的语法分析方法,它使用一个分析栈来推导输入符号串的语法结构。构造LR(0)分析表需要以下步骤: 1. 对文法进行扩展,添加一个新的起始符号S',并将S' -> S作为新的产生式添加到文法中。 2. 构造DFA(确定有限状态自动机)来表示LR(0)自动机。每个DFA状态对应一个分析栈中的状态,其中包括当前所在的文法符号和已处理的输入符号。 3. 对于每个DFA状态,计算它可能的移进(shift)或规约(reduce)操作。如果在该状态下可以进行移进操作,则找出下一个输入符号,并将该符号和输入缓冲区中的下一个符号相比较。如果它们相同,则将该符号移入分析栈,并转移到新的状态。如果在该状态下可以进行规约操作,则找出可以使用哪个产生式进行规约,并将产生式右部的符号从分析栈中弹出。然后,将产生式左部的符号压入分析栈,并转移到新的状态。 4. 根据计算得到的移进和规约操作创建LR(0)分析表。表的行表示DFA状态,列表示输入符号。 下面是一个简单的例子,用于说明如何构造LR(0)分析表: 考虑下面的文法: S -> E E -> E+T | T T -> T*F | F F -> (E) | id 我们将文法进行扩展,添加一个新的起始符号S',并将S' -> S作为新的产生式添加到文法中。得到扩展后的文法如下: S' -> S S -> E E -> E+T | T T -> T*F | F F -> (E) | id 接下来,构造DFA来表示LR(0)自动机。以下是该自动机的状态转移图: ![image.png](attachment:image.png) 对于每个DFA状态,计算它可能的移进或规约操作。例如,对于状态I0,输入符号为E、T、F和(,因此可以进行移进操作,转移到状态I1、I2或I3。对于状态I5,已处理的输入符号为E、T、F和),因此可以进行规约操作,使用F -> id将id规约为F。以下是完整的移进和规约操作列表: I0: 移进E到I1 移进T到I2 移进F到I3 移进(到I4 I1: 规约E -> T 规约S -> E I2: 规约T -> F 规约E -> T 规约S -> E I3: 规约F -> id 规约T -> F 规约E -> T 规约S -> E I4: 移进E到I1 移进T到I2 移进F到I3 移进(到I4 I5: 规约F -> (E) 规约T -> T*F 规约E -> E+T 规约S -> E 接下来,我们可以根据计算得到的移进和规约操作创建LR(0)分析表。以下是该表的部分内容: ![image-2.png](attachment:image-2.png) 在表中,行表示状态,列表示输入符号。例如,表中的S5表示状态I5,表中的id表示输入符号id。表中的每个单元格包含两部分信息,一部分是移进或规约操作,另一部分是转移后的状态。例如,表中的r3表示使用产生式T -> F进行规约,而3表示转移到状态I3。 这就是如何构造文法的LR(0)分析表的过程。通过使用该表,可以对输入符号串进行自底向上的语法分析,得到输入符号串的语法结构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值