构造一个SLR(1)分析器。要求如下: (1)用户任意给定文法,输出识别活前缀的DFA、LR(0)的项目集规范族、所有非终结符的FOLLOW集合; (2)输出SLR(1)分析表; (3)测试文法G[E]如下: S→bASB|bA A→dSa|e B→cAa|
时间: 2024-06-06 19:05:22 浏览: 93
基于C语言实现SLR(1)类文法判定及其分析器构造【100012260】
5星 · 资源好评率100%
首先,我们需要将给定的文法转换为 LR(0) 项目集规范族,然后再构建 DFA。下面是 G[E] 的 LR(0) 项目集规范族:
$I_0$:
$S'→·S$
$S→·bASB$
$S→·bA$
$A→·dSa$
$A→·e$
$B→·cAa$
$I_1$:
$S'→S·$
$I_2$:
$S→b·ASB$
$S→b·A$
$I_3$:
$A→d·Sa$
$I_4$:
$A→e·$
$I_5$:
$B→c·Aa$
$I_6$:
$S→bA·SB$
$S→bA·$
$I_7$:
$B→cA·a$
$I_8$:
$A→dS·a$
$I_9$:
$S→bAS·B$
$I_{10}$:
$S→bASB·$
$I_{11}$:
$B→cAa·$
对于 FOLLOW 集合,我们可以按照以下步骤计算:
1. 将 $S'$ 的 FOLLOW 集合设为 $\{\$\}$,其中 $\$$ 表示输入串的结束符。
2. 对于每个非终结符号 $A$,将 FOLLOW(A) 初始化为空集。
3. 对于每个产生式 $A→αBβ$,将 FOLLOW(B) 加入 FOLLOW(α)。
4. 对于每个产生式 $A→αB$ 或 $A→αBβ$,如果 $B$ 可以推导出空串,则将 FOLLOW(A) 加入 FOLLOW(B)。
按照上述步骤计算 FOLLOW 集合,得到:
$FOLLOW(S') = \{\$\}$
$FOLLOW(S) = \{a, \$\}$
$FOLLOW(A) = \{a, c\}$
$FOLLOW(B) = \{a, \$\}$
接下来,我们需要构建 SLR(1) 分析表。对于每个 LR(0) 项目集 $I_i$,以及每个终结符号 $a$,我们需要确定 $action[i, a]$ 和 $goto[i, A]$ 的值,其中 $A$ 是一个非终结符号。
对于 $action[i, a]$,我们有以下几种情况:
1. 如果 $I_i$ 中存在项目 $A→α·aβ$,则将 $action[i, a]$ 设为“shift $j$”,其中 $j$ 是使得 $I_j$ 中存在项目 $A→αa·β$ 的 LR(0) 项目集编号。
2. 如果 $I_i$ 中存在项目 $S'→S·$,且 $a=\$$,则将 $action[i, a]$ 设为“accept”。
3. 如果 $I_i$ 中存在项目 $A→α·$,且 $A≠S'$,则对于 FOLLOW(A) 中的每个终结符号 $b$,将 $action[i, b]$ 设为“reduce $A→α$”。
4. 如果 $I_i$ 中存在项目 $S'→·S$,则将 $action[i, a]$ 设为“goto $j$”,其中 $j$ 是使得 $I_j$ 中存在项目 $S'→S·$ 的 LR(0) 项目集编号。
5. 如果 $I_i$ 中存在项目 $A→α·$,且 $A=S'$,则将 $action[i, a]$ 设为“accept”。
对于 $goto[i, A]$,我们有以下情况:
1. 如果 $I_i$ 中存在项目 $B→α·Aβ$,则将 $goto[i, A]$ 设为 $j$,其中 $j$ 是使得 $I_j$ 中存在项目 $B→αA·β$ 的 LR(0) 项目集编号。
按照上述规则生成 SLR(1) 分析表,得到如下表格:
| | b | c | d | e | a | \$ | S | A | B |
|---|---|---|---|---|---|---|---|---|---|
| 0 | s2| |s3 |s4 | | | 1 | 6 | |
| 1 | | | | | |acc| | | |
| 2 | s2| |s3 |s4 | | | | 6 | |
| 3 | | | | |s7 | | | | |
| 4 | |s8 | | | | | | | 5 |
| 5 | r2|r2 | |r2 |r2 |r2 | | | |
| 6 | |s9 | | | | | | | |
| 7 | r4|r4 | |r4 |r4 |r4 | | | |
| 8 | | | | |s10| | | | |
| 9 | | |s11|s4 | | | | | |
|10 | | | | |r1|r1 | | | |
|11 | | | | |r3|r3 | | | |
其中 $s$ 表示 shift,$r$ 表示 reduce。例如,$s2$ 表示在状态 $0$ 遇到终结符号 $b$ 时应该进行 shift 操作,并转移到状态 $2$。
最后,我们可以使用上述 SLR(1) 分析表对输入串进行分析。例如,对于输入串 $bdaac$,我们可以按照以下步骤进行分析:
1. 将输入串的第一个字符 $b$ 读入,并从栈顶开始扫描栈,找到状态 $0$ 中对应于终结符号 $b$ 的动作,即 shift 操作,并将输入串中的下一个字符 $d$ 读入。
2. 将状态 $2$ 入栈,并从栈顶开始扫描栈,找到状态 $2$ 中对应于终结符号 $d$ 的动作,即 shift 操作,并将输入串中的下一个字符 $a$ 读入。
3. 将状态 $3$ 入栈,并从栈顶开始扫描栈,找到状态 $3$ 中对应于终结符号 $a$ 的动作,即 reduce 操作,并将栈顶的两个符号 $Sa$ 弹出,再根据 $A→dSa$ 这个产生式将 $dSa$ 压入栈中。
4. 将状态 $6$ 入栈,并从栈顶开始扫描栈,找到状态 $6$ 中对应于非终结符号 $A$ 的 goto 操作,并转移到状态 $9$。
5. 重复步骤 2 和 3,直到栈顶符号为 $S'$ 且输入串已经被完全读入,此时分析成功;或者遇到错误,此时分析失败。
阅读全文