LL(1) 文法实战:3步构建预测分析表,解决王原生习题4.1歧义

📅 2026/7/11 20:30:08
LL(1) 文法实战:3步构建预测分析表,解决王原生习题4.1歧义
LL(1) 文法实战3步构建预测分析表解决王原生习题4.1歧义编译原理中语法分析是理解程序结构的关键环节。而LL(1)文法作为自顶向下分析的重要工具其预测分析表的构建往往是学习难点。本文将以王原生《编译原理》第三版第四章习题1为例演示如何通过标准化流程解决文法歧义问题。1. 问题描述与文法改写原始文法G[S]如下S → a | ∧ | (T) T → T,S | S该文法存在两个典型问题左递归T → T,S 会导致无限循环公共左因子S的三个产生式首符号不同但T的两个产生式首符号重叠1.1 消除左递归采用标准左递归消除公式原规则A → Aα | β 改写为A → βA A → αA | ε应用在T的产生式T → S T T → ,S T | ε1.2 提取左因子观察改写后的文法已无公共左因子问题。最终改写结果为(1) S → a | ∧ | (T) (2) T → S T (3) T → ,S T | ε2. FIRST集与FOLLOW集计算2.1 FIRST集计算规则非终结符计算规则结果Sa, ∧, ( 的FIRST{a, ∧, (}TFIRST(S){a, ∧, (}T, 的FIRST ∪ ε{,, ε}2.2 FOLLOW集计算步骤初始化FOLLOW(S) {#, ,}传播规则S出现在T → S T因此FOLLOW(S) ∪ FIRST(T) - {ε} ∪ FOLLOW(T)T → ,S T 导致FOLLOW(S) ∪ FIRST(T) - {ε}最终结果FOLLOW(S) {#, ,, )} FOLLOW(T) {)} FOLLOW(T) FOLLOW(T) {)}3. 预测分析表构建与验证3.1 LL(1)分析表构造算法def build_predict_table(): for 产生式 A → α: for 每个终结符 a ∈ FIRST(α): 将 A → α 加入 M[A,a] if ε ∈ FIRST(α): for 每个终结符 b ∈ FOLLOW(A): 将 A → α 加入 M[A,b]3.2 完整预测分析表非终结符a∧(),#SS→aS→∧S→(T)TT→STT→STT→STTT→εT→,ST3.3 输入串(a,a)#分析过程使用栈和输入缓冲区进行模拟步骤栈输入动作1#S(a,a)#S→(T)2#)T((a,a)#匹配 (3#)Ta,a)#T→ST4#)TSa,a)#S→a5#)Taa,a)#匹配 a6#)T,a)#T→,ST7#)TS,,a)#匹配 ,8#)TSa)#S→a9#)Taa)#匹配 a10#)T)#T→ε11#))#匹配 )12##接受通过12步推导最终判定(a,a)#是该文法的合法句子。这个标准化流程可推广到其他LL(1)文法分析场景特别是处理嵌套结构和列表表达式时特别有效。