【编译原理】消除左递归与提取左因子

消除左递归

快速消除左递归

原文法(保证 β \beta β不含 P P P): P → P α 1 ∣ P α 2 ∣ P α 3 ∣ . . . ∣ P α n ∣ β 1 ∣ β 2 ∣ β 3 ∣ . . . ∣ β n P \rightarrow P\alpha_1|P\alpha_2|P\alpha_3|...|P\alpha_n|\beta_1|\beta_2|\beta_3|...|\beta_n PPα1Pα2Pα3...Pαnβ1β2β3...βn

消除后文法: P → β 1 P ′ ∣ β 2 P ∣ β 3 P ′ ∣ . . . ∣ β n P ′ P \rightarrow \beta_1P'|\beta_2P |\beta_3P'|...|\beta_nP' Pβ1Pβ2Pβ3P...βnP P ′ → α 1 P ′ ∣ α 2 P ′ ∣ α 3 P ′ ∣ . . . ∣ α n P ′ ∣ ϵ P' \rightarrow \alpha_1P'|\alpha_2P'|\alpha_3P'|...|\alpha_nP'|\epsilon Pα1Pα2Pα3P...αnPϵ

一般方法

example: 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

step1: 把文法右侧换为一个变量(符号)
S → S a b c ∣ a b c ∣ b c ∣ c S\rightarrow Sabc|abc|bc|c SSabcabcbcc Q → S a b ∣ a b ∣ b Q \rightarrow Sab|ab|b QSababb R → S a ∣ a R \rightarrow Sa|a RSaa

step2: 使用快速消除左递归转换带有公共符号的行
S → a b c S ′ ∣ b c S ′ ∣ c S ′ S\rightarrow abcS'|bcS'|cS' SabcSbcScS S ′ → a b c S ′ ∣ ϵ S'\rightarrow abcS'|\epsilon SabcSϵ Q → S a b ∣ a b ∣ b Q \rightarrow Sab|ab|b QSababb R → S a ∣ a R \rightarrow Sa|a RSaa

step3: 去掉无用的变量
S → a b c S ′ ∣ b c S ′ ∣ c S ′ S\rightarrow abcS'|bcS'|cS' SabcSbcScS S ′ → a b c S ′ ∣ ϵ S'\rightarrow abcS'|\epsilon SabcSϵ

消除左因子

一般方法

原始文法: A → s α 1 ∣ s α 2 ∣ . . . ∣ s α n ∣ β 1 ∣ β 2 ∣ . . . ∣ β n A\rightarrow s\alpha_1|s\alpha_2|...|s\alpha_n|\beta_1|\beta_2|...|\beta_n Asα1sα2...sαnβ1β2...βn
处理后文法: A → s A ′ ∣ β 1 ∣ β 2 ∣ . . . ∣ β n A\rightarrow sA'|\beta_1|\beta_2|...|\beta_n AsAβ1β2...βn A ′ → α 1 ∣ α 2 ∣ . . . ∣ α n A' \rightarrow \alpha_1|\alpha_2|...|\alpha_n Aα1α2...αn

First Set and Follow Set

First Set

找文法的左面,看右面。右面是终结符就append,不是就append这个非终结符的FirstSet。

Follow Set

找文法的右面谁出现要求的非终结符。看要求的符号右侧是谁,是终结符就append,非终结符append其去空的FirstSet,在末尾就append左边的终结符。(此处因为已经提前去除了左递归因此不会出现问题)

你可能感兴趣的:(总结)