Skip to content

第七章 自上而下的语法分析

Giovanna

About 1168 wordsAbout 4 min

2024-07-02

自上而下的语法分析:从开始符号S出发,看能否找到一个最右推导,使得S⇒ωS\Rightarrow \omega;或从S出发,能否构成一个语法树,使得树的叶节点自左向右构成ω\omega。

一、回溯分析法

1. 提取公共左因子

A→αβ1∣αβ2∣…∣αβn∣δ A\to \alpha\beta_1|\alpha\beta_2|\ldots|\alpha\beta_n|\delta

提取公共左因子后:

A→αB∣δB→β1∣β2∣…∣βn \begin{aligned} A\to &\alpha B|\delta \\ B\to &\beta_1|\beta_2|\ldots|\beta_n \end{aligned}

2. 消除左递归

消除直接左递归

直接左递归:文法中直接出现左递归,即有形如A→AαA\to A\alpha的产生式。

A⇒Aα⇒Aαα⇒… A\Rightarrow A\alpha\Rightarrow A\alpha\alpha\Rightarrow\ldots

产生无限推导。

将左递归的产生式改写成等价的右递归的产生式。

A→Aα1∣Aα2∣…∣Aαn∣β A\to A\alpha_1|A\alpha_2|\ldots|A\alpha_n|\beta

改写后:

A→βA′A′→α1A′∣α2A′∣…∣αnA′∣ε \begin{aligned} A\to &\beta A' \\ A'\to &\alpha_1A'|\alpha_2A'|\ldots|\alpha_nA'|\varepsilon \end{aligned}

消除间接左递归

间接左递归:通过推导产生的左递归。

S→AaA→Sb∣c \begin{aligned} S\to &Aa\\ A\to &Sb|c \end{aligned}

S⇒Aa⇒Sba⇒Aaba⇒Sbaba⇒… S\Rightarrow Aa\Rightarrow Sba\Rightarrow Aaba\Rightarrow Sbaba\Rightarrow\ldots

存在间接左递归同样会产生无限推导。

例:

S→Qc∣cQ→Rb∣bR→Sa∣a \begin{aligned} S\to &Qc|c\\ Q\to &Rb|b\\ R\to &Sa|a \end{aligned}

  1. 用R代入Q

Q→Sab∣ab∣b Q\to Sab|ab|b

  1. 用Q代入S

S→Sabc∣abc∣bc∣c S\to Sabc|abc|bc|c

消除直接左递归:

S→abcS′∣bcS′∣cS′S′→abcS′∣ε \begin{aligned} S\to &abcS'|bcS'|cS'\\ S'\to &abcS'|\varepsilon \end{aligned}

  1. Q和R为多余可删除,最后答案如上式

二、递归下降分析法

当文法改造为无公共左因子,无左递归时,让每个非终结符对应一个过程,该过程对相应的非终结符产生式的右部短语进行语法分析。

文法G={E→T∣E+T,T→F∣T∗F,F→(E)∣i}G=\{E\to T|E+T,T\to F|T*F,F\to (E)|i\},消除左递归后得到:

E→TE′E′→+TE′∣εT→FT′T′→∗FT′∣εF→(E)∣i \begin{aligned} E\to &TE'\\ E'\to &+TE'|\varepsilon\\ T\to &FT'\\ T'\to &*FT'|\varepsilon\\ F\to &(E)|i \end{aligned}

对输出串i+i∗ii+i*i的执行过程:

image.png

扩充的BNF

  • {α}\{\alpha\}表示α\alpha的0到任意多次重复,即α∗\alpha^*
  • {α}0n\{\alpha\}_0^n表示0次到n次重复,{α}00={α}0=ε\{\alpha\}_0^0=\{\alpha\}^0=\varepsilon
  • [α][\alpha]表示α\alpha可有可无(即α∣ε\alpha|\varepsilon)

文法G可以改写为:

E→T{+T}T→F{∗F}F→i∣(E) \begin{aligned} E\to &T\{+T\}\\ T\to &F\{*F\}\\ F\to &i|(E) \end{aligned}

i+i∗ii+i*i的分析过程:

image.png

三、预测分析法

是一种表驱动方法,由下推栈、预测分析表和控制程序组成,它实际上是一种下推自动机的实现模型。

