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. 消除左递归

消除直接左递归

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

AAαAαα A\Rightarrow A\alpha\Rightarrow A\alpha\alpha\Rightarrow\ldots

产生无限推导。

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

AAα1Aα2Aαnβ A\to A\alpha_1|A\alpha_2|\ldots|A\alpha_n|\beta

改写后:

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

消除间接左递归

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

SAaASbc \begin{aligned} S\to &Aa\\ A\to &Sb|c \end{aligned}

SAaSbaAabaSbaba S\Rightarrow Aa\Rightarrow Sba\Rightarrow Aaba\Rightarrow Sbaba\Rightarrow\ldots

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

例:

SQccQRbbRSaa \begin{aligned} S\to &Qc|c\\ Q\to &Rb|b\\ R\to &Sa|a \end{aligned}

  1. 用R代入Q

QSababb Q\to Sab|ab|b

  1. 用Q代入S

SSabcabcbcc S\to Sabc|abc|bc|c

消除直接左递归:

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

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

二、递归下降分析法

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

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

ETEE+TEεTFTTFTε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+iii+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可以改写为:

ET{+T}TF{F}Fi(E) \begin{aligned} E\to &T\{+T\}\\ T\to &F\{*F\}\\ F\to &i|(E) \end{aligned}

i+iii+i*i的分析过程:

image.png

三、预测分析法

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

预测分析表

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

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

ETEE+TEεTFTTFTε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集:

  • AaA\to a\ldotsaFIRST(A)a\in FIRST(A)
  • ABA\to B\ldotsFIRST(B)FIRST(A)FIRST(B)\subset FIRST(A)
  • ABCA\to BC\ldotsBB可产生ε\varepsilonFIRST(C)FIRST(A)FIRST(C)\subset FIRST(A)

FOLLOW集:

  • #FOLLOW(S)\#\in FOLLOW(S)
  • SAaS\to\ldots Aa\ldotsaFOLLOW(A)a\in FOLLOW(A)
  • SABS\to\ldots AB\ldotsFIRST(B)εFOLLOW(A)FIRST(B)-\varepsilon\subset FOLLOW(A)
  • SAS\to\ldots AFOLLOW(S)FOLLOW(A)FOLLOW(S)\subset FOLLOW(A)
  • SABS\to\ldots ABBB可以产生ε\varepsilonFOLLOW(S)FOLLOW(A)FOLLOW(S)\subset FOLLOW(A)
FIRSTFOLLOW
E( i) #
E'+ ε) #
T( i+ ) #
T'* ε+ ) #
F( i* + ) #

2. 构造预测分析表

  • VTV_T#\#,纵VNV_N
  • aFIRST(A)a\in FIRST(A)[A,a][A,a]填对应产生式
  • AA可以产生ε\varepsilonaFOLLOW(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,其中iji\neq ji,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)=\varnothingj=1,2,,nj=1,2,\ldots,njij\neq i

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

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

  • aFIRST(αi)a\in FIRST(\alpha_i)
  • αi+ϵ\alpha_i{\overset{+}{\Rightarrow}}\epsilonaFOLLOW(A)a\in FOLLOW(A)

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

Note

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