视频加载失败

课程

8526 字
约 25 分钟

第四章 课后作业参考答案

编译原理exercises/homework·更新于 2026-09-15

第四章 课后作业参考答案


5. 考虑下面文法 G1G_1

Sa(T)TT,SS\begin{aligned} S &\to a \mid \wedge \mid (T) \\ T &\to T, S \mid S \end{aligned}

(1) 消去 G1G_1 的左递归。然后,对每个非终结符,写出不带回溯的递归子程序。 (2) 经改写后的文法是否是 LL(1)\text{LL}(1) 的?给出它的预测分析表。

解答

(1) 消去直接左递归并写出递归下降子程序

文法中非终结符 TT 的产生式含有直接左递归:TT,SST \to T, S \mid S。 应用消除左递归的常规公式 AAαβ    AβA,AαAεA \to A\alpha \mid \beta \implies A \to \beta A', A' \to \alpha A' \mid \varepsilon,我们有: TSTT \to S T' T,STεT' \to , S T' \mid \varepsilon

消除左递归后的等价文法为:

Sa(T)TSTT,STε\begin{aligned} S &\to a \mid \wedge \mid (T) \\ T &\to S T' \\ T' &\to , S T' \mid \varepsilon \end{aligned}

不带回溯的递归下降子程序(伪代码)

procedure S;
begin
  if lookahead = 'a' then
    match('a')
  else if lookahead = '^' then
    match('^')
  else if lookahead = '(' then
    begin
      match('(');
      T;
      match(')');
    end
  else
    error("Syntax Error in S");
end;

procedure T;
begin
  S;
  T';
end;

procedure T';
begin
  if lookahead = ',' then
    begin
      match(',');
      S;
      T';
    end
  else if lookahead = ')' then
    { 对应 T' -> ε,空匹配,因为 ) 属于 FOLLOW(T') }
    begin end
  else
    error("Syntax Error in T'");
end;

(2) LL(1)\text{LL}(1) 判定及预测分析表

首先计算文法非终结符的 FIRST\text{FIRST}FOLLOW\text{FOLLOW} 集合:

  • FIRST(S)={a,,(}\text{FIRST}(S) = \{ a, \wedge, ( \}
  • FIRST(T)=FIRST(S)={a,,(}\text{FIRST}(T) = \text{FIRST}(S) = \{ a, \wedge, ( \}
  • FIRST(T)={,,ε}\text{FIRST}(T') = \{ ,, \varepsilon \}
  • \text{FOLLOW}(S) = \{ \, ,, ) }$
  • FOLLOW(T)={)}\text{FOLLOW}(T) = \{ ) \}
  • FOLLOW(T)=FOLLOW(T)={)}\text{FOLLOW}(T') = \text{FOLLOW}(T) = \{ ) \}

LL(1)\text{LL}(1) 判定: 对于含有选择分支的产生式 T,STεT' \to , S T' \mid \varepsilon,其两分支选择的 FIRST\text{FIRST} 交集为: FIRST(,ST)FOLLOW(T)={,}{)}=\text{FIRST}(, S T') \cap \text{FOLLOW}(T') = \{ , \} \cap \{ ) \} = \emptyset 由于对所有非终结符,候选产生式的 FIRST\text{FIRST} 集合均两两互不相交,且包含 ε\varepsilon 的产生式其 FIRST\text{FIRST}FOLLOW\text{FOLLOW} 的交集也为空。因此该文法是 LL(1)\text{LL}(1) 文法

预测分析表

非终结符aa\wedge(()),,$$$
SSSaS \to aSS \to \wedgeS(T)S \to (T)
TTTSTT \to S T'TSTT \to S T'TSTT \to S T'
TT'TεT' \to \varepsilonT,STT' \to , S T'

6. 对下面的文法 GG

ETEE+EεTFTTTεFPFFFεP(E)ab\begin{aligned} E &\to T E' \\ E' &\to +E \mid \varepsilon \\ T &\to F T' \\ T' &\to T \mid \varepsilon \\ F &\to P F' \\ F' &\to *F' \mid \varepsilon \\ P &\to (E) \mid a \mid b \mid \wedge \end{aligned}

(1) 构造这个文法的每个非终结符的 FIRST\text{FIRST}FOLLOW\text{FOLLOW} 集合。 (2) 证明这个文法是 LL(1)\text{LL}(1) 的。 (3) 构造它的预测分析表。 (4) 构造它的递归下降分析程序。

解答

(1) 计算 FIRST\text{FIRST}FOLLOW\text{FOLLOW} 集合