预测分析表

  • 形式:M[A,a]M[A,a]矩阵,A∈VNA\in V_N,a∈VT∪{#}a\in V_T\cup\{\#\}
  • 内容:A→αA\to\alpha或出错标志(空白)

例:文法G={E→T∣E+T,T→F∣T∗F,F→(E)∣i}G=\{E\to T|E+T,T\to F|T*F,F\to (E)|i\},消除左递归后得到

E→TE′E′→+TE′∣εT→FT′T′→∗FT′∣εF→(E)∣i \begin{aligned} E\to &TE'\\ E'\to &+TE'|\varepsilon\\ T\to &FT'\\ T'\to &*FT'|\varepsilon\\ F\to &(E)|i \end{aligned}

1. 构造FIRST集和FOLLOW集

FIRST集:

  • A→a…A\to a\ldots,a∈FIRST(A)a\in FIRST(A)
  • A→B…A\to B\ldots,FIRST(B)⊂FIRST(A)FIRST(B)\subset FIRST(A)
  • A→BC…A\to BC\ldots,BB可产生ε\varepsilon,FIRST(C)⊂FIRST(A)FIRST(C)\subset FIRST(A)

FOLLOW集:

  • #∈FOLLOW(S)\#\in FOLLOW(S)
  • S→…Aa…S\to\ldots Aa\ldots,a∈FOLLOW(A)a\in FOLLOW(A)
  • S→…AB…S\to\ldots AB\ldots,FIRST(B)−ε⊂FOLLOW(A)FIRST(B)-\varepsilon\subset FOLLOW(A)
  • S→…AS\to\ldots A,FOLLOW(S)⊂FOLLOW(A)FOLLOW(S)\subset FOLLOW(A)
  • S→…ABS\to\ldots AB,BB可以产生ε\varepsilon,FOLLOW(S)⊂FOLLOW(A)FOLLOW(S)\subset FOLLOW(A)
FIRSTFOLLOW
E( i) #
E'+ ε) #
T( i+ ) #
T'* ε+ ) #
F( i* + ) #

2. 构造预测分析表

  • 横VTV_T与#\#,纵VNV_N
  • a∈FIRST(A)a\in FIRST(A),[A,a][A,a]填对应产生式
  • AA可以产生ε\varepsilon,a∈FOLLOW(A)a\in FOLLOW(A),[A,a][A,a]填A→εA\to\varepsilon
i*+()#
EE->TE'E->TE'
E'E'->+TE'E'->εE'->ε
TT->FT'T->FT'
T'T'->*FT'T'->εT'->εT'->ε
FF->iF->(E)

3. 预测分析过程

  • 栈、输入串、归约
  • 栈放#S\#S
  • 根据栈顶与当前字符查表归约,产生式右部倒序入栈
  • [#,#]=acc[\#,\#]=acc
栈输入串归约
#Ei+i*i#E->TE'
#E'Ti+i*i#T->FT'
#E'T'Fi+i*i#F->i
#E'T'+i*i#T'->ε
#E'+i*i#E'->+TE'
#E'Ti*i#T->FT'
#E'T'Fi*i#F->i
#E'T'*i#T'->*FT'
#E'T'Fi#F->i
#E'T'#T'->ε
#E'#E'->ε
##acc

4. LL(1)文法

设有文法GG,若它的任一产生式A→α1∣α2∣…∣αnA\to\alpha_1|\alpha_2|\ldots|\alpha_n,均满足:

  • FIRST(αi)∩FIRST(αj)=∅FIRST(\alpha_i)\cap FIRST(\alpha_j)=\varnothing,其中i≠ji\neq j,i,j=1,2,…,ni,j=1,2,\ldots,n
  • 若αi⇒+ϵ\alpha_i{\overset{+}{\Rightarrow}}\epsilon,则FIRST(αj)∩FOLLOW(A)=∅FIRST(\alpha_j)\cap FOLLOW(A)=\varnothing,j=1,2,…,nj=1,2,\ldots,n且j≠ij\neq i

则文法G称为LL(1)文法。

自上而下分析时,若当前输入字符为aa,分析栈待匹配的非终结符为A,A→α1∣α2∣…∣αnA\to\alpha_1|\alpha_2|\ldots|\alpha_n,则当

  • a∈FIRST(αi)a\in FIRST(\alpha_i)
  • 若αi⇒+ϵ\alpha_i{\overset{+}{\Rightarrow}}\epsilon,a∈FOLLOW(A)a\in FOLLOW(A)

则A→αiA\to \alpha_i便是唯一与aa匹配的产生式。即LL(1)文法中的两个条件保证了自上而下匹配的唯一性。

Note

预测分析表没有多重入口,则该文法是LL(1)文法。