怎么写出LL(1)文法

将变量和常量分别用符号b和c表示,写出能够描述上述表达式的LL(1)文法,并构建预测分析表对b+c%b#进行分析,写出分析过程;
表达式为:x+y*z-3

LL(1)文法:

E -> TX
X -> +TX | -TX | ε
T -> FY
Y -> *FY | ε
F -> (E) | b | c

预测分析表:

+-*()bc#
ETXTXTXTXTX
X+TX-TXεε
TFYFYFYFYFY
Y*FYεε
F(E)bc

分析过程:

(1)E -> TX,读入 x,符号栈压入#E
(2)T -> FY,读入 +,符号栈弹出E,状态栈压入E
(3)X -> +TX,符号栈压入TX
(4)T -> FY,读入 y,符号栈弹出TX,状态栈压入TX
(5)Y -> ε,符号栈弹出FY,状态栈弹出TX
(6)X -> ε,符号栈弹出E,状态栈弹出E
(7)E -> TX,读入 *,符号栈压入#E
(8)T -> FY,读入 z,符号栈弹出E,状态栈压入E
(9)Y -> ε,符号栈弹出FY,状态栈弹出E
(10)E -> TX,读入 -,符号栈压入#E
(11)T -> FY,读入 3,符号栈弹出E,状态栈压入E
(12)Y -> ε,符号栈弹出FY,状态栈弹出E
(13)X -> ε,符号栈弹出E,状态栈弹出E
(14)读入 #,符号栈弹出#,状态栈弹
(15)E -> TX,读入 b,符号栈压入#E
(16)T -> FY,读入 +,符号栈弹出E,状态栈压入E
(17)X -> +TX,符号栈压入TX
(18)T -> FY,读入 c,符号栈弹出TX,状态栈压入TX
(19)Y -> ε,符号栈弹出FY,状态栈弹出TX
(20)X -> ε,符号栈弹出E,状态栈弹出E
(21)E -> TX,读入 %,符号栈压入#E
(22)T -> FY,读入 b,符号栈弹出E,状态栈压入E
(23)Y -> ε,符号栈弹出FY,状态栈弹出E
(24)X -> ε,符号栈弹出E,状态栈弹出E
(25)读入 #,符号栈弹出#,状态栈弹出
分析成功,表达式 b+c%b 是合法的。

写出一个 LL(1) 文法。LL(1) 文法是一种上下文无关文法,它可以使用一个单独的符号来预测下一个符号。
这是一个能够描述上述表达式的 LL(1) 文法:
E -> T + E | T - E | T
T -> F * T | F / T | F
F -> ( E ) | b | c
在这个文法中,'E'、'T' 和 'F' 分别表示表达式、项和因子。'b' 和 'c' 分别表示变量和常量。可以使用这个文法来构建预测分析表,并使用这个表对表达式 'x+yz-3' 进行分析。
这是分析过程的步骤:
1.将表达式的第一个符号 'x' 压入分析栈中。
2.将表达式的第二个符号 '+' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'x' 属于终结符 'b','+' 属于终结符 '+',所以根据文法的第一条产生式 'E -> T + E' 匹配成功。因此,将 'E' 替换为 'T + E',并将 'T' 压入栈中。
3.将表达式的第三个符号 'y' 压入分析栈中。
4.将表达式的第四个符号 '
' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'y' 属于终结符 'b','' 属于终结符 '',所以根据文法的第三条产生式 'T -> F * T' 匹配成功。因此,将 'T' 替换为 'F * T',并将 'F' 压入栈中。
5. 将表达式的第五个符号 'z' 压入分析栈中。
6.将表达式的第六个符号 '-' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'z' 属于终结符 'b','-' 属于终结符 '-',所以根据文法的第一条产生式 'E -> T - E' 匹配成功。因此,将 'E' 替换为 'T - E',并将 'T' 压入栈中。
7.将表达式的第七个符号 '3' 压入分析栈中。
8.将表达式的第八个符号 '#' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 '3' 属于终结符 'c','#' 属于终结符 '#',所以根据文法的第四条产生式 'F -> c' 匹配成功。因此,将 'F' 替换为 'c'。
9.将表达式的第七个符号 '3' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'c' 属于终结符 'c','3' 属于终结符 'c',所以根据文法的第四条产生式 'F -> c' 匹配成功。因此,将 'F' 替换为 'c'。
10.将表达式的第六个符号 '-' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'c' 属于终结符 'c','-' 属于终结符 '-',所以根据文法的第二条产生式 'T -> F - T' 匹配成功。因此,将 'T' 替换为 'F - T'。
11.将表达式的第五个符号 'z' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'z' 属于终结符 'b','z' 属于终结符 'b',所以根据文法的第四条产生式 'F -> b' 匹配成功。因此,将 'F' 替换为 'b'。
12.将表达式的第四个符号 '' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'b' 属于终结符 'b','' 属于终结符 '*',所以根据文法的第三条产生式 'T -> F * T' 匹配成功。因此,将 'T' 替换为 'F * T'。
13.将表达式的第三个符号 'y' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'y' 属于终结符 'b','y' 属于终结符 'b',所以根据文法的第四条产生式 'F -> b' 匹配成功。因此,将 'F' 替换为 'b'。
14.将表达式的第二个符号 '+' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'b' 属于终结符 'b','+' 属于终结符 '+',所以根据文法的第一条产生式 'E -> T + E' 匹配成功。因此,将 'E' 替换为 'T + E',并将 'T' 压入栈中。
15.将表达式的第一个符号 'x' 与栈顶的符号进行匹配。根据预测分析表,栈顶的符号 'x' 属于终结符 'b','x' 属于终结符 'b',所以根据文法的第四条产生式 'F -> b' 匹配成功。因此,将 'F' 替换为 'b'。
由于分析过程中所有的符号都匹配成功,所以这个表达式是合法的。