(详细推导见课本大题-答案

非终结符FIRST\text{FIRST} 集合FOLLOW\text{FOLLOW} 集合
EE{(,a,b,}\{ (, a, b, \wedge \}\{ \, ) }$
EE'{+,ε}\{ +, \varepsilon \}\{ \, ) }$
TT{(,a,b,}\{ (, a, b, \wedge \}\{ +, \, ) }$
TT'{(,a,b,,ε}\{ (, a, b, \wedge, \varepsilon \}\{ +, \, ) }$
FF{(,a,b,}\{ (, a, b, \wedge \}\{ (, a, b, \wedge, +, \, ) }$
FF'{,ε}\{ *, \varepsilon \}\{ (, a, b, \wedge, +, \, ) }$
PP{(,a,b,}\{ (, a, b, \wedge \}\{ *, (, a, b, \wedge, +, \, ) }$

(2) 证明是 LL(1)\text{LL}(1) 文法

文法中凡是具有多个候选产生式的非终结符,需要验证其 FIRST\text{FIRST}FOLLOW\text{FOLLOW} 无交集冲突:

  1. 对于 E+EεE' \to +E \mid \varepsilon\text{FIRST}(+E) \cap \text{FOLLOW}(E') = \{ + \} \cap \{ \, ) } = \emptyset$。
  2. 对于 TTεT' \to T \mid \varepsilon\text{FIRST}(T) \cap \text{FOLLOW}(T') = \{ (, a, b, \wedge \} \cap \{ +, \, ) } = \emptyset$。
  3. 对于 FFεF' \to *F' \mid \varepsilon\text{FIRST}(*F') \cap \text{FOLLOW}(F') = \{ * \} \cap \{ (, a, b, \wedge, +, \, ) } = \emptyset$。
  4. 对于 P(E)abP \to (E) \mid a \mid b \mid \wedge: 各分支选择的首字符集分别为 {(}\{(\}{a}\{a\}{b}\{b\}{}\{\wedge\},它们两两不相交。

经检验,文法所有冲突均可完全解决,故该文法LL(1)\text{LL}(1) 文法

(3) 构造它的预测分析表

(详细预测分析表见课本大题-答案

(4) 递归下降分析程序

procedure E;
begin
  T; E';
end;

procedure E';
begin
  if lookahead = '+' then
    begin match('+'); E; end
  else if lookahead in [')', '$'] then
    { 空匹配 }
  else error;
end;

procedure T;
begin
  F; T';
end;

procedure T';
begin
  if lookahead in ['(', 'a', 'b', '^'] then
    T
  else if lookahead in ['+', '$', ')'] then
    { 空匹配 }
  else error;
end;

procedure F;
begin
  P; F';
end;

procedure F';
begin
  if lookahead = '*' then
    begin match('*'); F'; end
  else if lookahead in ['(', 'a', 'b', '^', '+', '$', ')'] then
    { 空匹配 }
  else error;
end;

procedure P;
begin
  if lookahead = '(' then
    begin match('('); E; match(')'); end
  else if lookahead = 'a' then match('a')
  else if lookahead = 'b' then match('b')
  else if lookahead = '^' then match('^')
  else error;
end;

7. 对下面文法:

ExprExpr(Expr)Var ExprTailExprTailExprεVarid VarTailVarTail(Expr)ε\begin{aligned} \textit{Expr} &\to -\textit{Expr} \mid (\textit{Expr}) \mid \textit{Var} \ \textit{ExprTail} \\ \textit{ExprTail} &\to -\textit{Expr} \mid \varepsilon \\ \textit{Var} &\to \textit{id} \ \textit{VarTail} \\ \textit{VarTail} &\to (\textit{Expr}) \mid \varepsilon \end{aligned}

(1) 构造 LL(1)\text{LL}(1) 分析表。 (2) 给出对句子 idid((id))\textit{id}--\textit{id}((\textit{id})) 的分析过程。

解答

(1) FIRST\text{FIRST} / FOLLOW\text{FOLLOW}LL(1)\text{LL}(1) 预测分析表

  • 各非终结符的 FIRST\text{FIRST}FOLLOW\text{FOLLOW}

    • FIRST(Expr)={,(,id}\text{FIRST}(\textit{Expr}) = \{ -, (, \textit{id} \}
    • FIRST(ExprTail)={,ε}\text{FIRST}(\textit{ExprTail}) = \{ -, \varepsilon \}
    • FIRST(Var)={id}\text{FIRST}(\textit{Var}) = \{ \textit{id} \}
    • FIRST(VarTail)={(,ε}\text{FIRST}(\textit{VarTail}) = \{ (, \varepsilon \}
    • \text{FOLLOW}(\textit{Expr}) = \{ \, ) }$
    • \text{FOLLOW}(\textit{ExprTail}) = \text{FOLLOW}(\textit{Expr}) = \{ \, ) }$
    • \text{FOLLOW}(\textit{Var}) = (\text{FIRST}(\textit{ExprTail}) \setminus \{\varepsilon\}) \cup \text{FOLLOW}(\textit{Expr}) = \{ -, \, ) }$
    • \text{FOLLOW}(\textit{VarTail}) = \text{FOLLOW}(\textit{Var}) = \{ -, \, ) }$
  • LL(1)\text{LL}(1) 预测分析表

非终结符id-()$
Expr\textit{Expr}ExprVar ExprTail\textit{Expr} \to \textit{Var} \ \textit{ExprTail}ExprExpr\textit{Expr} \to -\textit{Expr}Expr(Expr)\textit{Expr} \to (\textit{Expr})
ExprTail\textit{ExprTail}ExprTailExpr\textit{ExprTail} \to -\textit{Expr}ExprTailε\textit{ExprTail} \to \varepsilonExprTailε\textit{ExprTail} \to \varepsilon
Var\textit{Var}Varid VarTail\textit{Var} \to \textit{id} \ \textit{VarTail}
VarTail\textit{VarTail}VarTailε\textit{VarTail} \to \varepsilonVarTail(Expr)\textit{VarTail} \to (\textit{Expr})VarTailε\textit{VarTail} \to \varepsilonVarTailε\textit{VarTail} \to \varepsilon

(2) 句子 idid((id))\textit{id}--\textit{id}((\textit{id})) 的分析步骤过程

下表展示了使用分析栈对句子进行分析的过程(其中 # 代表栈底标志):

步骤符号栈 (从右至左压栈)剩余输入串所用产生式 / 动作
1# Expr\textit{Expr}id - - id ( ( id ) ) #ExprVar ExprTail\textit{Expr} \to \textit{Var} \ \textit{ExprTail}
2# ExprTail\textit{ExprTail} Var\textit{Var}id - - id ( ( id ) ) #Varid VarTail\textit{Var} \to \textit{id} \ \textit{VarTail}
3# ExprTail\textit{ExprTail} VarTail\textit{VarTail} idid - - id ( ( id ) ) #匹配终结符 id (移进)
4# ExprTail\textit{ExprTail} VarTail\textit{VarTail}- - id ( ( id ) ) #VarTailε\textit{VarTail} \to \varepsilon (因 - \in FOLLOW(VarTail)\text{FOLLOW}(\textit{VarTail}))
5# ExprTail\textit{ExprTail}- - id ( ( id ) ) #ExprTailExpr\textit{ExprTail} \to -\textit{Expr}
6# Expr\textit{Expr} -- - id ( ( id ) ) #匹配终结符 - (移进)
7# Expr\textit{Expr}- id ( ( id ) ) #ExprExpr\textit{Expr} \to -\textit{Expr}
8# Expr\textit{Expr} -- id ( ( id ) ) #匹配终结符 - (移进)
9# Expr\textit{Expr}id ( ( id ) ) #ExprVar ExprTail\textit{Expr} \to \textit{Var} \ \textit{ExprTail}
10# ExprTail\textit{ExprTail} Var\textit{Var}id ( ( id ) ) #Varid VarTail\textit{Var} \to \textit{id} \ \textit{VarTail}
11# ExprTail\textit{ExprTail} VarTail\textit{VarTail} idid ( ( id ) ) #匹配终结符 id (移进)
12# ExprTail\textit{ExprTail} VarTail\textit{VarTail}( ( id ) ) #VarTail(Expr)\textit{VarTail} \to (\textit{Expr}) (因 ( \in FIRST((Expr))\text{FIRST}((\textit{Expr})))
13# ExprTail\textit{ExprTail} ) Expr\textit{Expr} (( ( id ) ) #匹配终结符 ( (移进)
14# ExprTail\textit{ExprTail} ) Expr\textit{Expr}( id ) ) #Expr(Expr)\textit{Expr} \to (\textit{Expr})
15# ExprTail\textit{ExprTail} ) ) Expr\textit{Expr} (( id ) ) #匹配终结符 ( (移进)
16# ExprTail\textit{ExprTail} ) ) Expr\textit{Expr}id ) ) #ExprVar ExprTail\textit{Expr} \to \textit{Var} \ \textit{ExprTail}
17# ExprTail\textit{ExprTail} ) ) ExprTail\textit{ExprTail} Var\textit{Var}id ) ) #Varid VarTail\textit{Var} \to \textit{id} \ \textit{VarTail}
18# ExprTail\textit{ExprTail} ) ) ExprTail\textit{ExprTail} VarTail\textit{VarTail} idid ) ) #匹配终结符 id (移进)
19# ExprTail\textit{ExprTail} ) ) ExprTail\textit{ExprTail} VarTail\textit{VarTail}) ) #VarTailε\textit{VarTail} \to \varepsilon (因 ) \in FOLLOW(VarTail)\text{FOLLOW}(\textit{VarTail}))
20# ExprTail\textit{ExprTail} ) ) ExprTail\textit{ExprTail}) ) #ExprTailε\textit{ExprTail} \to \varepsilon (因 ) \in FOLLOW(ExprTail)\text{FOLLOW}(\textit{ExprTail}))
21# ExprTail\textit{ExprTail} ) )) ) #匹配终结符 ) (移进)
22# ExprTail\textit{ExprTail} )) #匹配终结符 ) (移进)
23# ExprTail\textit{ExprTail}#ExprTailε\textit{ExprTail} \to \varepsilon (因 # \in FOLLOW(ExprTail)\text{FOLLOW}(\textit{ExprTail}))
24##分析成功结束,句子合法被接受
Profile Image of the Author
Sonder
好想要技术
这是公告标题
这只是一个公告
分类
标签
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.16.7
文章许可
CC BY-NC-SA 4.0
文章目录