美文网首页
编译原理(部分)

编译原理(部分)

作者: 隨筆塗鴉 | 来源:发表于2019-06-26 22:06 被阅读0次

    第1章 引论

    1.1 什么是编译程序
    • 功能:高级语言程序(源程序)→【编译程序】→低级语言程序(目标程序)
    • 过程
      需预处理的源程序→【预处理程序】→源程序→
      【编译程序】→目标汇编语言程序→【汇编程序】→
      可再装配的机器代码[+可再装配目标文件]→
      【装配/连接编辑程序】→绝对机器代码
    1.2 编译过程和编译程序的结构
    • 阶段
      源程序→【词法分析】→【语法分析】→【语义分析】→
      【中间代码生成】→【代码优化】→【目标代码生成】→目标程序
    • =====================================================
    • 结构
      【词法分析程序】+【语法分析程序】+【语义分析程序】+
      【中间代码生成程序】+【代码优化程序】+【目标代码生成程序】+
      【表格管理程序】【出错处理程序】
    • =====================================================
    • 组合
      前端(front end)工作主要依赖于源语言而与目标机无关;
      后端(back end)工作依赖于目标机而一般不依赖于源语言。
    1.3 解释程序
    • 区别:编译产生中间代码。

    第2章 文法和语言

    2.2 符号和符号串
    1. 字母表:元素的非空有穷集合,元素称为符号,因此字母表也成为符号集。

    2. 符号串:字母表中的符号组成的任何有穷序列,讲究顺序,允许空符号串\epsilon,其长度为0,即|\epsilon|=0。符号串有头/尾,头/尾非空称为固有头/尾。符号串有连接/方幂/集合运算,其中,\epsilon是连接运算的单位元,即s\epsilon=\epsilon s=s。指定字母表为\Sigma,则\Sigma^*表示字母表上所有有穷长的串的集合,称为\Sigma闭包\Sigma^+称为正闭包

    \Sigma^*=\Sigma^0\cup\Sigma^1\cup\dots\cup\Sigma^n\cup\dots
    \Sigma^*=\Sigma^0\cup\Sigma^+,\Sigma^+= \Sigma\Sigma^*=\Sigma^*\Sigma

    1. 规则:也称重写规则、产生式或生成式,是形如\alpha\to\beta\alpha::=\beta(\alpha,\beta)有序对。其中,\alpha称为左部,\beta称为右部,符号\to(::=)读作“定义为”。

    2. 文法G定义为四元组(V_N,V_T,P,S),其中,V_N为非终结符集/语法实体集/变量集,V_T为终结符集,P为产生式(\alpha\to\beta)的集合,\alpha,\beta\in(V_N\cup V_T)^*且至少有一个\alpha是非终结符,S为识别符/开始符,也是非终结符,至少要在一条产生式中作为左部出现。V_N\cap V_T=\emptysetV=V_N\cup V_T,称为文法G的字母表/字汇表。G=G[S]

    3. 推导:直接推导\Rightarrow,长度为n(n\geqslant1)的推导\overset{+}{\Rightarrow},长度为n(n\geqslant0)的推导\overset{*}{\Rightarrow}直接推导\alpha\to\beta,\text{both }\gamma\text{ and }\delta\in V^*,v=\gamma\alpha\delta,,如果w=\gamma\beta\delta,则v\Rightarrow w,称v直接产生w,或wv的直接推导,或w直接归约到v。若有v\overset{+}{\Rightarrow}wv=w,则记作v\overset{*}{\Rightarrow}w

    2.3 文法和语言的形式定义
    1. 对于文法G[S]x为符号串,若S\overset{*}{\Rightarrow}x,则称x是文法G[S]句型;若x仅由终结符号组成,即S\overset{*}{\Rightarrow}x,x\in V_T^*,则称xG[S]句子

    2. 可用L(G)表示文法G所产生的语言——集合{\{x|S\overset{*}{\Rightarrow}x,x\in V_T^* \}}文法描述的语言是该文法一切句子的集合。若L(G1)=L(G2),则称文法G1G2是等价的。

    3. 文法的类型:乔姆斯基(Chomsky)于1956年建立形式语言的描述,把文法分为四种类型,即0型、1型、2型和3型。设G=(V_N,V_T,P,S),产生式\alpha\to\beta

    2.4 文法的类型
    • 0型文法/短语文法,满足\alpha,\beta\in(V_N\cup V_T)^*且至少有一个\alpha是非终结符,能力相当于图灵机,0型语言都是递归可枚举的,反之递归可枚举集必是一个0型文法;

    • 1型文法/上下文有关文法,除S\to\epsilon外,满足|\beta|\geqslant|\alpha|

    • 2型文法/上下文无关文法,满足\alpha是一个非终结符且\beta\in(V_N\cup V_T)^*,也表示成A\to\beta,A\in V_N,用\beta取代非终结符A时,与A所在的上下文无关;

    • 3型文法/正规文法,满足A\to aBA\to a,且a\in V_T^*=V_T\cup\{\epsilon \},其中A,B都是非终结符。

    2.5 上下文无关文法及其语法树
    • 语法树/推导树,满足下列四个条件:
    1. 每个结点都有一个标记,是V的一个符号;
    2. 根的标记是S
    3. 若一个结点n至少有一个除自己外的子孙,且有标记A,则A\in V_N
    4. 若结点n的直接子孙从左到右的次序是n_1,n_2,\dots,n_k,其标记分别为A_1,A_2,\dots,A_k,则A\to A_1A_2\dots A_k一定是P中的一个产生式。
    • 如果推导的任何一步都是对最左/最右的非终结符进行替换,则称为最左/最右推导。最右推导常称为规范推导,得到的句型称为右句型/规范句型

    • 如果一个文法存在某个句子对应两棵不同的语法树,或者说,若一个文法存在某个句子有两个不同的最左/最右推导,则说该文法是二义的。文法的二义性≠语言的二义性,存在G\neq G',L(G)=L(G')的可能。如果产生上下文无关语言的每个文法都是二义的,则说此语言是先天二义的。理论证明,判定任给的一个上下文无关文法是否为二义的,或者该文法是否产生一个先天二义的上下文无关语言,都是递归不可解的问题——不存在一个算法,能在有限步骤内确切判定任给的一个文法是否为二义的。

    2.6 句型的分析
    • 定义:G,S\alpha\beta\delta是文法的一个句型,若S\overset{*}{\Rightarrow}\alpha A\deltaA\overset{+}{\Rightarrow}\beta,则称\beta是句型\alpha\beta\delta相对于非终结符A短语。特别地,若A\Rightarrow\beta,则称\beta是句型\alpha\beta\delta相对于产生式A\to\beta直接短语/简单短语。一个右句型的直接短语称为该句型的句柄
    2.7 文法应用的补充说明
    • 文法中不能存在有害规则(形如U\to U,引起文法的二义性)和多余规则(不可到达的和不可终止的)。

    • 对于文法G=(V_N,V_T,S,P),为保证非终结符A在句子推导中出现,须满足:

    1. A必须出现在某句型中,即有S\overset{*}{\Rightarrow}\alpha A\beta,\alpha\text{ and }\beta\in(V_N\cup V_T)^*
    2. 必须能从A推导出终结符号串t,即A\overset{+}{\Rightarrow}t,t\in V_T^*

    第3章 词法分析

    3.3 单词的形式化描述工具
    3.3.1 正规文法
    • 3型文法A\to aB,A\to a,A\text{ and }B\in V_N,a\in V_T^*=V_T\cup \{\epsilon \}
    3.3.2 正规式
    • ……
    3.3.3 正规文法等价于正规式
    • 正规式转换成正规文法:
    正规式 文法产生式
    规则1 A\to xy A\to xB,B\to y,B\in V_N
    规则2 A\to x^*y A\to xB,A\to y,B\to xB,B\to y
    规则3 A\to x|y A\to x,A\to y
    • 正规文法转换成正规式:
    文法产生式 正规式
    规则1 A\to xB,B\to y A=xy
    规则2 A\to xA|y A=x^*y
    规则3 A\to xz,A\to yz A=(x|y)z
    3.4 有穷自动机
    • 确定的有穷自动机(DFA)和不确定的有穷自动机(NFA)。
    3.4.1 DFA
    • M=(K,\Sigma,f,S,Z)
      K是有穷集,其每个元素称为一个状态;
      \Sigma是有穷字母表,其每个元素称为一个输入符号,故又称输入符号表;
      f是转换函数,是K\times\Sigma\to K的映像,令f(k_i,a)=k_j,k_i\text{ and }k_j\in K,当前状态为k_i,输入字符为a时,将转换到下一状态k_jk_j称作k_i的一个后继状态;
      S\in K是唯一的一个初态;Z\subseteq K是一个终态集,终态也称可接受状态/结束状态。
    • t\in\Sigma^*f(S,t)=P,P\in Z,则称t可为该DFA所接受/识别。
    • DFAM所能接受的符号串的全体记为L(M)\Sigma上的一个符号串集V\in\Sigma^*是正规的,当且仅当存在一个\Sigma上的确定有穷自动机M,使得V=L(M)
    3.4.2 NFA
    • M=(K,\Sigma,f,S,Z)
      K是有穷集,其每个元素称为一个状态;
      \Sigma是有穷字母表,其每个元素称为一个输入符号;
      f是一个K\times\Sigma^*\to K的全体子集的映像,
      K\times\Sigma^*\to2^K,其中2^K表示K的幂集;
      S\subseteq K是一个非空初态集;Z\subseteq K是一个终态集。
    • 对于每个NFAM,都存在一个DFAM',使得L(M)=L(M')。对于任何两个有穷自动机M,M',若L(M)=L(M'),则称两者是等价的。
    3.4.3 NFA转换为等价的DFA
    • 子集构造算法

    \epsilon-closure(s):能够从NFA的状态s开始只通过\epsilon转换到达的NFA状态集合

    \epsilon-closure(T):能够从T中某个NFA状态s开始只通过\epsilon转换到达的NFA状态集合,即\cup_{s\in T}\epsilon-closure(s)

    moveTo(T,a):能够从T中某个状态s出发通过标号为a的转换到达的NFA状态集合

    • NFA的开始状态集合用A标记,A=\epsilon-closure(0),然后反复依次读取字母表,每次记录变化的NFA状态集合同时进行标记,直到某个NFA状态集合包含终止符号,则最后一次读取字母表并记录和标记NFA状态集合。

    例如(字母表为\{ a,b \},状态集合E包含终止符):

    NFA状态 DFA状态 a b
    \{ \dots \} A B C
    \{ \dots \} B B D
    \{ \dots \} C B C
    \{ \dots \} D B E
    \{ \dots \} E B C
    3.4.4 DFA的化简
    • 两个状态等价的条件:
    1. 一致性——两者必须同时为可接受/不可接受状态;
    2. 蔓延性——对于所有输入符号,两者必须转换到等价的状态里。
    • 分割法
    1. 首先把M的状态分成两个子集,一个由终态组成,另一个由非终态组成,初始化划分为P_0=(\{s_1,s_2,s_3,s_4\} ,\{s_5,s_6,s_7\}),两个子集任何状态之间都不等价;

    2. 读入输入符号a,观察第一个子集,发现两组状态分别转换到终态和非终态,即这两组状态之间不等价,因此将其划分为P_1=(\{s_1,s_2\} ,\{s_3,s_4\} ,\{s_5,s_6,s_7\})

    3. 接着试图在P_1中寻找一个子集和一个输入符号使得其状态可区别,然后得到P_2=(\{s_1,s_2\} ,\{s_3\} ,\{s_4\} ,\{s_5,s_6,s_7\})

    4. 继续上述过程,直到P_3=(\{s_1,s_2\}, \{s_3\}, \{s_4\}, \{s_5\}, \{s_6,s_7\})不能再划分,令s_1代表\{ s_1, s_2 \}消去s_2s_6代表\{ s_6, s_7 \}消去s_7,得到化简之后的DFA。

    3.5 正规式与有穷自动机的等价性
    • 为NFAM构造正规式r
    1. M的状态转换图上加两个结点x,y,从x结点用\epsilon弧连接到M的所有初态结点,从M的所有终态结点用\epsilon弧连接到y结点,形成一个与M等价的M',后者只有一个初态x和一个终态y

    2. 逐步消去M'中所有结点,最后只剩下x,y结点,消去过程逐步用正规式来标记弧,规则如下:
      (1)r_1\text{ and }r_2\to r_1r_2
      (2)r_1\text{ or }r_2\to r_1|r_2
      (3)r_1\text{ and }r_2\text{ circle }r_2\text{ and }r_3\to r_1r_2^*r_3

    • 为正规式r构造NFAM
    1. \emptyset,\epsilon,a构造NFA:
      (1)\text{for }\emptyset,\Rightarrow(x),((y))
      (2)\text{for }\epsilon,\Rightarrow(x)\overset{\epsilon}{\rightarrow}((y))
      (3)\text{for }a,\Rightarrow(x)\overset{a}{\rightarrow}((y))

    2. s,t\Sigma上的正规式,相应的NFA分别为N(s),N(t)
      (1)\text{for }r=s|t,\Rightarrow(x)\overset{\epsilon}{\rightrightarrows}\{N(s)\text{ or }N(t)\}\overset{\epsilon}{\rightrightarrows}((y))
      (2)\text{for }r=st,
      (3)\text{for }r=s^*,

    3.6 正规文法与有穷自动机的等价性
    • ……

    第4章 自顶向下语法分析方法

    4.1 确定的自顶向下分析思想
    • 直观的文法特点:
      (1)每个产生式的右部都由终结符号开始;
      (2)若两个产生式有相同左部,则其右部由不同终结符开始。

    • 不直观的文法特点:
      (1)产生式右部不全是由终结符开始;
      (2)如果两个产生式有相同左部,则其右部由不同终结符或非终结符开始;
      (3)文法中无空产生式。

    =======================================================

    • FIRST集合

    FIRST(\alpha)= \{ a|\alpha\overset{*}{\Rightarrow}a\beta,a\in V_T,\alpha,\beta\in V^*{\}}

    \alpha\overset{*}{\Rightarrow}\epsilon,则规定\epsilon\in FIRST(\alpha)

    1. X是终结符号,则FIRST(X)=\{ X\}

    2. X是非终结符号,且X\to Y_1Y_2\dots Y_k,则令Y_i,i=1,2,\dots,k,从i=1开始逐个扫描Y_i:如果Y_i\overset{*}{\rightarrow}\epsilon不成立,则将FIRST(Y_i)的所有符号都加入FIRST(X),然后停止扫描;如果Y_1\dots Y_k\overset{*}{\Rightarrow}\epsilon,则将\epsilon加入FIRST(X)

    3. X\to\epsilon是产生式,则将\epsilon加入FIRST(X)

    =======================================================

    • FOLLOW集合

    FOLLOW(A)=
    \{ a|S\overset{*}{\Rightarrow}\mu A\beta\land a\in V_T, a\in FIRST(\beta),\mu\in V_T^*,\beta\in V^+ \}

    S\overset{*}{\Rightarrow}\mu A\beta\land\beta\overset{*}{\epsilon},则\#\in FOLLOW(A)

    1. \text{\$$$}加入FOLLOW(S),其中S是开始符号,而\text{\$$$}是输入右端的结束标记。

    2. 若存在A\to\alpha B\beta,则FIRST(\beta)中除\epsilon外的所有符号都在FOLLOW(B)中。

    3. 若存在A\to\alpha B,或存在A\to\alpha B\betaFIRST(\beta)包含\epsilon,则FOLLOW(A)的所有符号都在FOLLOW(B)中。

    =======================================================

    • SELECT集合:

    给定A\to\alpha,A\in V_N,\alpha\in V^*

    1. \text{if }\alpha\overset{*}{\nRightarrow}\epsilon,\text{then }
      SELECT(A\to\alpha)=FIRST(\alpha)

    2. \text{if }\alpha\overset{*}{\Rightarrow}\epsilon,\text{then }
      SELECT(A\to\alpha)=(FIRST(\alpha)-\{\epsilon\})\cup FOLLOW(A)

    =======================================================

    4.2 LL(1)文法的判别
    • 对每个非终结符A的两个不同产生式A\to\alpha,A\to\beta,满足:
      SELECT(A\to\alpha)\cap SELECT(A\to\beta)=\emptyset

    • 文法GLL(1)的,当且仅当G的任意两个不同产生式A\to\alpha|\beta满足条件:

    1. FIRST(\alpha)\cap FIRST(\beta)=\emptyset
    2. \epsilonFIRST(\beta)中,则FIRST(\alpha)\cap FIRST(A)=\emptyset
    3. \epsilonFIRST(\alpha)中,则FIRST(\beta)\cap FIRST(A)=\emptyset
    4.3 某些非LL(1)文法到LL(1)文法的等价变换
    4.3.1 提取左公因子
    1. 一般形式:A\to\alpha\beta_1|\alpha\beta_2|\dots|\alpha\beta_n
      提取左公因子:A\to\alpha A'
      引进非终结符:A'\to\beta_1|\beta_2|\dots|\beta_n

    2. 如果产生式右部以非终结符开始,可能存在隐式的左公因子,这种情况下,
      用左部与之相同而右部以终结符开始的产生式完全替换其右部开始的非终结符。

    4.3.2 消除左递归
    1. 消除直接左递归
      A\to A\alpha_1|A\alpha_2|\dots|A\alpha_m|\beta_1|\beta_2|\dots|\beta_n
      消除直接左递归后改写成:
      A\to\beta_1A'|\beta_2A'|\dots|\beta_nA'
      A'\to\alpha_1A'|\alpha_2A'|\dots|\alpha_mA'|\epsilon

    2. 消除间接左递归

    • 以下文法为例:
      S\to Aa|b
      A\to Ac|Sd|\epsilon

    对非终结符进行排序,先消除S的立即左递归,
    然后将S代入A,进行替换,消掉中间符号S
    最后对A消除直接左递归,得到最终消除结果。
    Sorting: S,A
    \because A\to Ac|Aad|bd|\epsilon
    \therefore S\to Aa|b
    \ \ \ A\to bdA'|A'
    \ \ \ A'\to cA'|adA'|\epsilon

    4.4 不确定的自顶向下分析思想

    第6章 LR分析

    6.1 LR分析概述
    • 一个LR分析器由3个部分组成:
      1)总控/驱动程序,所有LR分析器的总控程序都相同;
      2)分析表/分析函数,不同文法/同一文法采用不同LR分析器,分析表均不同,而分析表分为动作(ACTION)表和状态转换(GOTO)表,都用二维数组表示;
      3)分析栈,包括文法符号栈和相应的状态栈,均是FILO。

    • 分析器的动作由栈顶状态和当前输入符号来决定,其中,LR(0)分析器不需要向前查看输入符号。LR分析器的工作过程如下:
      1)SP为栈指针,S[i]为状态栈,X[i]为文法符号栈。状态转换表由关系GOTO[S_i,X]=S_j确定,意思是当栈顶状态为S[i]遇到当前文法符号为X时,应转向状态S_jX为终结符/非终结符。
      2)ACTION[S_i,a]规定栈顶状态为S_i遇到输入符号a应执行的动作,有4种可能:
      ①移进
      ②归约
      ③接受acc
      ④报错


    第7章 语法制导的语义计算

    7.1 基于属性文法的语义计算
    7.1.1 属性文法
    • 基本概念和术语
      在文法G[S]基础上,为文法符号关联有特定意义的属性,并为产生式关联相应的语义动作条件谓词,称之为属性文法,并称该文法是这一属性文法的基础文法。例如:

    S\to ABC \{ (A.num=B.num) and (B.num=C.num) \}
    A\to A_1a\ \{ A.num:=A_1.num+1 \}
    A\to a\ \quad\ \{ A.num:=1 \}
    B\to B_1b\ \{ B.num:=B_1.num+1 \}
    B\to b\ \quad\ \{ B.num:=1 \}
    C\to C_1c\ \{ C.num:=C_1.num+1 \}
    C\to c\ \quad\ \{ C.num:=1 \}

    上述属性文法可以接受的语言是L=\{a^nb^nc^n|n\geqslant1\}。稍作修改:

    S\to ABC \{ if \ (A.num=B.num) \ and \ (B.num=C.num)
    \qquad\qquad\quad \ \ then \ \ \ print("accepted")
    \qquad\qquad\quad \ \ else \quad print("refused"){\}}
    A\to A_1a\ \{ A.num:=A_1.num+1 \}
    A\to a\ \quad\ \{ A.num:=1 \}
    B\to B_1b\ \{ B.num:=B_1.num+1 \}
    B\to b\ \quad\ \{ B.num:=1 \}
    C\to C_1c\ \{ C.num:=C_1.num+1 \}
    C\to c\ \quad\ \{ C.num:=1 \}

    若输入串属于L,则语义计算结果会执行then语句,反之执行else语句。

    • 综合属性和继承属性
      对关联于产生式A\to\alpha的语义动作b:=f(c_1,c_2,\dots,c_k),若bA的某个属性,则称其是A的一个综合属性。从分析树的角度,计算综合属性是对父结点的属性赋值,是自底向上传递信息。
      对关联于产生式A\to\alpha的语义动作b:=f(c_1,c_2,\dots,c_k),若b是产生式右部某个文法符号X的某个属性,则称其是文法符号X的一个继承属性。从分析树的角度,计算继承属性是对子结点的属性赋值,是自顶向下传递信息。

    S\to ABC \{ B.in\_num:=A.num;C.in\_num:=A.num
    \qquad\qquad\quad \ \ if \ (B.num=0) \ and \ (C.num=0)
    \qquad\qquad\quad \ \ then \ \ \ print("accepted")
    \qquad\qquad\quad \ \ else \quad print("refused"){\}}
    A\to A_1a\ \{ A.num:=A_1.num+1 \}
    A\to a\ \quad\ \{ A.num:=1 \}
    B\to B_1b\ \{ B_1.in\_num:=B.in\_num;
    \qquad\qquad\quad\ B.num:=B_1.num-1 {\}}
    B\to b\ \quad\ \{ B.num:=B.in\_num-1 \}
    C\to C_1c\ \{ C_1.in\_num:=C.in\_num;
    \qquad\qquad\quad\ C.num:=C_1.num-1 {\}}
    C\to c\ \quad\ \{ C.num:=C.in\_num-1 \}

    其中,A.num,B.num,C.num是综合属性,B.in\_num,C.in\_num是继承属性。对于前者进行自底向上计算,对于后者进行自顶向下计算。

    7.1.2 遍历分析树进行语义计算
    7.1.3 S-属性文法和L-属性文法

    只包含综合属性的属性文法称为S-属性文法。
    S-属性文法是L-属性文法的一个特例。

    相关文章

      网友评论

          本文标题:编译原理(部分)

          本文链接:https://www.haomeiwen.com/subject/qjwhcctx.html