提纲
语法分析方法 LL(1) 左递归消除 一个文法含有下列形式的产生式时, 称为左递归文法, 不能采用自顶向下分析法
直接递归
A → A β , A ∈ V N A\rightarrow A\beta, A\in V_N A → A β , A ∈ V N ,β \beta β ∈ \in ∈ V*
间接递归
A → B β A\rightarrow B\beta A → Bβ
B → A α , A , B ∈ V N , α , β ∈ V ∗ B\rightarrow A\alpha, A,B\in V_N, \alpha, \beta\in V^* B → A α , A , B ∈ V N , α , β ∈ V ∗
左递归消除
P → P α 1 ∣ P α 2 ∣ . . . ∣ P α m ∣ β 1 ∣ β 2 ∣ . . . ∣ β n P\rightarrow P\alpha_1|P\alpha_2|...|P\alpha_m|\beta_1|\beta_2|...|\beta_n P → P α 1 ∣ P α 2 ∣...∣ P α m ∣ β 1 ∣ β 2 ∣...∣ β n
改写为
P → β 1 P ′ ∣ β 2 P ′ ∣ . . . ∣ β n P ′ P\rightarrow\beta_1 P'|\beta_2 P'|...|\beta_n P' P → β 1 P ′ ∣ β 2 P ′ ∣...∣ β n P ′
P ′ → α 1 P ′ ∣ α 2 P ′ ∣ . . . ∣ α m P ′ ∣ ε P'\rightarrow\alpha_1 P'|\alpha_2 P'|...|\alpha_m P'|\varepsilon P ′ → α 1 P ′ ∣ α 2 P ′ ∣...∣ α m P ′ ∣ ε
FIRST, FOLLOW 终结首符集:F I R S T ( α ) = { a ∣ α ⇒ ∗ a . . . , a ∈ V T } , 特别地 , 如果 α ⇒ ∗ ε , 则规定 ε ∈ F I R S T ( α ) FIRST(\alpha)=\{a|\alpha\Rightarrow^*a...,a\in V_T\}, \\特别地, 如果\alpha\Rightarrow^*\varepsilon, 则规定\varepsilon\in FIRST(\alpha) F I RST ( α ) = { a ∣ α ⇒ ∗ a ... , a ∈ V T } , 特别地 , 如果 α ⇒ ∗ ε , 则规定 ε ∈ F I RST ( α )
后继终结符号集:F O L L O W ( A ) = { a ∣ S ⇒ ∗ . . . A a . . . , a ∈ V T } , 特别地 , 如果 S ⇒ ∗ . . . A , 则规定 # ∈ F O L L O W ( S ) FOLLOW(A)=\{a|S\Rightarrow^*...Aa...,a\in V_T\}, \\特别地, 如果S\Rightarrow^*...A, 则规定\#\in FOLLOW(S) FO LL O W ( A ) = { a ∣ S ⇒ ∗ ... A a ... , a ∈ V T } , 特别地 , 如果 S ⇒ ∗ ... A , 则规定 # ∈ FO LL O W ( S )
LL(1)文法 可以进行无回溯的自上而下分析
不含左递归 产生式右侧的所有非终结符的FIRST集无交集A → α 1 ∣ α 2 ∣ . . . ∣ α n ⇒ F I R S T ( α i ) ∩ F I R S T ( α j ) = Φ , ( i ≠ j ) A\rightarrow\alpha_1|\alpha_2|...|\alpha_n\Rightarrow FIRST(\alpha_i)\cap FIRST(\alpha_j)=\Phi, (i\neq j) A → α 1 ∣ α 2 ∣...∣ α n ⇒ F I RST ( α i ) ∩ F I RST ( α j ) = Φ , ( i = j ) 若ε ∈ F I R S T ( A ) \varepsilon\in FIRST(A) ε ∈ F I RST ( A ) , 则F I R S T ( A ) ∩ F O L L O W ( A ) = Φ FIRST(A)\cap FOLLOW(A)=\Phi F I RST ( A ) ∩ FO LL O W ( A ) = Φ LL(1)分析方法 当前输入符号为a a a , 要匹配一个A A A , 且A → α 1 ∣ α 2 ∣ . . . ∣ α n A\rightarrow\alpha_1|\alpha_2|...|\alpha_n A → α 1 ∣ α 2 ∣...∣ α n 若a ∈ F I R S T ( α i a\in FIRST(\alpha_i a ∈ F I RST ( α i )集合, 则直接匹配A → α i A\rightarrow\alpha_i A → α i 若ε ∈ F I R S T ( A ) \varepsilon\in FIRST(A) ε ∈ F I RST ( A ) , 但是a ∈ F O L L O W ( A ) a\in FOLLOW(A) a ∈ FO LL O W ( A ) 中, 仍可以匹配 否则报错 LL(1)程序构造 递归下降程序 预测分析程序 使用分析表和符号栈实现LL(1)分析
需要预先构造分析表
略
规范规约 短语 :
对于文法 G , 开始符号 S , 若 α β δ 是一个句型 , 如果 S ⇒ ∗ α A δ 且 A ⇒ + β , 则称 β 是句型 α β δ 相对于 A 的短语 对于文法G, 开始符号S, 若\alpha\beta\delta是一个句型, 如果S\Rightarrow^*\alpha A\delta且A\Rightarrow^+\beta, 则称\beta是句型\alpha\beta\delta相对于A的短语 对于文法 G , 开始符号 S , 若 α β δ 是一个句型 , 如果 S ⇒ ∗ α A δ 且 A ⇒ + β , 则称 β 是句型 α β δ 相对于 A 的短语 句型语法树中每棵子树的所有叶子结点左右到右排列起来构成一个该句型相对于子树根 ( A ) 的短语 句型语法树中每棵子树的所有叶子结点左右到右排列起来构成一个该句型相对于子树根(A)的短语 句型语法树中每棵子树的所有叶子结点左右到右排列起来构成一个该句型相对于子树根 ( A ) 的短语 直接短语 :
A ⇒ β A\Rightarrow\beta A ⇒ β 只有父子两代的子树形成的短语 , 一步推导出终结符的子树 只有父子两代的子树形成的短语, 一步推导出终结符的子树 只有父子两代的子树形成的短语 , 一步推导出终结符的子树 句柄 :
一个句型的最左直接短语 一个句型的最左直接短语 一个句型的最左直接短语 语法树中最左的只有父子两代的子树形成的短语 语法树中最左的只有父子两代的子树形成的短语 语法树中最左的只有父子两代的子树形成的短语
句型E+T*F
的
短语为E+T*F
(相对于E), T*F
(相对于T) 直接短语为T*F
句柄为T*F
算符优先分析法 算符优先文法 算符文法: 任一产生式的右部都不包含两个相继(并列)的非终结符
最多一个优先关系: 对任何一对终结符, (a,b)最多满足一个优先关系
算符优先文法: 满足最多一个优先关系的算符文法
优先关系表 优先关系的表格
FIRSTVT, LASTVT F I R S T V T ( P ) = { a ∣ P ⇒ + a . . . 或 P ⇒ + Q a . . . , a ∈ V T 而 Q ∈ V N } FIRSTVT(P)=\{a|P\Rightarrow^+a...或P\Rightarrow^+Qa..., a\in V_T而Q\in V_N\} F I RST V T ( P ) = { a ∣ P ⇒ + a ... 或 P ⇒ + Q a ... , a ∈ V T 而 Q ∈ V N }
L A S T V T ( P ) = { a ∣ P ⇒ + . . . a 或 P ⇒ + . . . Q a , a ∈ V T 而 Q ∈ V N } LASTVT(P)=\{a|P\Rightarrow^+...a或P\Rightarrow^+...Qa, a\in V_T而Q\in V_N\} L A ST V T ( P ) = { a ∣ P ⇒ + ... a 或 P ⇒ + ... Q a , a ∈ V T 而 Q ∈ V N }
素短语 素短语: 至少含有一个终结符, 而且除它自身以外不含有任何更小的素短语
最左素短语: 句型最左边的素短语
LR分析法 L: 从左到右扫描输入串 R: 构造最右推导的逆过程 LR分析法是严格的规范规约
原理: 在移进-规约过程中寻找句柄
模型:
将历史和展望抽象成状态, 整体上是一个FA 一张分析表ACTION[s,a]: 状态s遇到输入a应该采取什么动作 GOTO[s,X]: 状态s遇到文法符号X时下一状态是什么, 构成了一个以文法符号为字母表的DFA 分类:
总控程序: 所有的LR分析器都相同 分析表: 是自动生成语法分析器的关键LR(0)表: 基础但有局限性 SLR表: 简单LR表, 实用 规范LR表: 能力强, 代价大 LALR表: 向前LR表, 介于SLR和规范LR之间 ACTION表:
移进s N sN s N : 将N N N 和输入符号a a a 进栈, 读取下一个输入 规约r N rN r N : 用N N N 号产生式A ⇒ β A\Rightarrow\beta A ⇒ β 进行规约, 出栈∣ β ∣ |\beta| ∣ β ∣ 项, 将G O T O [ s . t o p , A ] GOTO[s.top, A] GOTO [ s . t o p , A ] 和A A A 进栈(规约), 输入不动 接受a c c acc a cc : 分析成功结束 报错 LR文法: 能够构造LR分析表, 使得每个入口都是唯一确定的文法
LR(k)文法: 每步至多向前检查k个输入符号就能用LR分析器进行分析的文法
LR(0) LR(0)项目: 在文法产生式右部中间间隔处加一个圆点
活前缀: 规范句型的最多到句柄(可以包括句柄)的前缀
1. 识别活前缀的NFA方法 只有项目1作为初态, 其他任何项目都认为是终态
连接非ε \varepsilon ε 弧
状态 i 为 X → X 1 . . . X i − 1 ⋅ X i . . . X n 状态i为X\rightarrow X_1...X_{i-1}\cdot X_i...X_n 状态 i 为 X → X 1 ... X i − 1 ⋅ X i ... X n 状态 j 为 X → X 1 . . . X i − 1 X i ⋅ X i + 1 . . . X n 状态j为X\rightarrow X_1...X_{i-1}X_i\cdot X_{i+1}...X_n 状态 j 为 X → X 1 ... X i − 1 X i ⋅ X i + 1 ... X n 则连接状态i i i 到状态j j j , 标志为X i X_i X i 连接ε \varepsilon ε 弧
状态 i 为 X → α ⋅ A β 状态i为X\rightarrow \alpha\cdot A\beta 状态 i 为 X → α ⋅ A β 则连接状态i i i 到所有状态A → ⋅ γ A\rightarrow\cdot\gamma A → ⋅ γ , 标志为ε \varepsilon ε
确定化(NFA转DFA)
2. LR(0)项目集规范族 识别活前缀的DFA的项目集的全体称为文法的LR(0)项目集规范族
规约项目:A → α ⋅ A\rightarrow\alpha\cdot A → α ⋅ 接受项目:S → α ⋅ S\rightarrow\alpha\cdot S → α ⋅ 移进项目:A → α ⋅ a β A\rightarrow\alpha\cdot a\beta A → α ⋅ a β 待约项目:A → α ⋅ B β A\rightarrow\alpha\cdot B\beta A → α ⋅ Bβ 拓广文法
构造一个新的文法G ′ ⊇ G G'\supseteq G G ′ ⊇ G 引进一个开始符号, 非终结符S ′ S' S ′ 增加一个产生式S ′ → S S'\rightarrow S S ′ → S 唯一接受态:S ′ → S ⋅ S'\rightarrow S\cdot S ′ → S ⋅ 项目集的闭包C l o s u r e ( I ) Closure(I) Cl os u re ( I ) :
I ∈ C l o s u r e ( I ) I\in Closure(I) I ∈ Cl os u re ( I ) 若( A → α ⋅ B β ) ∈ C l o s u r e ( I ) (A\rightarrow\alpha\cdot B\beta)\in Closure(I) ( A → α ⋅ Bβ ) ∈ Cl os u re ( I ) , 则对于任何B → γ B\rightarrow\gamma B → γ ,( B → ⋅ γ ) ∈ C l o s u r e ( I ) (B\rightarrow\cdot\gamma)\in Closure(I) ( B → ⋅ γ ) ∈ Cl os u re ( I ) 与I I I 同状态的项目集合, 包括子项目 状态转换函数G O ( I , X ) GO(I,X) GO ( I , X ) :
G O ( I , X ) = C l o s u r e ( { A → α X ⋅ β ∣ ( A → α ⋅ X β ) ∈ I } ) GO(I, X)=Closure(\{A\rightarrow\alpha X\cdot\beta|(A\rightarrow\alpha\cdot X\beta)\in I\}) GO ( I , X ) = Cl os u re ({ A → α X ⋅ β ∣ ( A → α ⋅ Xβ ) ∈ I }) 若I I I 是对活前缀γ \gamma γ 有效的项目集, 那么G O ( I , X ) GO(I, X) GO ( I , X ) 就是对γ X \gamma X γ X 有效的项目集 (接受X X X 之后的C l o s u r e Closure Cl os u re 集合) 构造DFA算法
1 2 3 4 5 6 7 8 9 PROCEDURE ITEMSETS(G') BEGIN C:={Closure({S'\rightarrow\cdot S})} REPEAT FOR C中每个项目集I和G'的每个符号X DO IF GO(I, X)非空且不属于C THEN C += GO(I, X) UNTIL C 不再增大 END
LR(0)文法:
拓广文法的识别活前缀的dfa的项目集(LR(0)项目集规范族)不包含任何冲突 的文法 冲突
构造LR(0)分析表:
每个项目集为一个状态 包含S ′ → ⋅ S S'\rightarrow\cdot S S ′ → ⋅ S 的集合为初态 构造LR(0)的ACTION和GOTO :
若( A → α ⋅ a β ) ∈ I k (A\rightarrow\alpha\cdot a\beta)\in I_k ( A → α ⋅ a β ) ∈ I k 且G O ( I k , a ) = I j GO(I_k, a)=I_j GO ( I k , a ) = I j , 则A C T I O N [ k , a ] = s j ACTION[k, a]=sj A CT I ON [ k , a ] = s j 若( A → α ⋅ ) ∈ I k (A\rightarrow\alpha\cdot)\in I_k ( A → α ⋅ ) ∈ I k , 则A C T I O N [ k , a ] = r j ACTION[k, a]=rj A CT I ON [ k , a ] = r j 若( S ′ → S ) ∈ I k (S'\rightarrow S)\in I_k ( S ′ → S ) ∈ I k , 则A C T I O N [ k , a ] = a c c ACTION[k, a]=acc A CT I ON [ k , a ] = a cc 若G O ( I k , A ) = I j GO(I_k,A)=I_j GO ( I k , A ) = I j , 则G O T O [ k , a ] = j GOTO[k, a]=j GOTO [ k , a ] = j 其他均为报错
SLR LR(0)可能会误判: 即使存在项目冲突, 也不一定不合法
假定LR(0)规范族的一个项目集
I = { A 1 → α ⋅ a 1 β 1 , A 2 → α ⋅ a 2 β 2 , . . . A m → α ⋅ a m β m , B 1 → α ⋅ , B 2 → α ⋅ , . . . B n → α ⋅ } \begin{aligned} I=\{ &A_1\rightarrow\alpha\cdot a_1\beta_1,\\ &A_2\rightarrow\alpha\cdot a_2\beta_2,\\ &...\\ &A_m\rightarrow\alpha\cdot a_m\beta_m,\\ &B_1\rightarrow\alpha\cdot,\\ &B_2\rightarrow\alpha\cdot,\\ &...\\ &B_n\rightarrow\alpha\cdot\} \end{aligned} I = { A 1 → α ⋅ a 1 β 1 , A 2 → α ⋅ a 2 β 2 , ... A m → α ⋅ a m β m , B 1 → α ⋅ , B 2 → α ⋅ , ... B n → α ⋅ }
如果集合{ a 1 , . . . , a m } , F O L L O W ( B 1 ) , . . . , F O L L O W ( B n ) \{a_1, ..., a_m\}, FOLLOW(B_1), ..., FOLLOW(B_n) { a 1 , ... , a m } , FO LL O W ( B 1 ) , ... , FO LL O W ( B n ) 两两不相交(包括不得有两个FOLLOW集合有#), 则
若a是某个ai, i=1,2,…,m, 则移进 若a ∈ F O L L O W ( B i ) , i = 1 , 2 , . . . , n a\in FOLLOW(B_i), i=1,2,...,n a ∈ FO LL O W ( B i ) , i = 1 , 2 , ... , n , 则用产生式B i → α B_i\rightarrow\alpha B i → α 进行归约 此外, 报错。 冲突性动作的这种解决办法叫做SLR(1)解决办法。上述方法构造出的ACTION与GOTO表如果不含多重入口,则称该文法为SLR(1)文法
LR(1) LALR 不考, 略
二义文法的应用 二义文法 不是LR文法 简洁、自然 可以用文法以外的信息来消除二义 语法分析的效率高(基于消除二义后得到的分析表) 举例: E → E + E | E * E | (E) | id
消除二义性:
使用文法以外信息来解决分析动作冲突