编译原理 3 - 语法分析


语法分析(syntax analysis) 是编译程序的核心部分,其任务是检查词法分析器输出的单词序列是否是源语言中的句子

第4章 语法分析(自顶向下)

4.1 自上而下分析的问题:

  • 回溯问题
    分析过程中,当一个非终结符用某一个候选匹配成功时,这种匹配是暂时的;出错时,不得不进行“回溯”
    示例:对于具有两个候选式的A,第一次匹配时选择 A → ** 时,后续匹配失败 在这里插入图片描述
    这时,回溯到对 A 的候选时,选择下一个候选式 A → *,继续匹配后续字符。最后成功。
    在这里插入图片描述
  • 文法左递归问题
    如果一个文法存在非终结符 P 使得 P ⇒ + P α P \Rightarrow^{+} P \alpha P+Pα,则该文法含有左递归,导致分析器进入死循环
    在这里插入图片描述
    二义性

4.2 消除左递归

  • 消除直接左递归
    • 问题:形如 P → P α ∣ β P\rightarrow P\alpha | \beta PPαβ (其中 β \beta β不以 P P P开头)的文法,会变成 P ⇒ P α ⇒ P α α . . . ⇒ β α α . . . P\Rightarrow P\alpha \Rightarrow P\alpha\alpha ... \Rightarrow \beta\alpha\alpha... PPαPαα...βαα...
    • 思路:设计一种文法,也能达到上述文法的效果,而不存在左递归等死循环
    • 解决:左递归变右递归。上述文法可以转换为 P → β P ′ P\rightarrow \beta P' PβP P ′ → α P ′ ∣ ϵ P'\rightarrow \alpha P' | \epsilon PαPϵ
  • 消除间接左递归
    • 问题:问题:形如 S → Q c ∣ c S\rightarrow Qc| c SQcc Q → R b ∣ b Q\rightarrow Rb|b QRbb R → S a ∣ a R\rightarrow Sa|a RSaa 的文法,会变成 S ⇒ Q c ⇒ R b c ⇒ S a b c . . . S\Rightarrow Qc\Rightarrow Rbc \Rightarrow Sabc... SQcRbcSabc...
    • 解决的前提条件:① 不含以 ϵ \epsilon ϵ 为右部的产生式;② 不含回路 P ⇒ + P P\Rightarrow^+ P P+P(非终结符推出本身,没有其他符号)
    • 解决:将循环中的非终结符排序RQS,依次替换消除 或 消除直接左递归即可(排序不同,最终结果不同)
      在这里插入图片描述

