编译原理复习总结-耗子尾汁

抱佛脚 专栏收录该内容
5 篇文章 0 订阅

在这里插入图片描述

引论


  1. 编译程序运行框架
    在这里插入图片描述
词法分析器输入源程序,进行词法分析,输出单词符号。
语法分析器对单词符号串进行语法分析,识别出各类语法单位
语义分析与中间代码产生器按语义规则对归约出的语法单位进行语义分析并翻译成中间代码。
优化器对中间代码进行优化处理
目标代码生成器把中间代码翻译成目标程序
表格管理登记源程序的各类信息和编译各阶段的进展情况
出错处理对出现在源程序中的错误进行处理
  1. 编译前端和后端
  • 前端
    主要由与源语言有关但与目标机无关的那些部分(词法分析、语法分析、语义分析、中间代码产生)组成,有的代码优化工作也给包括在前端。
  • 后端
    包括编译程序中与目标机有关的那些部分(与目标机有关的代码优化、目标代码生成),后端通常依赖中间语言而不是源语言。
  1. 编译过程五个阶段
    词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。
    前四个阶段与硬件无关,最后一个阶段与硬件有关。

  2. 汇编语言和高级语言的区别
    汇编语言跟机器指令一一对应,高级语言不跟机器指令一一对应。

语法描述


  1. 乔姆斯基四型文法

乔姆斯基(Chomsky)把文法分成四种类型,即0型、1型、2型和3型。0型强于1型,1型强于2型,2型强于3型。这几类文法的差别在于对产生式加不同的限制。

0型短语文法能力相当于图灵机,都是递归可枚举的
1型上下文有关法即替换非终结符时考虑上下文 α \alpha α β \beta β α A β → α γ β \alpha A\beta→\alpha\gamma\beta αAβαγβ
2型上下文无关法即无需考虑上下文
3型右线性文法另一种形式左线性文法,也称正规文法, A → B α A→B\alpha ABα A → α A→\alpha Aα
  1. 上下文无关法
    一个上下文无关法G是一个四元式 G = ( V T , V N , S , P ) G=(V_T,V_N,S,P) G=(VT,VN,S,P),其中
    V T V_T VT:终结符集合(非空)
    V N V_N VN:非终结符集合(非空),且 V T ∩ V N = ∅ V_T\cap V_N=\varnothing VTVN=
    S S S:文法的开始符号, S ∈ V N S\in V_N SVN
    P P P:产生式集合(有限),每个产生式形式为 P → α , P ∈ V N , α ∈ ( V T ∪ V N ) ∗ P\rarr\alpha,P\in V_N,\alpha\in (V_T\cup V_N)^* Pα,PVN,α(VTVN),开始符 S S S至少必须在某个产生式的左部出现一次。

  2. 句型、句子
    假定G是一个文法,S是它的开始符号,称 S    ⟹    ∗ α S\overset{*}{\implies}\alpha Sα是一个句型,称仅含终结符的句型是一个句子。

    btw,符号    ⟹    ∗ \overset{*}{\implies} 指经过0步及以上推导;符号    ⟹    + \overset{+}{\implies} +指经过1步及以上推导;终结符指最终出现在程序中符号;非终结符是为了描述语法而创造出来的符号,不会出现在程序中。

    ( i ∗ i + i ) (i*i+i) (ii+i)是文法G(E): E → i ∣ E + E ∣ E ∗ E ∣ ( E ) E→i|E+E|E*E|(E) EiE+EEE(E)的一个句子,证明: E    ⟹    ( E )    ⟹    ( E + E )    ⟹    ( E ∗ E + E )    ⟹    ( i ∗ E + E )    ⟹    ( i ∗ i + E )    ⟹    ( i ∗ i + i ) E\implies(E)\implies(E+E)\implies(E*E+E)\implies(i*E+E)\implies(i*i+E)\implies(i*i+i) E(E)(E+E)(EE+E)(iE+E)(ii+E)(ii+i)

  3. 语言
    文法G所产生的句子的全体就是一个语言,记为L(G), L ( G ) = { α ∣ S    ⟹    + α & α ∈ V T ∗ } L(G)=\{\alpha|S\overset{+}{\implies}\alpha\&\alpha\in{V_{T}^{*}}\} L(G)={αS+α&αVT}

    例文法G1:A→c|Ab的语言L(G1)={cbn|n≥0};
    文法G2:S→AB,A→aA|a,B→bB|b的语言L(G2)={ambn|m,n≥1}。

