编译原理

编译原理

语法是指这样的一组规则,用它可以形成和产生一个合适的程序。

词法规则是指单词符号的形成规则。

语法规则是语法单位的形成规则,规定了如何从单词符号形成更大的结构(即语法单位或语法范畴)。

一般程序语言的语法单位有:表达式、语句、分程序、函数、过程和程序等。

程序语言的基本功能是描述数据和对数据的运算。所谓程序,从本质上来说是描述一定数据的处理过程。

 

强制式语言也称过程式语言。其特点是命令驱动,面向语句。一个强制式语言程序由一系列的语句组成,每个语句的执行引起若干存储单元中的值的改变。

应用式语言更注重程序所表示的功能,而不是一个语句接一个语句地执行。

文法是描述语言的语法结构的形式规则(即语法规则)。

 

所谓上下文无关文法是这样一种文法,它所定义的语法范畴(或语法单位)是完全独立于这种范畴可能出现的环境的。

一个上下文无关文法G包括四个组成部分:一组终结符号,一组非终结符,一个开始符号,以及一组产生式。形式上定义一个上下文无关文法G是一个四元式(V,V,S,P)

其中

是一个非空有限集,它的每一个元素称为终结符号;

是一个非空有限集,它的每一个元素称为非终结符号,V∩V=f;

S是一个非终结符号,称为开始符号;

