编译原理-至下而上的语法分析

文章目录

  • 至下而上分析的基本问题
    • 归约
    • 短语
    • `规范归约`
    • 符号栈的使用
  • 算符优先分析
    • 优先关系
    • 算符文法及优先关表构造
    • 如何求FIRSTVT和LASTVT
    • 算符优先分析算法
    • 优先函数

至下而上分析的基本问题

归约

用一个寄存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分归约成该产生式的左部符号
E − > i ∣ E + E ∣ E − E ∣ E ∗ E ∣ E / E ∣ ( E ) {E -> i|E + E|E-E|E*E|E/E|(E)} E>iE+EEEEEE/E(E)
输入符号串:
i ∗ i + i {i*i+i} ii+i
归约过程
E ∗ i + i ( 1 ) {E*i+i} \quad \quad (1) Ei+i(1)
E ∗ E + i ( 2 ) {E*E+i} \quad \quad (2) EE+i(2)
E + i ( 3 ) {E+i} \quad \quad (3) E+i(3)
E + E ( 4 ) {E+E} \quad \quad (4) E+E(4)
E ( 5 ) {E} \quad \quad (5) E(5)
例子:设文法G(S):
S − > a A c B e {S->aAcBe} S>aAcBe
A − > b {A->b} A>b
A − > A b {A->Ab} A>Ab
${b->d} $
试对 a b b c d e {abbcde} abbcde进行移进归约分析:
能进行归约就进行归约不能进行归约进行移进
编译原理-至下而上的语法分析_第1张图片
编译原理-至下而上的语法分析_第2张图片
编译原理-至下而上的语法分析_第3张图片
编译原理-至下而上的语法分析_第4张图片
此时我们进行归约的话就会出现矛盾,b是第二个推导的产生式,Ab是第二个产生式的候选式,这里我们选择第二种进行归约
编译原理-至下而上的语法分析_第5张图片
编译原理-至下而上的语法分析_第6张图片
编译原理-至下而上的语法分析_第7张图片
编译原理-至下而上的语法分析_第8张图片
在不能归约时我们就移进
编译原理-至下而上的语法分析_第9张图片

短语

定义:令G是一个文法,S是文法的开始符号,假定 α β δ {\alpha \beta \delta} αβδ是文法G的一个句型,如果有:
image
就称 β \beta β是句型 α β δ {\alpha \beta \delta} αβδ相对于非终结符 A {A} A的短语
如果有 A = > β {A => \beta} A=>β,则称 β \beta β是句型 α β δ {\alpha \beta \delta} αβδ相对于产生式 A − > B A->B A>B直接短语,一个句型的最左直接短语称为该句型的句柄
一个句型对应的语法树中

  1. 以某非终结符为根的两代以上的子树的所有末端结点从左到右排列就是相对于该非终结符的一个短语
  2. 如果子树只有两代,则改短语是直接短语

句柄可以被用来对句子进行归约

规范归约

定义:假定 α \alpha α是文法 G G G的一个句子,我们称序列
α n , α n − 1 , . . . , α 0 {\alpha_n, \quad \alpha_n-1, \quad ... \quad, \alpha_0} αn,αn1,...,α0
α \alpha α的一个规范归约,如果此序列满足:
1. α n = α {1. \alpha_n = \alpha} 1.αn=α
2. α 0 为文法的开始符号,即 α 0 = S {2. \alpha_0为文法的开始符号,即\alpha_0=S} 2.α0为文法的开始符号,即α0=S
3. 对于任何 i , 0 < i < = n , α i − 1 是从 α i 经句柄替换成相应产生式左部符号而得到的 {3.对于任何i, 0 < i<= n,\alpha_{i - 1}是从\alpha_i经句柄替换成相应产生式左部符号而得到的} 3.对于任何i0<i<=nαi1是从αi经句柄替换成相应产生式左部符号而得到的
规范推导:我们将规范归约的过程逆过来就是规范推导,规范推导也经常被称为最右推导
由规范推导推出来的句型被称为规范句型

符号栈的使用

  1. 栈是语法分析的一种基本数据结构, # \# #作为栈底符号
    文法 G ( E ) : G(E): G(E):
    E − > T ∣ E + T E->T|E+T E>TE+T
    T − > F ∣ T ∗ F T->F|T*F T>FTF
    F − > ( E ) ∣ i F->(E)|i F>(E)i
    输入串为 i 1 ∗ i 2 + i 3 i_1*i_2+i_3 i1i2+i3的分析过程
    编译原理-至下而上的语法分析_第10张图片
    编译原理-至下而上的语法分析_第11张图片
    编译原理-至下而上的语法分析_第12张图片