词法分析


  1. 用状态图和正规式描述标识符
    在这里插入图片描述

结点代表状态,用圆圈表示。状态之间用箭弧连结。箭弧上的标记(字符)代表在射出节点状态下可能出现得输入字符或字符类。
其中0为初态,2为终态(用双圈表示)。终态结上打个星号*意味着多读进了一个不属于标识符部分得字符,应把它退还给输入串。

Σ = { A , B , 0 , 1 } \Sigma=\{A,B,0,1\} Σ={A,B,0,1}

正规式正规集
(A|B)(A|B|0|1)* Σ \Sigma Σ上“标识符”的全体
(0|1)(0|1)* Σ \Sigma Σ上“数”的全体
  1. 确定有限自动机(DFA)
    一个确定有限自动机M是一个五元式 M = ( S , Σ , δ , s 0 , F ) M=(S,\Sigma,\delta,s_0,F) M=(S,Σ,δ,s0,F),其中
    S S S:有穷状态集
    Σ \Sigma Σ:输入字母表(有穷)
    δ \delta δ:状态转换函数,为 S × Σ → S S×\Sigma\rarr S S×ΣS的单值部分映射, δ ( s , a ) = s ’ \delta(s, a)=s’ δ(s,a)=s表示:当现行状态为 s s s,输入字符为 a a a时,将状态转换到下一状态 s ’ s’ s。我们把 s ’ s’ s称为 s s s的一个后继状态。
    s 0 ∈ S s_0\in S s0S:初态(唯一)
    F ⊆ S F\sube S FS:终态集(可空)

  2. 非确定有限自动机(NFA)
    一个非确定有限自动机M是一个五元式 M = ( S , Σ , δ , S 0 , F ) M=(S,\Sigma,\delta,S_0,F) M=(S,Σ,δ,S0,F),其中
    S S S:有穷状态集
    Σ \Sigma Σ:输入字母表(有穷)
    δ \delta δ S × Σ ∗ → 2 S S×\Sigma^*\rarr2^S S×Σ2S
    S 0 ⊆ S S_0\sube S S0S:初态集(非空)
    F ⊆ S F\sube S FS:终态集(可空)

  3. LEX
    LEX用来描述和自动产生所需的各种词法分析器,包括正规式定义和识别规则两部分,将LEX程序编译后所得结果程序记为L,其作用同有限自动机一样,可用来识别和产生单词符号。
    在这里插入图片描述

  4. 确定化和最小化
    在这里插入图片描述
    (a)确定化

IIaIb
{0}{0,1}{1}
{0,1}{0,1}{1}
{1}{0} Φ \varPhi Φ
Φ \varPhi Φ Φ \varPhi Φ Φ \varPhi Φ

如({0},a)={0,1}表示{0}只经过弧a可以到达{0,1},以此类推。
给状态编号

sab
012
112
203
333

在这里插入图片描述

最小化
终态{0,1},非终态{2,3}

IIaIb
{0,1}{1}{2}
{2,3}{0,3}{3}

{0,1}包含了{1}和{2},所以不能再划分;
{0,3}不包含在{0,1}或{2,3}中,拆分由状态2经弧a到达状态0和由状态3经弧a到达状态3,即{2,3}    ⟹    \implies {2},{3};
得{{0,1},{2},{3}}

在这里插入图片描述

(b)已经确定化,进行最小化
终态{0,1},非终态{2,3,4,5}

IIaIb
{0,1}{1}{2,4}
{2,3,4,5}{0,1,3,5}{2,3,4,5}
{2,4}{0,1}{3,5}
{3,5}{3,5}{2,4}

{0,1,3,5}已经大于{0,1}了,故不继续分析
{1}和{2,4}包含于{0,1}、{2,3,4,5},故{0,1}不拆分;
{0,1,3,5}没有包含于{0,1}、{2,3,4,5};又状态24经弧a到达状态10,包含于{0,1},应拆24为一组(其他拆法可自验证),即拆分{2,3,4,5}为{2,4}、{3,5}