P是一个产生式(有限)集合,每个产生式形式是A→a ,其中,A∈VN,  a∈( V∪V开始符号S至少必须在某一产生式的左部出现一次。

 

假定G是一个文法,S是它的开始符号。如果SÞa(表示从S出发,经0步或若干步可推出a),则称a是一个句型。仅含终结符号的句型是一个句子

最左推导:任何一步aÞb都是对a中的最左非终结符进行替换的。同样,可定义最右推导

 
产生式形式


文法名称


定义的语言


描述能力


包含关系


0型文法


ab


短语文法


递归可枚举语言


最强

 

1型文法


ab

|a|<=|b|


上下文有关文法


上下文有关语言


次之


又是0型文法


2型文法


Ab


上下文无关文法


上下文无关语言


次之


又是0,1文法


3型文法


ABb

AbB


正规文法


正规语言


最弱


又是0,1,2型文法

 


表示、术语


令X1=“abc”, X2=“def”


|X1|


|abc|=   3


ε


|ε|= 0


X1.X2


“abc”“def”=“abcdef”  


Xn  


“abc”3   =“abcabcabc”


X1的前缀


“abc”的前缀可以是:ε,a,ab, abc


X1的后缀


“abc”的后缀可以是:ε,c,bc, abc


X1的子串


“abc”的子串可以是: ε,a,b, c, ab, bc ,abc


X1的真前缀


“abc”的真前缀可以是:a,ab


X1的真后缀


c,bc


X1的真子串


a,b, c, ab, bc

 

字母表:由若干元素组成的有限非空集合,用S表示,它的每个元素称为一个符号。

符号串: 由S中的符号所构成的有穷序列。

符号串的前缀和后缀及子串:设x是一个符号串,将x的尾(前)部删掉几个字符后形成的符号串,称为x的前(后)缀;从一个符号串中删去他的一个前缀和后缀后所剩下部分称为x的子串。

 

空串(字):不包含符号的序列称为空串(字) ,记为e。

用S*表示S上的所有符号串的全体,空字也包括在其中。如:若S={a,b}则S*={ e,a,b,aa,ab,bb,aaa,…}。f表示不含人何元素的空集{}。这里要注意e、{}和{e}的区别。

 

符号串的连接运算:设x和y是两个符号串,如果将y直接拼接在x之后,称这种操作为符号串的连接,记作: x.y

符号串的方幂:一个符号串与其自身的n-1的任意连接称为符号串的n次幂,记作:xn

   xn = xn-1.x=x.xn-1

特别地:x0= e

 

字符串集合的和(等价于集合的并运算):设A、B是两个符号串的集合,则将集合A、B的和记为A+B或A∪B,定义为:A∪B={w|wÎA或wÎB}

符号串集合的连接:S*的子集U和V中的(连接)积定义为:

         UV={ab∣aÎU & bÎV }

即集合UV中的符号串是由U和V的符号串连接而成的。注意,一般UV¹VU,但(UV)W=U(VW).

 

符号串集合V自身的n次(连接)积记为:

  Vn = V V…V =Vn-1V=VVn-1 (n个V)

规定 V0 = {e}.

V的闭包:令: V*  = V0 ∪ V1 ∪ V2 ∪ …  称 V*是V的闭包。

V的正则包(正闭包,正则闭包):记V+ = VV*, 称 V+是V的正则包,即V+ =V1 ∪ V2 ∪ V3 ∪ …。

 

产生式(也称为产生规则或简称规则)是定义语法范畴的一种书写规则。

 一个产生式的形式是  A→ α.

 

0型文法:设G=(VN,VT,P,S),如果它的每个产生式α→β是这样一种结构:α∈(VN∪VT)*且至少含有一个非终结符,而β∈(VN∪VT)*,则G是一个0型文法。0型文法也称短语文法。一个非常重要的理论结果是:0型文法的能力相当于图灵机(Turing)。或者说,任何0型文语言都是递归可枚举的,反之,递归可枚举集必定是一个0型语言。0型文法是这几类文法中,限制最少的一个,所以我们在试题中见到的,至少是0型文法。

 

1型文法:也叫上下文有关文法,此文法对应于线性有界自动机。它是在0型文法的基础上每一个α→β,都有|β|>=|α|。这里的|β|表示的是β的长度。

注意:虽然要求|β|>=|α|,但有一特例:α→ε也满足1型文法。

如有A->Ba则|β|=2,|α|=1符合1型文法要求。反之,如aA->a,则不符合1型文法。

 

2型文法:也叫上下文无关文法,它对应于下推自动机。2型文法是在1型文法的基础上,再满足:每一个α→β都有α是非终结符。如A->Ba,符合2型文法要求。

如Ab->Bab虽然符合1型文法要求,但不符合2型文法要求,因为其α=Ab,而Ab不是一个非终结符。

 

3型文法:也叫正规文法,它对应于有限状态自动机。它是在2型文法的基础上满足:A→α|αB(右线性)或A→α|Bα(左线性)。

如有:A->a,A->aB,B->a,B->cB,则符合3型文法的要求。但如果推导为:A->ab,A->aB,B->a,B->cB或推导为:A->a,A->Ba,B->a,B->cB则不符合3型方法的要求了。具体的说,例子A->ab,A->aB,B->a,B->cB中的A->ab不符合3型文法的定义,如果把后面的ab,改成“一个非终结符+一个终结符”的形式(即为aB)就对了。例子A->a,A->Ba,B->a,B->cB中如果把B->cB改为B->Bc的形式就对了,因为A→α|αB(右线性)和A→α|Bα(左线性)两套规则不能同时出现在一个语法中,只能完全满足其中的一个,才能算3型文法。

注意:上面例子中的大写字母表示的是非终结符,而小写字母表示的是终结符。

 

状态转换图 :由有限个结点所组成的有向图。

每个结点代表在识别分析过程中扫描器所处的状态,其中 含有一个初始状态和若干个终态。在图中,状态用圆圈表示,终态用双层圆圈表示。

 

抽象地看,状态转换图由五个部分组成:

(1) 有限个状态之集,记作K;

(2) 有限个输入符号组成的字母表,记作S;

(3) 从K´S到K的转换函数 f: K´SK. f(p,a)=q表示若当前状态为p,且输入符号为a,则进入下一个状态为q;

(4) S0ÎK,初始(开始)状态;

(5) 若干个终态之集: Z( ÍK )

        由上述五个要素组成的五元式  M=(K, S, f,S0,Z )称为一个确定的有限自动机(DFA: Deterministic Finite Automata).由此可见,一DFA实际上是状态转换图的形式描述(数学定义),状态转换图是DFA的几何(图形)表示.

 

有穷自动机,或有穷状态的机器,是描述(或“机器”)特定类型算法的数学方法。特别地,有穷自动机可用作描述在输入串中识别模式的过程,因此也能用作构造扫描程序。当然有穷自动机与正则表达式之间有着很密切的关系,在下一节中大家将会看到如何从正则表达式中构造有穷自动机。但在学习有穷自动机之前,先看一个说明的示例。

通过下面的正则表达式可在程序设计语言中给出标识符模式的一般定义(假设已定义了letter 和digit):

identifier = letter ( letter | digit ) *

它代表以一个字母开头且其后为任意字母和/ 或数字序列的串。

                       

有穷自动机

  通过标明数字1 和2 的圆圈表示的是状态(state),它们表示其中记录已被发现的模式的数量在识别过程中的位置。带有箭头的线代表由记录一个状态向另一个状态的转换(transition),该转换依赖于所标字符的匹配。

有穷自动机又分为确定型的有穷自动机(DFA)与非确定型的有穷自动机(NFA)两种。由于NFA与DFA是等价的,今后统称FA.

 

正规表达式就是用特定的运算符及运算对象按某种规则构造的表达式,用于描述给定3型语言的所有句子。

 

确定有穷自动机的化简方法有很多,我们介绍一个方法,叫做"分割法"把一个DFA(不含多余状态)的状态分成一些不相交的子集,使得任何不同的两子集的状态都是可区别的,而同一子集中的任何两个状态都是等价的。

首先将M的状态分成两个子集:一个由终态(可接受态)组成,一个由非终态组成,

初始划分P0为:P0=({1234},{567})
  第一个子集{1,2,3,4},在读入输入符号a后,状态3和4分别转换为第一个子集中所含的状态1和4,而1 和2分别转换为第二个子集中所含的状态6和7,这就意味着{1,2}中的状态和{3,4}中的任何状态在读入a后到达了不等价的状态,因此{1,2}中的任何状态与{3,4}中的任何状态都是可区别的,因此得到了新的划分P1如下:

       P1=({12} {34} {567})
  P1中的子集{3,4}对应输入符号a将再分割,而得到划分P2=({1,2},{3},{4},{5,6,7})。
P2中的{5,6,7}可由输入符号a或b而分割,得到划分P3=({1,2},{3},{4},{5},{6,7})。令1代表{1,2}消去2,令6代表{6,7},消去7,我们便得到了化简了的DFA M′。

 

定义 设S是一字母表,则S上的正规表达式(正则表达式,正规式)及其表示的正规集可递归定义如下:

(1) f是一正规式,  相应的正规集为f;

(2) e是一正规式,  相应的正规集为{e};

(3) "aÎS,a 是一正规式,  相应的正规集为{a};

(4) 设r,s是正规式, 且它们所表示的正规集为Lr,Ls,则

1. (r) •(s)是正规式, 相应的正规集为Lr•Ls;

2. (r)|(s)是正规式, 相应的正规集为LrÈ Ls;

3. (r)*是正规式, 相应的正规集为Lr*

有限地使用上面的规则(4),所得的表达式均是正规式.

 

正规式的基本等价关系(“公理”)

A1.  r|s=s|r             A2. r|r=r        

A3.  r|f=r                A4. (r|s)|t=r|(s|t)

A5. (rs)t=r(st)       A6. r(s|t)=rs|rt

A7. (s|t)r=sr|st        A8. rf=fr=f

A9. re=er=r                A10. r*=(e|r)*=e|rr*

 

对于给定的三型文法G,如何构造正规式r,使Lr=L(G)

方法: 将G视为定义所含非终结符为变量的联立方程组,通过解方程组求得相应的正规式.

例  SaS | bA | b  AaS  设S,A所产生的正规集为LS, LA 则有

            LS={a} LS È{b} LA È{b}          LA ={a} LS

         由定义可知,L(G)= LS,视S, A为LS, LA 的正规式,相应的关系为

             S=aS | bA |b   A=aS  记 ‘|’ 为’+’, 有

               S=aS + bA + b     (1)  

              A=aS                     (2)

将(2)代入(1),得  S=aS + baS + b = (a+ba) S +b   (3)

得到形如         X= aX + b 的方程.关于这类方程有如下论断:

论断3.1 方程X=aX+b 有解 X=a*b    (不唯一)

证: 将x= a*b 代入右边: 右= aa*b+ b=(aa*+e) b= a*b=左

由论断3.1可知,S=(a+ba)*b=(a|ba)*b .

另外,对(3)连续使用两次论断3.1,有S=a*(baS+b)=a*baS+a*b=(a*ba)*a*b 我们可得一副产品: (a|ba)*b = (a*ba)*a*b

例  SaA         AbA | aB | b       BaA

相应的方程组为

           S=aA                  (1)

           A=bA+aB+b             (2)

           B=aA                  (3)

           (3) 代入(2):   A=(b+aa)A+b 得         A=(b+aa)*b

         代入(1):   S=a(b+aa)*b=a(b|aa)*b

 

Thmopson

(1) r= r1|r2 ,引入新开始状态S0,终态Sf,将M1,M2并联:

 

(2) r=r1·r2 , 将M1,M2串联

 

(3) r=r*,引入新开始状态S0,终态Sf,令原M1构成循环

 

在实际的构造中,我们可以省略一些e矢线。

 

第四章 语法分析和语法分析程序

自顶向下:对已给的输入串w,试图自上而下地建立一棵语法树;或者说,从S出发,为w构造一个最左推导。若成功,则wÎL(G)否则拒绝。

    一般说来,在为w寻求最左推导的每一步,都涉及使用何产生式进行替换的问题。最简单的方法是,逐一试探。但是,逐一试探也不能完全解决问题。

消除文法的左递归:设文法是已简化的。若文法含直接左递归式:

      AAa | b (aÎV+) ,      则类似正规式求解方法,我们有

           A b {a}  (b a*).

    引入新的非终结符A’,令其产生a*,则有:   A bA’        A’ aA’|e      

例:  ET                可改写为:

     E EAT                  ETE’

     TF                    E’ATE’|e

     T TMF                 TFT’

     F(E)                   T’MFT’|e 

     F i                    F(E) | i 

     A+|-                  A+|-

     M* | /                M *|/

例: SaA | b      AcAS | e 

     FIRST(cAS)={c}

     FOLLOW(A) =FIRST(S)È{#}={a,b,#} 两个集合不相交, 故可进行无回溯的自顶向下分析。

设输入串w=aca#,其推导过程如下:

S#ÞaA#  当前输入符a属于FIRST(aA),用SaA推导

ÞacAS#  当前输入符c属于FIRST(cAS),用AcAS推导

ÞacS#  当前输入符a属于FOLLOW(A),用Ae推导.

ÞacaA# 当前输入符a属于FIRST(aA),用SaA推导

Þaca#            当前输入符#属于FOLLOW(A),用Ae推导,成功。

 

提取左因子  当文法中含有形如  Aab1|ab2|…|abm  的产生式时,可将其改写为:    AaA’      A’b1|b2|…|bm   

例如, EE+T | T     T(E) | a(E) | a        经改造后可得文法                   ETE’      E’+TE’| e      TaT’ | (E)      T’ (E) | e        这是一个LL(1)文法.

并非所有的文法都能改造为LL(1)文法.

 

能由LL(1)文法产生的语言称为LL(1)语言.它们已被证明具有许多重要特性, 主要有:

(1) 任何LL(1)文法都是无二义性的;

(2) 左递归文法是非LL(1)的;

(3) 存在一种算法,它能判定任意文法是否为LL(1)的;

(4) 存在一种算法,它能判定任意两个LL(1)文法是否等价;

(5) CFL是否是LL(1)语言是不可判定的;

(6) 非LL(1)语言是存在的.

若在分析过程中,每步向前扫描k个符号来确定选用的产生式,此分析方法称为是LL(k)分析.

例:表达式文法为:
E→E+T|T
T→T*F|F
F→i|(E)

(1)     判断文法是否为LL(1)文法

  消除左递归,使文法变为:
E→TE′
E′→+TE′|ε
T→FT′
T′→*FT′|ε
F→i|(E)

 

(2) 构造预测分析表
对每个终结符或"#"号用a表示。
若a∈SELECT(A→α),则把A→α放入M[A,a]中。
把所有无定义的M[A,a]标上出错标记。
为了使表简化,其产生式的左部可以不写入表中,表中空白处为出错。

 

 

定义设G=(VT,VN,S,P)是上下文无关文法

   FIRST(α)={a|α   aβ,a∈VT,α,β∈V*},若α   ε,则规定ε∈FIRST(α)

 

 

 

 

预测分析法实例

ETE’ 

E’ATE’|e    

TFT’ 

T’MFT’|e 

F(E) | i 

A+|-

M *|/

 

 

 

 

 

 

 

 

 

 

 

 

对i+i*i进行预测分析的过程

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

LL(1)算法流程图

 

简单优先关系的定义:设G是已化简的文法,s,tÎV,若G中存在规范句型 a=…st…, 则s,t与a的句柄之间的关系必有下述情况之一:

 

对于上述情况,我们规定,       情况1: s>t; 情况2: s=t;         情况3: s<t

另外,还有一种情况,就是s和t均不在句柄中,那么一定存在某句型使得它们进入上述三种情况之一.

若s和t在任何句型中都不可能相邻出现,则我们规定二者无关系.

注意,这种优先关系是不对称的!

 

定义:若一文法G的任何两个符号之间至多存在一种优先关系,且任意两个不同的产生式无相同的右部,则称G为简单优先文法 .

时间: 2024-10-14 20:58:35

编译原理的相关文章

编译原理scanner的java代码

问题描述 编译原理scanner的java代码 package lexer; public class Token { public final int tag;public Token(int t) { tag = t;}public String toString() { return """" + (char) tag;} } package lexer; public class Tag { public final static int AND = 256

求各位大神帮忙做一下编译原理程序设计

问题描述 求各位大神帮忙做一下编译原理程序设计 1.设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码.将词法分析器设计成供语 法分析器调用的子程序.功能包括:具备预处理功能.将不翻译的注释等符号先滤掉,只保留要翻译的符号串,即要求设计一个供词法分析调用的预处理子程序:能够拼出语言中的各个单词:http://ask.csdn.net/#将拼出的标识符填入符号表:返回(种别码, 属性值).2.目标代码生成器c. 能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇

编译原理之文法

关于编译原理这块之前根本没有涉及过,这次要用到这里的知识就需要来接触一下这里的内容.编译原理顾名思义就是处理高级语言,使之称为计算机能够识别的语言(低级语言)的原理.而文法呢?就是用来描述程序设计语言的方法.类似佛法,用来描述佛家的诵经禅道的规则的.不用去纠结这个名字,知道这个含义,足以. 文法 概念 终结符和非终结符 如图:在p这个推导式的集合中,存在六个推导式.其中S.A.B为非终结符.a.b.c.d.q.p为终结符.终结符是原子不可分的. 分类 文法的分类也就这几种了,先看各自的定义,在定

ASP.NET MVC的Razor引擎:View编译原理

通过.cshtml或者.vbhtml文件定义的View能够被执行,必须先被编译成存在于某个程序集的类型,ASP.NET MVC采用动态编译的方式对View文件实施编译.当我们在对ASP.NET MVC进行部署的时候,需要对.cshtml或者.vbhtml文件进行打包.针对某个View的第一次访问会触发针对它的编译,一个View对应着一个类型.我们可以对.cshtml或者.vbhtml进行修改,View文件修改后的第一次访问将会导致View的再一次编译.和ASP.NET 传统的编译方式一样,针对V

大前端开发者需要了解的基础编译原理和语言知识

在我刚刚进入大学,从零开始学习 C 语言的时候,我就不断的从学长的口中听到一个又一个语言,比如 C++.Java.Python.JavaScript 这些大众的,也有 Lisp.Perl.Ruby 这些相对小众的.一般来说,当程序员讨论一门语言的时候,默认的上下文经常是:"用 xxx 语言来完成 xxx 任务".所以一直困扰着的我的一个问题就是,为什么完成某个任务,一定要选择特定的语言,比如安卓开发是 Java,前端要用 JavaScript,iOS 开发使用 Objective-C

深入剖析ASP.NET的编译原理之二:预编译(Precompilation)

在本篇文章的第一部分:[原创]深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation),详细讨论了ASP.NET如何进行动态编译的,现在我们来谈谈另外一种重要的编译方式:预编译(Precompilation). 目录 一.为什么要进行预编译 二.In Place Pre-compilation V.S. Pre-compilation for Deployment 三.Non-updatable Pre-compilation V.S. Updatable P

c语言如何进阶?需不需要学操作系统和编译原理

问题描述 c语言如何进阶?需不需要学操作系统和编译原理 学了一段时间的c语言,基本知识都掌握了,想深入学习一下c语言,不知道需不需要先学习一下操作系统方面的知识或者编译原理,请高手指点一下 解决方案 C语言是一种系统编程语言,有人称它叫做"高级语言中的低级语言",由于它接近硬件,语法相对简单,并且自身抽象程度很差,不适合编写应用程序,而很适合编写系统软件,比如微控制器.嵌入式系统.驱动程序等等. 这恰好是操作系统和编译原理的学习中最适合的语言.C语言接近硬件,接近操作系统,天然地,和操

深入剖析ASP.NET的编译原理之一:动态编译(Dynamical Compilation)

Microsoft 的Visual Studio为我们在应用开发中提供的强大功能,我们是有目共睹.借助该工具,是我们的开发 显得更加高效而轻松.从Microsoft把这个IDE的名字从VS.NET 该为VS(比如原来的Visual Studio.NET 2003,现在的版本叫VS2005),可以MS对该IDE的期望和野心:MS要把它改造成一个万能的IDE.不过任何都有其两面性,对于我们广大的开发者来说,VS是我们的各种行为简单化,傻瓜化:但是在另一方面,他也会蒙蔽我们的眼睛,使我们对它背后做的事

编译原理求解........................

问题描述 编译原理求解........................ 输入:if (a123>0.2){b2=b2+50;} 输出: <( 括号> < >= relop> <) 括号><{ 花括号> <= 赋值号> <+ op> <; 标点><} 花括号>