下面是能够描述上述表达式的 LL(1) 文法:

E -> T E'
E' -> + T E' | - T E' | ε
T -> F T'
T' -> * F T' | / F T' | ε
F -> ( E ) | b | c

构建预测分析表,对 b+c%b# 进行分析:

img


分析过程如下:首先,我们可以看到在 E 这一行的第 5 列,预测分析表中对应的符号是 T E',所以我们可以将第一个 b 作为一个 T,进入 T 这一列。

在 T 这一行的第 5 列,预测分析表中对应的符号是 F T',所以我们可以将第一个 b 作为一个 F,进入 F 这一列。

在 F 这一行的第 5 列,预测分析表中对应的符号是 b,所以我们可以将第一个 b 匹配掉。

接下来,我们可以看到在 E 这一行的第 1 列,预测分析表中对应的符号是 T E',所以我们可以将第二个 + 作为一个 T,进入 T 这一列。

在 T 这一行的第 5 列,预测分析表中对应的符号是 F T',所以我们可以将第二个 c 作为一个 F,进入 F 这一列。

在 F 这一行的第 5 列,预在 F 这一行的第 5 列,预测分析表中对应的符号是 c,所以我们可以将第二个 c 匹配掉。

接下来,我们可以看到在 E 这一行的第 2 列,预测分析表中对应的符号是 ε,所以我们可以将第三个 % 忽略掉,继续往下匹配。

接下来,我们可以看到在 E 这一行的第 5 列,预测分析表中对应的符号是 T E',所以我们可以将第四个 b 作为一个 T,进入 T 这一列。

在 T 这一行的第 5 列,预测分析表中对应的符号是 F T',所以我们可以将第四个 b 作为一个 F,进入 F 这一列。

在 F 这一行的第 5 列,预测分析表中对应的符号是 b,所以我们可以将第四个 b 匹配掉。

最后,我们可以看到在 E 这一行的第 3 列,预测分析表中对应的符号是 ε,所以我们可以将最后一个 # 忽略掉。

这样,我们就成功地分析了表达式 b+c%b#。

希望这个答案对您有所帮助。

提供参考实例【编译原理LL(1)文法分析】,链接:https://blog.csdn.net/archerll/article/details/116179319

LL(1)文法可以这样表示:

E -> T | T + E
T -> F | F * T
F -> b | c | ( E )

构建预测分析表的过程如下:

首先构建符号表,包括终结符和非终结符。终结符有b、c和%,非终结符有E、T、F。

求出每个非终结符的FOLLOW集。FOLLOW集的定义是:对于非终结符A,FOLLOW(A)表示在文法中出现A后可能出现的符号集合。根据定义,可以得到以下FOLLOW集:

FOLLOW(E) = {%)}
FOLLOW(T) = {%, +}
FOLLOW(F) = {*, %, +}

求出每个非终结符的FIRST集。FIRST集的定义是:对于非终结符A,FIRST(A)表示文法中出现A的产生式的第一个符号的集合。根据定义,可以得到以下FIRST集:
FIRST(E) = {b, c, (}
FIRST(T) = {b, c, (}
FIRST(F) = {b, c, (}

根据文法和FIRST、FOLLOW集,填写预测分析表。对于每个产生式A -> α,如果FIRST(α)中包含终结符a,则在A的行、a的列填写产生式A -> α;如果FIRST(α)中不包含终结符,则在A的行、FOLLOW(A)中的每个符号a的列填写产生式A -> α。