编译原理学习笔记(五)——自下而上语法分析

归约:指根据文法的产生式规则,把产生式的右部换成左部符号
短语:令G是一个文法,S是文法的开始符号,假定ɑβδ是文法G的一个句型,如果S闭包有ɑβδ且A可以推出β,则β是句型ɑβδ对于A的短语
直接短语:A得到β是规则中明确的
句柄:句型的最左直接短语
规范规约:假定ɑ为文法G的一个句子,则把从ɑ通过把句柄替换成相应产生式的一系列式子成为规范规约

将规范规约顺序颠倒即是一个最右推导

用符号栈进行自下而上的语法分析:

先将#入栈,作为栈底,并将#作为输入串的结束符
自左向右对输入串不断入栈,并进行移进归约
直到形成“#S

算法优先分析法:定义算符之间的优先关系,借助这种关系来寻找可归约串,并进行归约
算法文法:文法中的任一产生式都不包含两个连续的非终结符,则为算法文法,即OG文法
定义终结符之间的优先关系:

  1. a=.b:文法中含有P→…ab…或…aQb…的产生式
  2. a<.b:文法中含有P→…aR…的产生式而R→b…或R→+Qb…
  3. a>.b:含P→…Rb…,而R→…a或R→…aQ

如果算符文法G中的任何终结符对(a,b)至多只有一种优先关系,则是一个算符优先文法
构造算法优先关系表:


  1. 先找满足a=.b
  2. 对G中的每个非终结符P构造集合FIRSTVT(P)和LASTVT(P):