{{0,1},{2,4},{3,5}}

IIaIb
{0,1}{1}{2,4}
{2,4}{0,1}{3,5}
{3,5}{3,5}{2,4}

继续验证不可再拆,且都属于集合{{0,1},{2,4},{3,5}}。
在这里插入图片描述

语法分析


自上向下分析

  1. 消除左递归
    含有左递归的文法将使自上而下的分析过程写入无限循环,如 P    ⟹    + P α P\overset{+}{\implies}P\alpha P+Pα P    ⟹    P α    ⟹    P α α    ⟹    P α α α    ⟹    … … P\implies P\alpha\implies P\alpha\alpha\implies P\alpha\alpha\alpha\implies…… PPαPααPααα

    消除左递归可以在原产生式中增加一个非终结符,如 P → P α ∣ β P\rarr P\alpha|\beta PPαβ改写为(注意 β \beta β不以 P P P开头):
    P → β P ′ P\rarr\beta P' PβP
    P ′ → α P ′ ∣ ε P'\rarr\alpha P'|\varepsilon PαPε

  2. 消除回溯
    确保对输入符号准确的指派一个候选去执行任务且此候选的工作结果是确信无疑的,避免回溯推倒重来费时费力。

  3. First集和Follow集

  • 令G是一个不含左递归的文法,对G的所有非终结符的每个候选 α \alpha α定义它的终结首符集 F I R S T ( α ) FIRST(\alpha) FIRST(α)为:
    F I R S T ( α ) = { a ∣ α    ⟹    ∗ a . . . , a ∈ V T } FIRST(\alpha)=\{a|\alpha\overset{*}{\implies}a...,a\in V_T\} FIRST(α)={aαa...,aVT}
  • 假定S是文法G的开始符号,对于G的任何非终结符A,定义 F O L L O W ( A ) FOLLOW(A) FOLLOW(A)
    F O L L O W ( A ) = { a ∣ S    ⟹    ∗ . . . A a . . . , a ∈ V T } FOLLOW(A)=\{a|S\overset{*}{\implies}...Aa...,a \in V_T\} FOLLOW(A)={aS...Aa...,aVT}
    安利DZ大佬的讲解
  1. LL(1)文法
    ①文法不含左递归

    ②对于文法中每一个非终结符A的各个产生式的候选首符集两两不相交
    即,若 A → α 1 ∣ α 2 ∣ . . . ∣ α n A\rarr\alpha_1|\alpha_2|...|\alpha_n Aα1α2...αn
    F I R S T ( α i ) ∩ F I R S T ( α j ) = Φ FIRST(\alpha_i)\cap FIRST(\alpha_j)=\varPhi FIRST(αi)FIRST(αj)=Φ

    ③对文法中的每个非终结符A,若它存在某个候选首符集合包含 ε \varepsilon ε
    F I R S T ( A ) ∩ F O L L O W ( A ) = Φ FIRST(A)\cap FOLLOW(A)=\varPhi FIRST(A)FOLLOW(A)=Φ

    文法G满足以上条件,则称G为LL(1)文法。

  2. LL(1)基本思想
    顾名思义,第一个L表示从左到右扫描输入串,第二个L表示最左推导,1表示分析时每一步只需向前查看一个符号。即根据输入串的当前输入符号来唯一确定选用哪个产生式来进行推导,从而消除左递归和回溯。

  3. 递归下降分析优缺点

优点缺点
分析高效(线性时间)频繁递归工作效率低
错误定位和诊断信息准确缺乏完善语法检查和出错处理
容易实现(方便编码)
  1. LL(1)分析过程
    比如如下分析表:
i+
EE→TE’
E’E’→TE’

太多了不想画,举一反三
初始时栈内是#E,例输入串为i,则根据表格栈顶元素E遇到i时,用TE’替代E,即逆序入栈,此时栈内为#E’T,以此类推,当输入串和栈顶都是#(结束符号)时表示成功,如果遇到分析表是空白的,则报错,如果是替换 ε \varepsilon ε,则意味不入栈。