算符优先分析

  1. 算符优先就是定义算符之间(终结符之间)的某种优先关系,借助优先关系来寻找可归约串和进行归约
    考虑二义文法 G ( E ) : i ∣ E + E ∣ E − E ∣ E ∗ E ∣ E / E ∣ ( E ) G(E) \quad: \quad i|E+E|E-E|E*E|E/E|(E) G(E):iE+EEEEEE/E(E)
    这个句子由几种不同的规范归约
    例如句子 i + i − i ∗ ( i + i ) i+i-i*(i + i) i+ii(i+i)的规约过程(按四则运算的优先顺序)
    ( 1 ) i + i − i ∗ ( i + i ) (1) \quad {i + i - i * (i + i)} (1)i+ii(i+i)
    ( 2 ) E + i − i ∗ ( i + i ) (2) \quad {E + i - i * (i + i)} (2)E+ii(i+i)
    ( 3 ) E + E − i ∗ ( i + i ) (3) \quad {E + E - i * (i + i)} (3)E+Ei(i+i)
    ( 4 ) E − i ∗ ( i + i ) (4) \quad {E - i * (i + i)} (4)Ei(i+i)
    ( 5 ) E − E ∗ ( i + i ) (5) \quad {E - E * (i + i)} (5)EE(i+i)
    ( 6 ) E − E ∗ ( E + i ) (6) \quad {E - E * (E + i)} (6)EE(E+i)
    ( 7 ) E − E ∗ ( E + E ) (7) \quad {E - E * (E + E)} (7)EE(E+E)
    ( 8 ) E − E ∗ ( E ) (8) \quad {E - E * (E)} (8)EE(E)
    ( 9 ) E − E ∗ E (9) \quad {E - E * E} (9)EEE
    ( 10 ) E − E (10) \quad {E - E} (10)EE
    ( 11 ) E (11) \quad {E} (11)E

优先关系

编译原理-至下而上的语法分析_第13张图片

算符文法及优先关表构造

算符文法:一个文法,如果它的任一产生式的右部都不含两个相继(并列)的非终结符,即不含如下形式的产生式右部: . . . Q R . . . ...QR... ...QR...,则我们称该文法为算符文法
约定:
a 、 b 代表任意终结符 a、b代表任意终结符 ab代表任意终结符
P 、 Q 、 R 代表任意非终结符 P、Q、R代表任意非终结符 PQR代表任意非终结符
. . . 代表由终结符和非终结符组成的任意序列,包括空字 ...代表由终结符和非终结符组成的任意序列,包括空字 ...代表由终结符和非终结符组成的任意序列,包括空字

"等于":image
"小于":
编译原理-至下而上的语法分析_第14张图片
"大于":
编译原理-至下而上的语法分析_第15张图片
编译原理-至下而上的语法分析_第16张图片
FIRSTYT:编译原理-至下而上的语法分析_第17张图片

LASTVT:编译原理-至下而上的语法分析_第18张图片
比较:
编译原理-至下而上的语法分析_第19张图片
算符优先关系表
有了FIRSTVTLASTVT这两个概念后,我们就可以用算法构造优先关系表

编译原理-至下而上的语法分析_第20张图片
我们只需对每个产生式检查一遍,把所有优先关系都找到就可以了

如何求FIRSTVT和LASTVT

编译原理-至下而上的语法分析_第21张图片
编译原理-至下而上的语法分析_第22张图片

算符优先分析算法

素短语:至少包含一个终结符,并且除了它自身外不包含任何更小的素短语,最左素短语就是句型最左边的素短语
我们考虑句型:
# N 1 a 1 N 2 a 2 . . . N n a n N n + 1 # \# N_1 a_1 N_2 a_2 ... N_n a_n N_{n+1} \# #N1a1N2a2...NnanNn+1#
其中每一个 a i a_i ai都是终结符, N i N_i Ni都是可有可无的非终结符。
一个算符优先文法G的任何上述句型的最左素短语是满足如下条件的最左子串 N j a j . . . N i a i N i + 1 {N_ja_j...N_ia_iN_{i + 1}} Njaj...NiaiNi+1
image
算法
编译原理-至下而上的语法分析_第23张图片

优先函数

我们在通常实现上面算法的时候在判断优先关系的时候一般不采用查表的方法而是用两个优先函数,优先函数可以将原来 N ∗ N N * N NN的时间复杂度降低到 2 ∗ N 2 * N 2N,缺点是原来可能两个符号不可比较优先级,但是经过优先函数之后会映射到自然数从而导致可以比较,这样会导致一些错误
image
f被称为栈优先函数
g被称为比较优先函数
如何构造优先函数(证明过程略)
编译原理-至下而上的语法分析_第24张图片
经过构造完的优先函数需要我们进一步检验是否正确

你可能感兴趣的:(编译原理,数据结构,算法,django,python,java)