FIRSTTVT(P)={a|P→+a…,或P→Qa…}
LASTVT(P)={a|P→+…a,或P→…aQ}

  • 对一个产生式为…aP…型,则对任何b∈FIRSTVT(P)有a<.b

  • 对…Pb…型,对任何a∈LASTVT(P),有a>.b

    对于#,相当于在开始符号S前加一个额外的开始符号,比如Z→#S#添加到原文法中,再进行分析


  • 算符优先分析算法的设计
    分析:移进归约:句柄为可归约串 算符优先分析法:最左素短语为可归约串
    素短语:指一个句型的短语,至少包括一个终结符且除去它本身之外不在含有任何更小的素短语
    最左素短语:句型最左的素短语

    句型的一般表示形式:

    优先函数:

    把每个终结符θ与两个自然数f(θ)与g(θ)相对应,使得
    若θ1 <. θ2,则f(θ1) < g(θ2)
    若θ1 =. θ2,则f(θ1) = g(θ2)
    若θ1 >. θ2,则f(θ1) > g(θ2)

    f称为入栈优先函数,g称为比较优先函数

    如果优先函数存在,则可以通过以下三个步骤从优先表构造优先函数:

    (1)对于每个终结符a,令其对应两个符号fa和ga,画一张以所有符号fa和ga为结点的方向图。

    如果a>.b,则从fa画一条弧至gb

    如果a<.b,则从gb画一条弧至fa

    (2)对每个结点都赋予一个数,此数等于从该结点出发所能到达的结点(包括出发点自身)。

    赋给fa的数作为f(a)

    赋给ga的数作为g(a)

    (3)检查所构造出来的函数f和g是否与原来的关系矛盾。若没有矛盾,则f和g就是要求的优先函数,若有矛盾,则不存在优先函数


    LR分析法:

    LR分析器栈的结构:

    动作表:

    ACTION[s,a]:当状态s面临输入符号a时,应采取什么动作

    状态转换表:

    GOTO[s,X]:状态s面对文法符号X时,下一状态是什么

    ACTION[s,a]所规定的四种动作:
    <1>. 移进 :把(s,a)的下一状态s’=GOTO[s,a] 和输入符号a推进栈,下一输入符号变成现行输入符号
    <2>. 归约 :指用某产生式A→β进行归约. 假若β的长度为r, 归约动作是A, 去除栈顶r个项,使状态sm-r变成栈顶状态,然后把(sm-r, A)的下一状态s’=GOTO[sm-r, A]和文法符号A推进栈
    <3>. 接受 :宣布分析成功,停止分析器工作

    <4>. 报错 :发现源程序含有错误,调用出错处理程序

    LR分析过程:

    第一步 分析开始时,首先将初始状态SO及句子左界符#推入分析栈中

    第二步 以栈顶的状态及正扫视的输入符号ai组成符号对(Sm,ai)去查分析动作表,并根据表元ACTION[Sm,ai]的指示完成相应的分析动作

    每一分析表元所规定的动作,仅能是下列四种动作之一:

    (1)若ACTION[Sm,ai]=“移进”,这表明句柄尚未在栈顶部形成,此时正期待继续移进输入符号以形成句柄,故将当前的输入符号推入栈中:

    然后,以符号对(Sm,ai)查状态转移表,设相应的表元GOTO [Sm,ai]= Sm+1,再将此新的状态(即要转移到的下一状态)推入栈中
    

    (2)若ACTION[Sm,ai]= rj ,其中rj意指按文法的第j个产生式A→Xm-r+1 Xm-r+2…Xm进行归约

    将分析栈从顶向下的r个符号(因为该产生式右部符号串的长度为r)退出,然后再将文法符号A推入栈中
    
    然后,以(Sm-r ,A)查状态转移表,设GOTO [Sm-r,A]=Sl,将此新状态推入栈中
    

    (3)若ACTION[Sm,ai]=“接受”,则表明当前的输入串已被成功地分析完毕,应中止分析器的工作

    (4)若ACTION[Sm,ai]=ERROR,则表明当前的输入串中有语法错误,也应终止分析器的工作

    LR(k)文法:最多向前看K个的符号就可以决定动作的LR分析器所分析的文法成为LR(k)文法

    活前缀:文法G的活前缀是他的规范句型的前缀,该前缀不超过句柄的右端

    LR(0)项目:在每个产生式的右部适当位置添加一个圆点构成项目

    构造识别活前缀的NFA:

    1、构造文法的所有产生式的项目,每个项目都为NFA的一个状态

    2、确定初态、句柄识别态、句子识别态

        由于S′(起始符)仅在第一产生式的左部出现 ,因此规定起始符相关的项目1为初态 
    
        其余每个状态都为活前缀的识别态(终态)
    
    圆点在最后的项目为句柄识别态 
    
        第一个产生式的句柄识别态为句子识别态 
    

    状态之间的转换关系确定方法如下:

        若项目i为X→X1X2...Xi-1 • Xi…Xn
    
        项目j为X→X1X2...Xi-1Xi • Xi+1…Xn。
    

      则从状态i到状态j连一条标记为Xi的箭弧s

        若i为X→γ•Aβ,k为A→•β,
    
        则从状态i画标记为ε的箭弧到状态k
    

    把识别文法所有活前缀的NFA确定化:

        用子集法,把项目集变为状态
    

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

    1.构造G的拓广文法G’

    2.I的闭包CLOSURE(I)

    (1) I的任何项目都属于CLOSURE(I)

    (2) 若A→α·Bβ属于CLOSURE(I),那么,对任何关于B的产生式B→γ的项目B→·γ也属于CLOSURE(I);

    (3) 重复执行上述两步骤直至CLOSURE(I) 不再增大为止

    3.转换函数

    GOTO(I,X)=CLOSURE(J)其中:

    I为包含某一项目集的状态,

    X为一文法符号,

    J={任何形如A→αX•β的项目|A→α•Xβ属于I}

    构造识别文法活前缀DFA的两种方法:

    1、求出文法的所有项目,按一定规则构造识别活前缀的NFA再确定化为DFA

    2、把拓广文法的第一个项目{S′→·S}作为初态集的核,通过求核的闭包和转换函数, 求出LR(0)项目集规范族,再由转换函数建立状态之间的连接关系得到识别活前缀的DFA

    LR(0)项目集规范族的项目类型分为如下四种:

    1)移进项目 A →α•aβ
    2)待约项目 A →α•Bβ
    3)归约项目 A →α•

    4)接受项目 S’→S •

    其LR(0)项目集规范族不存在移进-归约,或归约-归约冲突,称为LR(0)文法

    LR(0)分析表的ACTION和GOTO表的构造步骤:

    a)若项目A→α•aβ属于Ik,且转换函数GO(Ik,a)=Ij,当a为终结符时 ,则置ACTION[k,a]为Sj。

    b)若项目A→α•属于Ik, 则对a为任何终结符或#′,置ACTION[k,a]=rj, j为产生式在文法G′中的编号。

    c)若GO(Ik,A)=Ij,则置GOTO[k,A]=j,其中A为非终结符,j为某一状态号。

    d)若项目S′→S•属于Ik,则置ACTION[k,#]= acc。

    e)其它填上“报错标志”。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值