插播反爬信息 )博主CSDN地址:https://wzlodq.blog.csdn.net/

  1. 下面文法中,那些是LL(1)的,说明理由。

(1)
S → A b c S\rarr Abc SAbc
A → a ∣ ε A\rarr a|\varepsilon Aaε
B → b ∣ ε B\rarr b|\varepsilon Bbε

FIRSTFOLLOW
S{a,b}{#}
A{a, ε \varepsilon ε}{b}
b{b, ε \varepsilon ε} Φ \varPhi Φ

是,满足三个条件

(2)
S → A b S\rarr Ab SAb
A → a ∣ B ∣ ε A\rarr a|B|\varepsilon AaBε
B → b ∣ ε B\rarr b|\varepsilon Bbε

FIRSTFOLLOW
S{a,b}{#}
A{a,b, ε \varepsilon ε}{b}
B{b, ε \varepsilon ε}{b}

FIRST(A) ∩ \cap FOLLOW(A)={b}
FIRST(B) ∩ \cap FOLLOW(B)={b}
不是,A、B不满足条件③

(3)
S → A B B A S\rarr ABBA SABBA
A → a ∣ ε A\rarr a|\varepsilon Aaε
B → b ∣ ε B\rarr b|\varepsilon Bbε

FIRSTFOLLOW
S{a,b, ε \varepsilon ε}{#}
A{a, ε \varepsilon ε}{#,a,b}
B{b, ε \varepsilon ε}{#,a,b}

FIRST(A) ∩ \cap FOLLOW(A)={a}
FIRST(B) ∩ \cap FOLLOW(B)={b}
不是,A、B不满足条件③
(4)
S → a S e ∣ B S\rarr aSe|B SaSeB
B → b B e ∣ C B\rarr bBe|C BbBeC
C → c C e ∣ d C\rarr cCe|d CcCed

FIRSTFOLLOW
S{a,b,c,d}{#,e}
B{b,c,d}{#,e}
C{c,d}{#,e}

FIRST(aSe) ∩ \cap FIRST(B)= Φ \varPhi Φ
FIRST(bBe) ∩ \cap FIRST(C )= Φ \varPhi Φ
FIRST(cCe) ∩ \cap FIRST(d)= Φ \varPhi Φ
是,满足三个条件
其实没有 ε \varepsilon ε可以不用求FOLLOW集。

自下向上分析

  1. 短语、直接短语、句柄
    G G G是一个文法, S S S是文法的开始符号,假定 α β δ \alpha\beta\delta αβδ是文法 G G G的一个句型,如果有
    S    ⟹    ∗ α A δ S\overset{*}{\implies}\alpha A\delta SαAδ A    ⟹    + β A\overset{+}{\implies}\beta A+β
    则称 β \beta β是句型 α β δ \alpha\beta\delta αβδ相对于非终结符A的短语。特别是,如果有
    A → β A\rarr\beta Aβ
    则称 β \beta β是句型 α β δ \alpha\beta\delta αβδ相对于规则 A → β A\rarr\beta Aβ直接短语,一个句型的最左直接短语称为该句型的句柄

  2. 规范规约、规范推导
    假定 α \alpha α是文法 G G G的一个句子,我们称序列 α n , α n − 1 . . . , a 0 \alpha_n,\alpha_{n-1}...,a_0 αn,αn1...,a0 α \alpha α的一个规范规约,如果此序列满足:
    α n = α \alpha_n=\alpha αn=α
    α 0 \alpha_0 α0为文法的开始符,即 α 0 = S \alpha_0=S α0=S
    ③对任何 i , 0 < i ≤ n , α i − 1 i,0<i≤n,\alpha_{i-1} i,0<in,αi1是从 α i \alpha_i αi经把句柄替换为相应产生式的左部符号而得到的。

    规范规约是关于 α \alpha α的一个最右推导的逆过程,故规范规约也称最左规约。
    在形式语言中,最右推导常被称为规范推导,由规范推导所得的句型称为规范句型。

  3. 前缀、活前缀
    字的前缀是指该字的任意首部。例如字abc的前缀有ε、a、ab或abc。所谓活前缀是指规范句型的一个前缀,这种前缀不含句柄之后的任何符号。之所以称为活前缀,是因为在右边增添一些终结符号之后,就可以使它成为一个规范句型。
    在LR分析工作过程中的任何时候,栈里的文法符号(自栈底而上)X1X2…Xm应该构成活前缀,把输入串的剩余部分配上之后即应成为规范句型(如果整个输入串确实构成一个句子)。因此只要输入串的已扫描部分保持可归约成一个活前缀,那就意味着所扫描过的部分没有错误。

  4. LR分析基本思想
    在规约过程中,一方面记住已移进和规约出的整个符号串,即记住“历史”;
    另一方面根据所用的产生式推测未来可能遇到的输入符号,即对未来进行“展望”;
    最后结合“现实”的输入符号来确定栈顶符号串是否构成相对某一产生式的句柄。

  5. 有效项目
    我们说项目 A → β 1 ⋅ β 2 A\rarr\beta_1·\beta_2 Aβ1β2对活前缀 α β 1 \alpha\beta_1 αβ1有效的,其条件是存在规范推导:
    S ′    ⟹    R ∗ α A w    ⟹    R α β 1 β 2 w S'\overset{*}{\underset{R}{\implies}}\alpha Aw\underset{R}{\implies}\alpha\beta_1\beta_2w SRαAwRαβ1β2w

  6. LR(1)分析过程
    在这里插入图片描述
    (1)sj 把下一状态j和现行输入符号a移进栈;
    (2) rj 按第j个产生式进行归约;
    (3)acc 接受;
    (4)空白格 出错标志,报错

    利用图5.5 分析表,假定输人串为 i ∗ i + i i*i+i ii+i,LR分析器的工作过程(即,三元式的变化过程)如下:
    在这里插入图片描述

  • 第(1)步到第(2)步:状态0,输入i,定位表格[0,i]=s5,入栈状态5和输入i,输入串出栈;
  • 第(2)步到第(3)步:栈顶状态5,输入*,定位[5,*]=r6,用第6个产生式F→i规约,出栈5和i,入栈F,此时看GOTO,栈顶状态0,定位[0,F],入栈状态3;
  • 第(3)步到第(4)步:定位[3,*]=r4,用第4个产生式T→F规约,出栈3和F,入栈T,此时GOTO[0,T]=2,入栈状态2;
  • 第(3)步到第(4)步:定位[2,*]=s7,入栈状态7和输出*,输入串出栈;
  • 以此类推,不一一写了。
  1. LR(0)分析过程:
    考虑文法
    S → A S ∣ b S\rarr AS|b SASb
    A → S A ∣ a A\rarr SA|a ASAa
    (1)列出这个文法的所有LR(0)项目。
    0 S ′ → ⋅ S S'\rarr·S SS
    1 S ′ → S ⋅ S'\rarr S· SS
    2 S → ⋅ A S S\rarr ·AS SAS
    3 S → A ⋅ S S\rarr A·S SAS
    4 S → A S ⋅ S\rarr AS· SAS
    5 S → ⋅ b S\rarr ·b Sb
    6 S → b ⋅ S\rarr b· Sb
    7 A → ⋅ S A A\rarr ·SA ASA
    8 A → S ⋅ A A\rarr S·A ASA
    9 A → S A ⋅ A\rarr SA· ASA
    10 A → ⋅ a A\rarr ·a Aa
    11 A → a ⋅ A\rarr a· Aa
    (2)构造这个文法的LR(0)项目集规范族及识别活前缀的DFA。
    在这里插入图片描述

确定化

SAab
{0,2,5,7,10}{1,2,5,7,8,10}{2,3,5,7,10}{11}{6}
{1,2,5,7,8,10}{2,5,7,8,10}{2,3,5,7,9,10}{11}{6}
{2,3,5,7,9,10}{2,4,5,7,8,10}{2,3,5,7,10}{11}{6}
{2,4,5,7,8,10}{2,5,7,8,10}{2,3,5,7,9,10}{11}{6}
{11} Φ \varPhi Φ Φ \varPhi Φ Φ \varPhi Φ Φ \varPhi Φ
{6} Φ \varPhi Φ Φ \varPhi Φ Φ \varPhi Φ Φ \varPhi Φ

在这里插入图片描述

I 0 = S ′ → ⋅ S , S → ⋅ A S , S → ⋅ b . A → ⋅ S A , A → ⋅ a I_0={S'\rarr·S,S\rarr·AS,S\rarr·b.A\rarr·SA,A\rarr·a} I0=SS,SAS,Sb.ASA,Aa
G O ( I 0 , a ) = { A → a ⋅ } = I 1 GO(I_0,a)=\{A\rarr a·\}=I_1 GO(I0,a)={Aa}=I1
G O ( I 0 , b ) = { S → b ⋅ } = I 2 GO(I_0,b)=\{S\rarr b·\}=I_2 GO(I0,b)={Sb}=I2
G O ( I 0 , S ) = { S ′ → S ⋅ , A → S ⋅ A , S → ⋅ A S , S → ⋅ b , A → ⋅ S A , A →   a ⋅ } = I 3 GO(I_0,S)=\{S'\rarr S·,A\rarr S·A,S\rarr ·AS,S\rarr ·b,A\rarr ·SA,A\rarr\ a·\}=I_3 GO(I0,S)={SS,ASA,SAS,Sb,ASAA a}=I3
G O ( I 0 , A ) = { S → A ⋅ S , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 4 GO(I_0,A)=\{S\rarr A·S,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_4 GO(I0,A)={SAS,SAS,Sb,A SA,Aa}=I4

G O ( I 3 , a ) = { A → a ⋅ } = I 1 GO(I_3,a)=\{A\rarr a·\}=I_1 GO(I3,a)={Aa}=I1
G O ( I 3 , b ) = { S → b ⋅ } = I 2 GO(I_3,b)=\{S\rarr b·\}=I_2 GO(I3,b)={Sb}=I2
G O ( I 3 , S ) = { A → S ⋅ , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 5 GO(I_3,S)=\{A\rarr S·,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_5 GO(I3,S)={AS,SAS,Sb,A SA,Aa}=I5
G O ( I 3 , A ) = { A → S A ⋅ , S → A ⋅ S , S → ⋅ A S , S →   ⋅ b , A → ⋅ S A , A → ⋅ a } = I 6 GO(I_3,A)=\{A\rarr SA·,S\rarr A·S,S\rarr ·AS,S\rarr\ ·b,A\rarr ·SA,A\rarr ·a\}=I_6 GO(I3,A)={ASA,SAS,SAS,S b,ASA,Aa}=I6

G O ( I 4 , a ) = { A → a ⋅ } = I 1 GO(I_4,a)=\{A\rarr a·\}=I_1 GO(I4,a)={Aa}=I1
G O ( I 4 , b ) = { S → b ⋅ } = I 2 GO(I_4,b)=\{S\rarr b·\}=I_2 GO(I4,b)={Sb}=I2
G O ( I 4 , S ) = { S → A S ⋅ , A → S ⋅ A , S → ⋅ A S , S →   ⋅ b , A → ⋅ S A , A → ⋅ a } = I 7 GO(I_4,S)=\{S\rarr AS·,A\rarr S·A,S\rarr ·AS,S\rarr\ ·b,A\rarr ·SA,A\rarr ·a\}=I_7 GO(I4,S)={SAS,ASA,SAS,S b,ASA,Aa}=I7
G O ( I 4 , A ) = { S → A ⋅ S , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 4 GO(I_4,A)=\{S\rarr A·S,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_4 GO(I4,A)={SAS,SAS,Sb,A SA,Aa}=I4

G O ( I 5 , a ) = { A → a ⋅ } = I 1 GO(I_5,a)=\{A\rarr a·\}=I_1 GO(I5,a)={Aa}=I1
G O ( I 5 , b ) = { S → b ⋅ } = I 2 GO(I_5,b)=\{S\rarr b·\}=I_2 GO(I5,b)={Sb}=I2
G O ( I 5 , S ) = { A → S ⋅ A , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 5 GO(I_5,S)=\{A\rarr S·A,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_5 GO(I5,S)={ASA,SAS,Sb,A SA,Aa}=I5
G O ( I 5 , A ) = { A → S A ⋅ , S → A ⋅ S , A → S ⋅ A , S → ⋅ A S , S →   ⋅ b , A → ⋅ S A , A → ⋅ a } = I 6 GO(I_5,A)=\{A\rarr SA·,S\rarr A·S,A\rarr S·A,S\rarr ·AS,S\rarr\ ·b,A\rarr ·SA,A\rarr ·a\}=I_6 GO(I5,A)={ASA,SAS,ASA,SAS,S b,ASA,Aa}=I6

G O ( I 6 , a ) = { A → a ⋅ } = I 1 GO(I_6,a)=\{A\rarr a·\}=I_1 GO(I6,a)={Aa}=I1
G O ( I 6 , b ) = { S → b ⋅ } = I 2 GO(I_6,b)=\{S\rarr b·\}=I_2 GO(I6,b)={Sb}=I2
G O ( I 6 , S ) = { S → A S ⋅ , A → S ⋅ A , S → ⋅ A S , S →   ⋅ b , A → ⋅ S A , A → ⋅ a } = I 7 GO(I_6,S)=\{S\rarr AS·,A\rarr S·A,S\rarr ·AS,S\rarr\ ·b,A\rarr ·SA,A\rarr ·a\}=I_7 GO(I6,S)={SAS,ASA,SAS,S b,ASA,Aa}=I7
G O ( I 6 , A ) = { S → A ⋅ S , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 4 GO(I_6,A)=\{S\rarr A·S,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_4 GO(I6,A)={SAS,SAS,Sb,A SA,Aa}=I4

G O ( I 7 , a ) = { A → a ⋅ } = I 1 GO(I_7,a)=\{A\rarr a·\}=I_1 GO(I7,a)={Aa}=I1
G O ( I 7 , b ) = { S → b ⋅ } = I 2 GO(I_7,b)=\{S\rarr b·\}=I_2 GO(I7,b)={Sb}=I2
G O ( I 7 , S ) = { A → S ⋅ A , S → ⋅ A S , S → ⋅ b , A →   ⋅ S A , A → ⋅ a } = I 5 GO(I_7,S)=\{A\rarr S·A,S\rarr ·AS,S\rarr ·b,A\rarr\ ·SA,A\rarr ·a\}=I_5 GO(I7,S)={ASA,SAS,Sb,A SA,Aa}=I5
G O ( I 7 , A ) = { A → S A ⋅ , S → A ⋅ S , A → S ⋅ A , S → ⋅ A S , S →   ⋅ b , A → ⋅ S A , A → ⋅ a } = I 6 GO(I_7,A)=\{A\rarr SA·,S\rarr A·S,A\rarr S·A,S\rarr ·AS,S\rarr\ ·b,A\rarr ·SA,A\rarr ·a\}=I_6 GO(I7,A)={ASA,SAS,ASA,SAS,S b,ASA,Aa}=I6

项目集规范族为 C = { I 0 , I 1 , I 2 , I 3 , I 4 , I 5 , I 6 , I 7 } C=\{I_0,I_1,I_2,I_3,I_4,I_5,I_6,I_7\} C={I0,I1,I2,I3,I4,I5,I6,I7}

属性文法


属性文法、综合属性、继承属性
属性文法(也称属性翻译文法)是在上下文无关文法的基础上为每个文法符号(终结符或非终结符)配备若干相关的“值"(称为属性)。.

这些属性代表与文法符号相关信息,例如它的类型、值、代码序列、符号表内容等等。属性与变量一样,可以进行计算和传递。属性加工的过程即是语义处理的过程。对于文法的每个产生式都配备了一组属性的计算规则,称为语义规则。

综合属性:自下而上传递信息
继承属性:自上而下传递信息
要特别强调的是:

  1. 终结符只有综合属性,它们由词法分析器提供;
  2. 非终结符既可有综合属性也可有继承属性,文法开始符号的所有继承属性作为属性计算前的初始值。

语义分析和是中间代码产生


中间代码生成对编译器构造的意义

  1. 便于进行与机器无关的代码优化工作;
  2. 使编译程序改变目标机更容易;
  3. 使编译程序的结构在逻辑上更为简单明确。以中间语言为界面,编译前端和后端的接口更清晰。

优化


代码优化的原则

  1. 等价原则:经过优化后不应改变程序运行的结果。
  2. 有效原则:使优化后所产生的目标代码运行时间较短,占用的存储空间较小。
  3. 合算原则:应尽可能以较低的代价取得较好的优化效果。

目标代码生成


代码生成器的输出是目标程序,目标程序有哪几种形式?

  1. 能够立即执行的机器语言代码,所有地址均已定位(代真)。
  2. 待装配的机器语言模块。当需要执行时,由连接装入程序把它们和某些运行程序连接起来,转换成能执行的机器语言代码。
  3. 汇编语言代码,尚需经过汇编程序汇编,转换成可执行的机器语言代码。

在这里插入图片描述
参考文献
《程序设计语言编译原理(第3版)》-陈火旺等著

原创不易,请勿转载本不富裕的访问量雪上加霜
博主首页:https://wzlodq.blog.csdn.net/
来都来了,不评论两句吗👀
如果文章对你有帮助,记得一键三连❤

相关推荐
<p> <span style="font-size:14px;color:#337FE5;">【为什么学爬虫?】</span> </p> <p> <span style="font-size:14px;">       1、爬虫入手容易,但是深入较难,如何写出高效率的爬虫,如何写出灵活性高可扩展的爬虫都是一项技术活。另外在爬虫过程中,经常容易遇到被反爬虫,比如字体反爬、IP识别、验证码等,如何层层攻克难点拿到想要的数据,这门课程,你都能学到!</span> </p> <p> <span style="font-size:14px;">       2、如果是作为一个其他行业的开发者,比如app开发,web开发,学习爬虫能让你加强对技术的认知,能够开发出更加安全的软件和网站</span> </p> <p> <br /> </p> <span style="font-size:14px;color:#337FE5;">【课程设计】</span> <p class="ql-long-10663260"> <span> </span> </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 一个完整的爬虫程序,无论大小,总体来说可以分成三个步骤,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 网络请求:模拟浏览器的行为从网上抓取数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据解析:将请求下来的数据进行过滤,提取我们想要的数据。 </li> <li class="" style="font-size:11pt;color:#494949;"> 数据存储:将提取到的数据存储到硬盘或者内存中。比如用mysql数据库或者redis等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 那么本课程也是按照这几个步骤循序渐进的进行讲解,带领学生完整的掌握每个步骤的技术。另外,因为爬虫的多样性,在爬取的过程中可能会发生被反爬、效率低下等。因此我们又增加了两个章节用来提高爬虫程序的灵活性,分别是: </p> <ol> <li class="" style="font-size:11pt;color:#494949;"> 爬虫进阶:包括IP代理,多线程爬虫,图形验证码识别、JS加密解密、动态网页爬虫、字体反爬识别等。 </li> <li class="" style="font-size:11pt;color:#494949;"> Scrapy和分布式爬虫:Scrapy框架、Scrapy-redis组件、分布式爬虫等。 </li> </ol> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 通过爬虫进阶的知识点我们能应付大量的反爬网站,而Scrapy框架作为一个专业的爬虫框架,使用他可以快速提高我们编写爬虫程序的效率和速度。另外如果一台机器不能满足你的需求,我们可以用分布式爬虫让多台机器帮助你快速爬取数据。 </p> <p style="font-size:11pt;color:#494949;">   </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> 从基础爬虫到商业化应用爬虫,本套课程满足您的所有需求! </p> <p class="ql-long-26664262" style="font-size:11pt;color:#494949;"> <br /> </p> <p> <br /> </p> <p> <span style="font-size:14px;background-color:#FFFFFF;color:#337FE5;">【课程服务】</span> </p> <p> <span style="font-size:14px;">专属付费社群+定期答疑</span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"><br /> </span> </p> <p> <br /> </p> <p class="ql-long-24357476"> <span style="font-size:16px;"></span> </p>
©️2020 CSDN 皮肤主题: 护眼 设计师:闪电赇 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值