✏️

语法分析

Created
Sep 25, 2024 02:20 AM

问题

二义性、左递归问题和回溯问题
正则文法有二义性、可判定
存在某句型 v.t. 不同推导规则 → 两棵语法树,句柄不同
上下文无关(CFG)的二义性不可判定
 

自顶向下

带回溯的自顶向下分析方法

从根节点遍历文法树,匹配一个句子
极慢
 

消除左递归

  • 提因子:右式中公共部分可以提出来,压缩文件长度
  • 递归部分 → { Vt+ }
  • 转为右递归:
    • S → (左递归下的起始符号)S’
    • S’ → 左递归的可重复部分S’ | ε
  • 文法可能有间接子递归,通过将规则一条条带下去找到直接子递归
 
 

消除回溯

定义:对于文法U::= α1 | … | αn
无回溯的条件是对任意i≠j, First(αi) ∩ First(αj) = φ
消除方法
  • 反复提取左因子:若两个αi的First集相同,则提出来放在U的右式的最左边
    • U::= (<publicFirst> αi’ | αj’) | (…)
 

递归下降分析法(递归子程序法)

先把文法左递归消除掉
对每个非终结符,生成其对应的分析程序
算法流程是对一个输入串,从左往右依次读,终结符就直接判断,非终结符调用分析程序判断
notion image
 
 

含有ε的情况

follow(A): 所有句型中,紧挨A后面的终结符集合
S为识别符号
FOLLOW(A) = {a | Z ⇒* …Aa…}, a∈Vt
识别算法:
notion image
 

文法无回溯的充分必要条件

对于A的任意两条规则A ::= α | β
  • FIRST(α) ∩ FIRST(β) = Φ
  • 若β ⇒* ε,则还需满足FIRST(α) ∩ FOLLOW(A) = Φ
 
 

LL(1)分析法

适用于满足无二义无回溯无左递归的语法
维护一个符号表(二维矩阵)和符号栈
符号表
是一个Vt × Vn的二维矩阵
填表规则
  • A → αi
    • A ⇒ αi 且 ( a ∈ FIRST(αi) 或 (αi ⇒* ε 且 a ∈ FOLLOW(A) )
 
在分析非终结符A时,若匹配到的输入串的第一个字符为a,则将A替换成αi
 
符号栈
匹配的时候用
先push(#) 和 (识别符号),指针ptr指向匹配串的最左侧
迭代分析过程:
对栈顶元素E
if E ∈ Vt
pop()
ptr右移一位
else if E ∈ Vn
*ptr → a,查T(E, a)
if A → αi
pop()
将αi从右往左依次push(目的是保证Leftmost)
else
error
else if E = #
if ptr = 匹配串终结符
end
else
error