4.3 消除回溯 与 LL(1)文法

  • FIRST集合

    • 定义
      令G是一个不含左递归的文法,对G的所有非终结符的每个候选 α \alpha α 定义它的终结首符集FIRST( α \alpha α)为:
      F I R S T ( α ) = { x ∣ α ⇒ ∗ x . . . , x ∈ V T } FIRST(\alpha) = \{x | \alpha\Rightarrow^{*} x..., x\in V_T\} FIRST(α)={xαx...,xVT}
      特别的,若 α ⇒ ∗ ϵ \alpha \Rightarrow^* \epsilon αϵ,则规定 ϵ ∈ F I R S T ( α ) \epsilon \in FIRST(\alpha) ϵFIRST(α)
    • 理解: α \alpha α能推出的任意串,这个串如果以终结符x开头,则这个终结符 x 就在FIRST集合中;此外FIRST集合中可能存在空字 ϵ \epsilon ϵ
  • 提取公共左因子
    在这里插入图片描述

    • 目的:把每个非终结符(包括新定义的 A ′ A' A等)的FIRST集变成两两不相交,进而在匹配字符时,能更准确的匹配某一个候选继续进行匹配,从而“避免”回溯问题
      在这里插入图片描述
    • 缺点:提取公因子不能完全消除回溯,只能不断延后回溯的发生
  • FOLLOW集合

    • 引入
      在这里插入图片描述
      在上面的例子中,我们希望获得一个句型: E ⇒ . . . ⇒ i T ′ E\Rightarrow...\Rightarrow iT' E...iT+ . . . ... ...,其中的 + 号跟在 T ′ T' T后面
    • FOLLOW集合 定义
      设 S 是文法G的开始符号,对G的所有非终结符A,A的FOLLOW集合为:
      F O L L O W ( A ) = { x ∣ S ⇒ ∗ . . . A x . . . , x ∈ V T } FOLLOW(A) = \{x | S\Rightarrow^{*} ...Ax..., x\in V_T\} FOLLOW(A)={xS...Ax...,xVT}
      特别的,若 S ⇒ ∗ . . . A S\Rightarrow^{*} ...A S...A,则规定 # ∈ F O L L O W ( A ) \in FOLLOW(A) FOLLOW(A)
    • 理解: 在某个句型中,跟在非终结符A后面的的终结符 x 在A的FOLLOW集合中
  • LL(1)文法
    在这里插入图片描述
    第一个 L:left to right,从左到右扫描输入串
    第二个 L:leftmost derivation,最左推导
    (1):表示每一步只需向前查看 1 个字符


  • 构造每个文法符号的FIRST集合
    对每一个 A ∈ V T ∪ V N A\in V_T\cup V_N AVTVN,连续使用下面的规则,直至每个集合FIRST不再增大为止:
    1. A ∈ V T A\in V_T AVT,A是终结符,则 F I R S T ( A ) = { A } FIRST(A) = \{A\} FIRST(A)={A}
    2. A ∈ V N A\in V_N AVN,A是非终结符,且有产生式 A → x . . . A\rightarrow x... Ax...,其中 x x x 是一个终结符,则 把 x x x 加入到 F I R S T ( A ) FIRST(A) FIRST(A)中;
      A → ϵ A\rightarrow\epsilon Aϵ 也是一条产生式,则把 ϵ \epsilon ϵ 也加入到 F I R S T ( A ) FIRST(A) FIRST(A)
    3. A → B . . . A\rightarrow B... AB...是产生式,且 B B B是非终结符,则把 F I R S T ( B ) FIRST(B) FIRST(B)中的 非 ϵ \epsilon ϵ 元素都加到 F I R S T ( A ) FIRST(A) FIRST(A)
    4. A → B 1 B 2 . . . B i . . . B k A\rightarrow B_1B_2...B_i...B_k AB1B2...Bi...Bk是产生式,且 B 1 B 2 . . . B i − 1 B i . . . B k B_1B_2...B_{i-1}B_i...B_k B1B2...Bi1Bi...Bk都是非终结符
      ① 对于所有 j j j 1 ≤ j ≤ i − 1 1≤j≤i-1 1ji1 F I R S T ( B j ) FIRST(B_j) FIRST(Bj)都含有 ϵ \epsilon ϵ (即 B 1 . . . B i − 1 ⇒ ∗ ϵ B_1...B_{i-1}\Rightarrow^* \epsilon B1...Bi1ϵ),则把 F I R S T ( B i ) FIRST(B_i) FIRST(Bi)中的所有非 ϵ \epsilon ϵ 元素都加到 F I R S T ( A ) FIRST(A) FIRST(A)
      ② 若所有的 F I R S T ( B j ) FIRST(B_j) FIRST(Bj) 均含有 ϵ \epsilon ϵ j = 1 , 2 , . . . , k j=1,2,...,k j=1,2,...,k,则把 ϵ \epsilon ϵ 加到 F I R S T ( A ) FIRST(A) FIRST(A)
  • 构造任何符号串的FIRST集合
    对文法G的任何符号串 α = X 1 X 2 . . . X n \alpha=X_1X_2...X_n α=X1X2...Xn 构造集合 F I R S T ( α ) FIRST(\alpha) FIRST(α)
    1. F I R S T ( α ) = F I R S T ( X 1 ) FIRST(\alpha) = FIRST(X_1) FIRST(α)=FIRST(X1) \ { ϵ } \{\epsilon\} {ϵ}
    2. 若对任何 1 ≤ j ≤ i − 1 , ϵ ∈ F I R S T ( X j ) 1≤j≤i-1, \epsilon\in FIRST(X_j) 1ji1,ϵFIRST(Xj),则把 F I R S T ( X j ) FIRST(X_j) FIRST(Xj) \ { ϵ } \{\epsilon\} {ϵ} 加至 F I R S T ( α ) FIRST(\alpha) FIRST(α)
      特别的,若所有的 F I R S T ( X j ) FIRST(X_j) FIRST(Xj) 都含有 ϵ , 1 ≤ j ≤ n \epsilon, 1≤j≤n ϵ,1jn,则把 ϵ \epsilon ϵ也加至 F I R S T ( α ) FIRST(\alpha) FIRST(α)
      α = ϵ \alpha = \epsilon α=ϵ,则 F I R S T ( α ) = { ϵ } FIRST(\alpha) = \{\epsilon\} FIRST(α)={ϵ}

  • 构造每个 非终结符 的 FOLLOW集合
    对于文法G的每个非终结符A构造FOLLOW(A),连续使用下面的规则,直至每个FOLLOW集都不再增大为止:
    1. 对于文法的开始符号 S,置 # 于 FOLLOW(S)中
    2. A → α B β A\rightarrow \alpha B\beta Aα是一个产生式,则把 F I R S T ( β ) FIRST(\beta) FIRST(β) \ { ϵ } \{\epsilon\} {ϵ} 加至 F O L L O W ( B ) FOLLOW(B) FOLLOW(B)
    3. A → α B A\rightarrow \alpha B AαB是一个产生式,或 A → α B β A\rightarrow \alpha B\beta Aα β ⇒ ∗ ϵ \beta\Rightarrow^{*} \epsilon βϵ (即 ϵ ∈ F I R S T ( β ) \epsilon\in FIRST(\beta) ϵFIRST(β)),则把FOLLOW(A)加至FOLLOW(B)中

练习

  1. (4.2节 - 消除直接左递归)
    在这里插入图片描述
    答:对于 E 的左递归,可以变为 E → T E ′ E \rightarrow TE' ETE E ′ → + T E ′ ∣ ϵ E' \rightarrow +TE' | \epsilon E+TEϵ;对于 F 的左递归,可以变为 T → F T ′ T \rightarrow FT' TFT T ′ → ∗ F T ′ ∣ ϵ T' \rightarrow *FT' | \epsilon TFTϵ;F没有左递归。
  2. (4.2节 - 消除间接左递归)
    在这里插入图片描述
    答:第①步,对 非终结符 排序:B,A,S
    第②步,遍历排好序的非终结符,进行 身后变量替换消除直接左递归
    i = 1,B → Sa | a 无直接左递归,也不存在需要替换的身前语法变量
    i = 2,A → Bb | b,右侧的B在A前,替换B后得到 A → Sab | ab | b
    i = 3,S → Ac | c,右侧的A在S前,替换A得到 S → Sabc | abc | bc | c,发现直接左递归
    消除直接左递归,S → abcS’ | bcS’ | cS’,S’ → abcS’ | ϵ \epsilon ϵ
    第③步,简化得到的文法(学校老师没说qwq )

第5章 语法分析(自下向上)

5.1 LR(0)文法

  • 拓展文法
    G’(S’) = G(S) + { S’ → S }
  • 项目
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值