当前位置:文档之家› 一个简单的C语言编译器

一个简单的C语言编译器

一个简单的C语言编译器
一个简单的C语言编译器

一个简单的C语言编译器

一.小组成员

朱嘉俊()计算机996

王筱()计算机996

朱杭()计算机996

朱林()计算机994

二.运行方式

在DOS环境下运行:

Cminus.exe -h

三.概述

经过一段时间的学习,我们在初步掌握了编译器的基本原理以后,设计了一个具有基本编译功能的编译器。该编译器接受类C语言语法的源代码输入,输出结果是PC机的汇编源代码。在捆绑了宏汇编编译器Masm后,即可直接生成MSDOS下的二进制可执行文件。为方便起见,以下简称为C—语言编译器。

本编译器实现了基本高级语言所必须的语法要素,包括简单变量声明、函数的实现、整数和字符串运算、条件判断语句和循环语句及跳转语句、基本代数运算、赋值等,还支持汇编语言嵌入。本编译器是利用编译器生成器Parse Generator和VC6.0在Windows平台上实现的,并开发了一个基于Windows平台的32位编译集成开发环境CompilerMan,提供了关键字彩色提示、出错同屏提示、出错代码跳转等较为完善方便的功能。

由于编译程序本身涉及到词法分析、语法分析、代码生成、错误恢复和优化等诸多模块,要在实验中做到面面俱到不太可能,所以本编译器不可避免的会存在各种问题,但作为一个具有基本功能的、可扩充的系统,完全达到了巩固编译原理的理论知识,并将其运用于实践的目的。

四.背景

编译程序,就是一种具有编撰和翻译功能的程序。人们要用计算机来解决问题,首先面临的一个问题,就是要告诉计算机解决什么问题,或者告诉计算机如何解决这个问题。这就涉及到用什么样的语言来描述的问题,人所习惯的自然语言和计算机认识的机器语言有很大的差别,用机器语言来描述人想解决的问题十分不便,因而,计算机科学家设计一些人们比较习惯的语言来描述要解决的问题,称之为高级语言。用语言来描述的问题,统称为程序。然而,用高级语言写的程序,不能被计算机所直接认识和理解,必须经过等价的转换,变成机器能理解并执行的机器语言的程序。进行这种等价转换工作的工具,就是编译程序。

1.编译程序的结构

编译程序是很复杂的,但它可被分为相对独立的几个部分,每个部分承担专门的工作,各部分间互相共享传送数据。把编译程序分解成较小的部分,不仅便于开发、调试,而且便于编译程序的移植。一个典型的编译程序通常具有如图1的结构。

图1 编译器基本结构

1.1 词法分析

词法分析负责对源程序的字符串进行扫描和分解,根据构词法将字符流(Character Stream)转化成单词流(Token Stream)。

例如对于C--语句:

x = y + z – m * 10;

词法分析的结果是:

ID ASSIGN ID ADD ID SUB ID MUL NUM SEMI

构词的规则就是词法,例如标识符(ID)可定义为以字母开头,后面跟零个或任意个字母或数字的序列。词法分析程序就根据词法构造有限自动机来识别每一个单词,将产生的单词交给语法分析程序。

1.2 语法分析

语法分析模块的任务是根据文法规则把单词序列分解成各类语法单位,识别出一个一个句子,例如对前面的语句进行语法分析可得到如图2的分析树。

如果输入单词不能构成语法树,则说明有语法错误。常见的语法分析方法分为自顶向下分析和自底向上分析两大类。在C--编译器中采用了一种自底向上的方法,即LR方法。

1.3 语义分析

这一阶段部分是根据前一阶段产生的语法树,按语言的语义进行翻译,产生四元式或三元式等中间语言。中间语言可以很方便地转换成目标代码。前面的语法树可能产生的四元式序列为:

(*,_t0,10,m)

(-,_t1,z,_t0)

(+,_t0,y,_t1)

(=,x,_t0)

由于中间语言对后面的代码优化和目标代码生成有密切关系,又和目标机器的体系结构有关,所以中间语言的选择对于编译器的效率和质量有很大的影响。

1.4 代码优化

代码优化是把中间代码进行变换,以产生更加高效的目标代码。

1.5 目标代码生成

目标代码生成是编译最后一个阶段,它把中间代码转换成汇编指令或可重定位的目标代码。例如对于前面生成的中间代码,可以产生IBM PC汇编指令为:mov ax, m

mul ax, 10

mov bx, z

sub bx,ax

add bx,y

mov x, bx

汇编代码经过Masm汇编器(Assembler)和连接器(Linker)处理,就产生了可在IBM PC机器上运行的二进制代码。

2.形式语言简介

2.1 文法和语言

文法是产生语言的规则,它可定义为:

对于一个四元式G=(V N,V T,S,P),其中

(1) V N是非终结符号的有限集合

(2) V T是终结符号的有限集合,且V T∩V N

(3) 开始符号S,S∈V N

(4) 一组产生式P,P中的每一个产生式都具有如下形式:

u→v,u∈(V N∪V T)+且至少要有一个非终结符号,v∈(V N∪V T)*

则G表示一个文法。

乔姆斯基(Noam Chmosky)把文法分成四类:0型文法又称无约束文法,产生式的形式为a→b,a、b是任意字符串。1型文法又称上下有关文法,产生式形式为a→b,且|a|≥|b|。2型文法又称上下文无关文法(Context-Free Grammar),产生式形式为A→a,a∈(V N∪V T)*,A∈V N。3型文法又称正规文法,它的产生式左部是一个非终结符号,右部最多只有一个非终结符号且在右部的最左端或最右端。通常程序设计语言的文法属于2型文法,可被下推机(Pushdown Automaton)识别。

语言定义为L(G)={w|S=>*w,w∈V T*},可见,文法G中的V T相当于产生语言的字母表,G中的一组产生式是产生语言的一组规则;语言L(G)中的每一个句子w,是由G的开始符号S经推导得到的,完全由终结符号组成的字。非终结符号是引起推导继续进行的中间符号,在推导进行到某一步时,如果再没有非终结符号留在推导的结果中,则称推导成功。

在语言的设计和编译器的编写方面,文法都提供了极大的优点:

a) 文法给出了精确的,也易于理解的语言语法说明。

b) 对于某些文法类,可以自动产生高效的分析器。额外的好处是,分析器的构造过程可以揭露出语法的二义性和其它难于分析的结构,这些问题在语言和它的编译器的最初设计阶很可能没有发现。

c) 设计得漂亮的文法,把结构加于程序设计语言,这些结构对把源程序翻译成为正确的目标代码和错误诊断都是有用的。把以文法为基础的翻译的描述转变成程序的开发工具也是存在的。

d) 语言也是逐渐完善的,需要补充新的结构和完成附加的任务。如果存在以文法为基础的语言的实现,这些新结构的加入就更方便。

2.2巴科斯范式(BNF)

巴科斯范式(Backus Normal Form,BNF)是描述语法规则的一种形式方法,在该方法中,使用如下符号:

< > 非终结号

::= 定义符

| 或者

{ } 括号内的成份可以重复出现多次,也可以不出现

[ ] 括号内的成份为任选项,可以出现一次或不出现

例如C语言中IF-THEN语句可以表示成:

::= IF <布尔表达式> THEN <语句> []

用巴科斯范式的形式表示文法的优点是简洁、清楚并容易被理解。

3.编译程序的实现环境Parse Generator简介及其使用

编译器生成工具----Parse Generator 基于Windows平台,它集成了词法生成器ALEX和语法生成器AYACC,并提供了较为强大的类库。其主要优点体现在以下几个方面:

●可以视一个编译程序为一个Project,集成Alex和Ayacc文件的环境有利于

整体调试和开发。且编辑界面友好,利于初学者使用。

●.l文件(lex文件)和.y文件(yacc文件)可生成为标准的C原代码,也可

生成Visual C++和Borland C++格式的原代码。这对习惯与BC或VC编程

的程序员,无疑是极大的方便。

●ALex和AYacc的表驱动代码隐藏在联接库中。库在程序LINK的时候连入

系统中。这在程序编译的效率和灵活性两个方面都有较大贡献。

●ALex和AYacc的原代码和和生成的目标代码(C或C++)可以建立语句的

对应,这对生成代码的调试提供很大方便。

实验中的编译程序采用将ALex和AYacc文件转化为Visual C++格式的代码。现将程序中使用的联接库中主要类和函数作一介绍。

●类yylexer ---- 所有词法分析器类的基类

yylexer类提供由Alex生成的C++词法分析器的一切基本功能。

yylexer是一个抽象类,要使用它,必须继承出自己的类,并实现抽象函数yylex 和yyaction。

C--编译器程序中的词法分析器类是其子类C_Lexer类。

●类yyparser ---- 所有语法分析器类的基类

yyparser类提供由AYacc生成的C++语法分析器的一切基本功能。

yyparser是一个抽象类,要使用它,必须继承出自己的类,并实现抽象函数yywork 和yyparseaction。

C--编译器程序中的语法分析器类是其子类C_Parser类。

五.详细设计

1.功能说明

输入:类C语言纯文本源程序。

输出:

·目标机为具有8086+处理器的MSDOS系统下的二进制可执行代

码。

·PC Assembly Language汇编语言源代码以供分析使用。

本编译程序实现的主要功能如下表所示:

2.词法分析器(lexer)

2.1 正规式和DFA

·ε和φ都是Σ上的正规式,它们所表示的正规集分别为{ε}和φ

·任何a∈Σ,a是Σ上的一个正规式,它所表示的正规集为{a}

·假定U和V都是Σ上的正规式,它们所表示的正规集分别记为L(U)和L(V),那么,(U|V)、(U.V)和(U)*也都是正规式,它们所表示的正规集分别为L(U)

∪L(V)、L(U)L(V)和(L(U))*。

仅由有限次使用上述三步骤而定义的表达式才是Σ上的正规式,仅由这些正规所表示的字集才是Σ上的正规集。正规式可以有效地描述词法,而确定的有限自动机(DFA)能准确地识别正规集,执行词法分析的功能。

2.2 利用有限自动机进行词法分析

词法分析是整个编译过程的第一阶段,它将字符序列转化为单词序列。识别单词的基本方法是根据词法定义构造有限自动机即描述语言结构特征的状态转换图。例如对于十进制整数正规定义:

[1-9]+[0-9]*

可以构造如图3所示的有限自动机。

图 3 识别十进制整数的有限自动机

其中状态2为接收态,若对于一个字符序列有限自动机可以到达2状态,则说明一个整数已被识别出来。词法分析器构造程序LEX正是根据这一原理工作的。构造词法分析器的主要任务是设计词法的正规定义和相关的动作。上面例子的LEX程序段就是:

[1-9]+[0-9]* return ICON;

2.3 C--词法分析器的实现

·数据结构

1)关键字和系统标识符表Ktab []

保存关键字和系统标识符的信息,定义如下:

typedef struct {

char *name;

int val;

} KWORD;

其中

·name域保存关键字的名字,val域保存关键字的种类标识。

·val域就是词法分析器传递给语法分析器的终结符信息。

2)C--中的关键字

以下为Ktab[]数组的定义:

KWORD Ktab[] = {

{"break", BREAK },

{"char", TYPE },

{"continue",CONTINUE},

{"do", DO },

{"else", ELSE },

{"for", FOR },

{"goto", GOTO },

{"if", IF },

{"int", TYPE },

{"main", MAIN },

{"print", PRINT },

{"while", WHILE }

};

·具体实现(参见源文件C--_lex.l)

1)对注释的处理:

支持/*....*/和//两种注释风格,对于注释内容在匹配到/* 和// 后,直接通过动作input跳过。处理了注释符号遗漏的情况,并有出错信息显示。

2)常数的处理:

词法分析器可识别十进制、八进制和十六进制无符号整数以及字符常数(形为’a’),并通过函数int stoi(char *string, int radix)转化成数值形式。

3)标点符号的处理:

直接返回其相应的标识。

4)标识符的处理:

识别标识符后,调用函数id_or_keyword查找其属性值并返回。

·对于系统保留字和关键字,函数id_or_keyword返回相应的标识(token)。

返回值相同的,可以通过yytext区别。

·对于用户自定义的标识符,函数id_or_keyword返回NAME。

为了提高查找关键字和系统标识符表的效率,函数id_or_keyword采用二分查找法(bsearch函数)。

5)嵌入汇编(_asm{……})的处理:

在函数id_or_keyword()中当遇到yytext=“_asm”时,则进入嵌入汇编处理代码:先匹配字符‘{’,如果接下来的第一个字符不是‘{’,则打印出错信息。如果匹配则将后续代码原样写入汇编代码中,直至遇到字符‘}’结束;如果未遇到则打印出错信息。由于要防止嵌入汇编代码中出现字符立即操作数‘}’或注释语句中的‘{’,因此要考虑这些情况。

采用上述方法的好处是大大简化了语法分析器的工作,不必设计大量的产生式来处理汇编格式。但是这样就不能检查嵌入汇编的语法错误。可以采用这样的方法:用Masm编译嵌入的代码,重定向其输出而判断有无汇编语法错误。

6)生成的C_Lexer 的类定义(参见源文件C--_lex.h):

class C_Lexer : public yyflexer {

public: 嵌入

C_Lexer ();

protected:

void yytables();

virtual int yyaction(int action);

public:

};

C_Lexer () 实现对词法分析器对象的初始化,它调用yytables()。

yyaction()则具体由定义的正则表达式实现归约。

3.语法分析器(parser)

3.1 上下文无关文法

上下文无关文法G可以用一个四元组表示

G=(V,T,P,S)

其中:

·V是文法的非终结符号集,每个非终结符号表示语言的一个语法变量;

·T是终结符号集,每个终结符号表示语言的一个基本符号,即词汇;

·P是产生式集,文法用产生式定义每个非终结符号;

·S是V中的一个非终结符号,称开始符号。

文法的每个产生式由左、右两部分组成,左部是一个非终结符号;右部是由零个或若干个终结符、非终结符组成的符号串。

3.2 LR分析方法

LR分析方法是自底向上进行语法分析,它的功能很强,适用于多种上下文

无关方法。L是指从左向右扫描输入串,R指的是按照最右推导的的逆过程进行归约。

LR分析法具有一些优点:

·能用上下文无关文法描述的程序设计语言结构,都可以构造其LR分析器

进行识别。

·LR分析法是具有一般性的无回溯移进归约分析法,并且能有效地被实现。

·能用LR分析器分析的文法类包含能用LL(1)分析器分析的全部文法类。

·LR分析器在自左向右扫描输入时,可以尽可能地发现语法错误。

图 4 LR分析器

图4是LR分析器的结构示意。其中分析栈存放状态和移进、归约的文法符号:S0X1S1...X m-1S m-1S0

其中,S i表示状态,X i表示文法符号;在实现中,文法符号不必进分析栈。动作表中的项目ACTION[S m,a i]表示当前输入符号为a i、栈顶状态为S m时,分析算法应执行的动作;若ACTION[S m,a i]=S i,表示移进,然后栈顶状态为i;r j表示用产生式j 归约;acc表示接收输入串,err表示语法错误。状态转换表中的项目GOTO[S i,X]表示归约出非终结符号X之后,当前栈顶状态为S i时,分析栈应转换到的下一上状态,即栈顶的新状态。

LR分析算法为:

根据输入符号a i、栈顶状态S m和动作表项action[S m,a i]的值,决定当前分析应执行的动作;移进、归约、接收或出错;移进或归约之后要根据动作表或状态转换表设置分析栈的状态。

可以把分析栈中的串和等待输入的终结答号串看成是两个分量,这两个分量构成如下形式的二元组:

(S0X1S1X2S2...X m S m, a i a i+1...a n#)

这个二元组结构表示右句型X1X2...X m a i a i+1...a n#

假定当前分析栈的栈顶为状态S m,下一个输入符号为a i,分析器的下一个动作由动作表项action[S m,a i]决定。

·如果action[S m,a i]=移进S,则分析器执行移进,二元组变成

(S0X1S1X2S2...X m S m a i S , a i+1...a n#)

即分析器将输入符号a i和状态S移进栈,于是,a i+1变成下一个输入符号。

·如果action[S m,a i]=归约A→β则分析器执行归约,二元组变成

(S0X1S1X2S2...X m-r S m-r AS , a i+1...a n#)

其中,S由goto表确定:S = goto[S m-r,a i],r=|β|,是句柄号串的长度。

归约时,分析器先从栈中弹出2r个元素:r个状态和r个文法符号;于是使状态S m-r 出现在栈顶;然后,再把归约产生式左部的非终结符A和由goto[S m-r,A]确定的状态S压入栈。在归约过程中不改变输入符号。对LR分析器来说,从栈中弹出的文法符号串X m-r+1...X m总是匹配归约产生式的右部β。

·如果action[S m,a i]=acc,则接收输入符号串,语法分析完成

·如果action[S m,a i]=err,则发现语法错误,调用错误处理子程序。

3.3 C--系统中使用的主要产生式(参见源文件C--_par.h)

program :MAIN LP RP c ompound_stmt

compound_stmt :LC local_defs stmt_list RC

local_defs :def_list

def_list :def_list def

| /* epsilon */

def:specifiers decl_list SEMI

decl_list :var_decl

| decl_list COMMA var_decl

var_decl :new_name

| var_decl LB ICON RB

| LP var_decl RP

new_name :NAME

specifiers :TYPE

stmt_list :stmt_list statement

| /* epsilon */

statement :SEMI

| compound_stmt

| PRINT LP expr COMMA DIVOP ICON RP SEMI

| expr SEMI

| GOTO target SEMI

| target COLON statement

| IF LP test RP statement

| IF LP test RP statement ELSE statement

| WHILE LP test RP statement

| DO statement WHILE LP test RP SEMI

| FOR LP opt_expr SEMI test SEMI

opt_expr RP statement

| BREAK SEMI

| CONTINUE SEMI

test :expr

| /* epsilon */

target :NAME

opt_expr :expr

expr :expr COMMA

non_comma_expr :non_comma_expr EQUAL non_comma_expr

| non_comma_expr ASSIGNOP non_comma_expr

| or_expr

or_expr :or_list

or_list :or_list OROR and_expr

| and_expr

and_expr :and_list

and_list :and_list ANDAND binary

| binary

binary : binary RELOP binary

|binary POWER binary

|……

|unary

unary : LP expr RP

|……

3.4 系统中符号表的实现

1)符号表的组织要求

编译程序用符号表跟踪关于名称的汇聚信息和作用域,当词法分析器识别出一个标识符后,编译程序就查找符号表,看它是否在符号表中,如果没有,则把这个新标识符填入符号表。在语义分析阶段和代码生成阶段也要通过查找符号表来获得标识符的属性信息。可见在编译过程中符号表的查、填动作非常频繁,因而提高符号表查填效率是提高编译程序运行效率的关键因素,也是对符号表设计的根本要求。

2)符号表的几种组织方式

·线性表

符表项按顺序排列,这种组织方式最简单并且实现也很容易。线性表的缺

点是插入和查找的效率较低,虽然可以采用反序查找、表项排序、动态调

整表项来提高效率,但其性能的改善是很有限的。

·哈希表

通过计算符号的哈希值来确定其在表格中的位置。哈希表结构简单、实现

较容易,而且其插入和查找效率很高。采用哈希表要解决“冲突”的问题,而解决冲突将会提高哈希表的复杂度。

·二叉树

二叉树的组织方式平均查填效率最高,但实现的复杂度较高。对于名称冲

突也要特别处理。在某些情况下,二叉树会退化成线性表,这个问题可以

通过采用A VL树的结构来解决,但这会进一步提高实现的代价。

3)C--系统中符号表的组织(参见源文件Symbol.h)

本编译程序中对符号表的管理和操作在C S ymbol类中实现,采用的是哈希杂凑表的方式。

该类的声明如下:

class CSymbol

{

public:

CSymbol();

symbol *NewSymbol(char *name, unsigned level);

symbol *FindSymbol(char *name);

bool DeleteNest(symbol *pHead);

unsigned Hash(char *name);

virtual ~CSymbol();

private:

Hash_Node *SymTable[TABLE_LEN];

};

类中所涉及到的结构声明如下:

struct symbol

{

char name[NAME_MAX+1]; // 输入变量名

char rname[NAME_MAX+1]; // 实际变量名

unsigned level; // 当前嵌套级

type *pType; // 变量类型

symbol *next; // 指向同层的下一个变量};

struct Hash_Node

{

Hash_Node *pre; // 上一个冲突节点

Hash_Node *next; // 下一个冲突节点

symbol *sym; // 指向此节点上的变量};

CSymbol采用哈希表来实现对变量的管理和查找。

变量表采用数组实现,对于每一个产生哈系冲突的变量节点,利用链表将其连接到已有的节点后。

在本编译程序中,采用了较复杂的计算哈系值的算法,其伪码如下:

unsigned CSymbol::Hash(char *name)

{

hash_val = 0;

for(对变量名中的每一个字符)

{

hash_val = (hash_val << 2) + 变量字符值;

if(i = hash_val & 0x3fff)

hash_val = (hash_val ^ (i >> 12)) & ~0x3fff;

}

返回hash_val;

}

CSymbol类中两个主要的成员函数是:

·symbol *FindSymbol(char *name),实现根据变量名,在变量表中查找该一项。

· symbol*New Symbol(char *name, unsigned level),实现在变量表中加入一

个symbol项。

4)其他主要结构定义(参见源文件Structs.h)

struct type

{

u nsigned noun; // CHAR INT

i nt num_ele; // number of elements if array

i nt v_int; // Value if constant

};

struct value

{

c har name[NAME_MAX * 2]; // Operan

d that accesses th

e value

t ype *pType; // Variable's type

s ymbol *sym; // Original symbol

b ool lvalue; // TRUE = lvalue, FALSE = rvalue

b ool is_tmp; // TRUE = temp, FALSE = non-temp

u nsigned offset; // Abolute value of offset from base of temp

// stack

};

3.5 系统中局部变量的处理

虽然本编译程序采用预分配栈来存放局部变量,这样的做法浪费空间且缺乏灵活性,但是它带来的一个好处是局部变量可以回收,而不像很多编译程序存在着局部变量无法回收的缺憾。

处理局部变量的主要函数有(参见源文件Functions.h及Functions.cpp):void figure_local_offsets(symbol *s);

void release_local(symbol *s);

函数figure_local_offsets为一个层中的局部变量分配空间,而函数release_local 则释放在某一层执行完时释放其中的所有变量。这可以通过遍历杂凑链表中的该层的变量链表(单向链表)得到所有变量的存储总长度,然后把局部变量堆栈指针减掉这个长度就可以了。这样该层的所有变量所占的空间都释放掉了。下一次又可以使用这些释放的空间。

3.6 系统中临时变量的处理

临时变量是编译系统中使用较多的部分,通过建立临时变量来记录每一次运算的结果,使后续的运算能方便地引用前次的值,是一个较通用的方法。所以,临时变量的管理成为编译程序中一个比较重要的部分。

·因为本编译程序的条件限制,系统中对临时变量的处理采取栈式结构存放的方法。

存放临时变量的堆栈是系统全局的,通过在编译程序初始化是建立,如下:fprintf(OutPut,"\t%s\tdb\t%d dup(?)\n\n", TMP_STACK, TMP_STACK_LEN);

此语句将在汇编源代码中生成如下的语句:

t_stack db 1024 dup(?)

·系统通过一个布尔型数组对临时变量栈进行管理。

bool Tmp_Reg[TMP_STACK_LEN];

Tmp_Reg[offset]的值表示临时变量栈中偏移量为offset的空间是否已被

分配为临时变量的存放。

·系统使用以下4个函数完成对临时变量的管理:

int tmp_alloc(int size);

value *tmp_create(type *t);

void tmp_free(int offset, int size);

void tmp_freeall(void);

3.7 系统中代码的生成

编译程序中的翻译的推导规则和每一个推导的相应动作,生成汇编源代码。(详见程序清单)

·主程序框架的生成

通过函数void Init(void) 和void End(void)完成。

Init主要任务:

·生成数据段、代码段;

·生成主程序的起始代码;

·返回地址入栈;

·创建全局和系统堆栈;

·初始化系统变量。

End主要任务:

·生成返回操作系统代码;

·结束代码段;

·结束程序。

·常量定义的翻译

本系统中常量的翻译,是通过函数:

value *make_icon(char *yytext, int numeric_val)

生成value结构并设置symbol结构,记录常量标识符的名称和值,把该symbol 加入处于栈顶的符号表。

·变量定义的翻译

本系统中变量的定义,是通过函数:

CSymbol类的NewSymbol(char *name, unsigned level) 成员函数实现。

该函数将判断是否有重复定义,如果有将提示出错信息;否则把新变量加

入符号表。

·赋值语句的翻译

赋值语句是构成程序体的基本语句。翻译赋值语句的任务是:计算在赋值

符号左边变量的地址,计算在赋值符号右边表达式的值,然后送入左值所

指的内存单元。

本系统只支持两种数据类型:int 和char。

所以可以方便的实现不同类型间的转化,具体由函数:

value* convert_type(value *v, type *t);

实现。

·当char 向 int转化时,高位补0;

·当int 向 char转化时,高位截断;

·控制流语句的生成

主要的控制语句有:if-then语句、do-while语句、while语句、for语句。

语句的生成较为简单,具体做法不详细描述。

值得一提的是:在通过实际的测试程序测试时,发现当生成的汇编跳转语

句“jz Label”与 Label 之间的代码长度超过128字节时,Masm编译将

报错。这是由汇编语言在16位地址下的局限性造成的。而实际上在while 和for语句中的循环体部分很容易超出128字节,所以通过对JZ 的模拟跳转来解决这个问题:

由gen("jz", L_NEXT, (void *)$$, -1);

变为

gen("jz", L_NEXT2, (void *)$$, -1);

gen("jmp", L_BUSTOP, (void *)$$, -1);

gen(":", L_NEXT2, (void *)$$, -1);

gen("jmp", L_NEXT, (void *)$$, -1);

gen(":", L_BUSTOP, (void *)$$, -1);

通过加入L_BUSTOP和L_NEXT2把JZ跳转限制在128字节内。但是此方法会使编译系统的输出代码变得冗长。

·print系统函数的处理

可以在Yacc文件中发现处理print系统函数的产生式。处理时调用了函数Print ()。该函数完成参数的入栈、过程调用以及堆栈恢复语句的生成,并且作一个标记表示程序中调用了print系统函数。

语法分析完毕时,函数End()会检查是否有print系统函数的调用,若有则在编译出的汇编代码之后插入print系统函数的汇编实现代码。

注:语法分析用到的所有函数都在Functions.h和Functions.cpp中定义声明。

六.总结

完成全部编程工作一共大约用了3个星期的时间,在整个编程过程中,我们小组成员通力合作,解决了不少无法想象的困难,最后经过大家的努力终于完成了这个程序。

文档编辑:朱嘉俊,王筱

C语言编译器的设计与实现.

C语言编译器的设计与实现 01计算机4班18号任春妍2号陈俊我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分: (1) 词法分析部分 (2) 语法分析处理及四元式生成部分 (3) 输出显示部分 一.词法分析器设计 由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值) #define ACC -2 #define syl_if 0 #define syl_else 1 #define syl_while 2 #define syl_begin 3 #define syl_end 4 #define a 5 #define semicolon 6 #define e 7 #define jinghao 8 #define s 9 #define L 10 #define tempsy 11 #define EA 12 #define EO 13 #define plus 14 #define times 15 #define becomes 16 #define op_and 17 #define op_or 18 #define op_not 19 #define rop 20 #define lparent 21 #define rparent 22 #define ident 23 #define intconst 24

一个简单的C语言编译器

个简单的C语言编译器 源代码: // // #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #include #include #include #include #include #include using namespace std; class Symbol { public: int line; string word; char group; Symbol(); Symbol(const Symbol &b); virtual ~Symbol(); operator =(const Symbol &b); string code; };

class Label { public: Label(); virtual ~Label(); string text; private: int n; static int next(); static int _label; }; class Action { public: static int lookUp(char v,int s); private: Action(); ~Action(); static int Table[54][19]; static string vs; }; class Goto { public: static int lookUp(char v,int s); private: Goto(); ~Goto(); static int Table[54][9]; static string vs; }; class Compiler {

Pascal语言编译器的设计与实现

Pascal语言编译器的设计与实现我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分: (1) 词法分析部分 (2) 语法分析处理及四元式生成部分 (3) 输出显示部分 一.词法分析器设计 由于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值) #define ACC -2 #define sy_if 0 #define sy_then 1 #define sy_else 2 #define sy_while 3 #define sy_begin 4 #define sy_do 5 #define sy_end 6 #define a 7 #define semicolon 8 #define e 9 #define sharp 10 #define S 11 #define L 12 #define tempsy 15 #define EA 18 //E and #define EO 19 //E or #define plus 34 #define subtract 35 #define times 36 #define divide 37 #define becomes 38 #define op_and 39 #define op_or 40 #define op_not 41 #define rop 42

一个简单编译器的实现

基于flex与bison的一个简单编译器的研究与实践 [摘要]编译是程序执行过程中一个重要的步骤,分为词法分析、语法分析、语义分析、中间代码生成、中间代码优化、机器代码生成、机器代码优化几个步骤。本文使用flex与bison 工具,编写了简洁的代码,实现了对一个简单语言的简单程序的词法分析、语法分析,最后生成了相应的抽象语法树。得出了flex与bison是编写词法分析器和语法分析器的有效工具的结论。 [关键词] 编译抽象语法树词法语法程序 目录 摘要 第一章绪论 1.1 为什么要用编译器 1.2 编译步骤 第二章简单编译器的研究与实现 2.1 简单编译器的结构 2.2 词法分析 2.3 语法分析 2.4 语义分析 第三章实验结果 全文总结 第一章绪论 1.1 为什么要用编译器 在计算机中,程序可以用不同的语言来编写,比如C,C++,汇编语言,机器代码等。计算机能够直接识别的只有机器代码,因此需要编译器来将其他语言编译成机器代码,或者将一种语言编译成另一种语言[1]。 编译器是一个计算机程序(或一系列程序),它能将用程序语言写的源代码编译成计算机能够识别的目标代码,后者往往是二进制代码[2]。 近年来基本的编译器设计都没多大的改变,而且它们正迅速地成为计算机科学课程中的中心一环。[5] 1.2 编译步骤 1.2.1 预处理 一个较为复杂的程序可能被分割为多个模块,并存放于对应的源文件中。预处理器是一个程序,它把源程序拼接在一起,并把宏转化为源语言的语句[3]。 1.2.2 词法分析 经过预处理的源程序会作为输入传递给编译器,词法分析是编译的第一个步骤。词法分析器以字符流的形式读入源程序,将它们组织成有意义的单词(token)[3]。flex是一种词法分析工具,它基于lex做了改进,能够更快地生成C语言词法分析程序。 1.2.3 语法分析 语法分析是编译的第二个步骤。在这个步骤中,根据语言的语法识别词法分析后得到的字符流,生成语法树。为了能够为应用程序提供清晰简洁的接口,隐藏复杂的底层信息,抽象语法树仅仅设计了有实际意义的节点。Bison是一种语法分析工具,它基于YACC做了改进,能够自动生成C语言语法分析程序。

C++课程设计报告(简易文本编辑器)

面向对象程序设计课程设计报告 (2011/2012学年第二学期) 题目名称简单文本编辑器的设计 系部 专业计算机科学与技术 班级 学生 完成时间 2012年 6 月 指导老师

在文本编辑器出现前,人们用打孔机把计算机文字打到穿孔卡片上。文字存放于一个装着这样的薄卡片的盒子里,可以用读卡器来阅读它。 第一个文本编辑器是一种行编辑器,它运行在打字机型的终端上,这种编辑器并不具备在窗口和屏幕中显示的功能。它包含了一些非常短的命令(为了减少打字量)。其中一个命令能够把文件的指定部分通过打字机打印出来。编辑光标是想象中的一个插入点,通过特殊命令,可以把它移动到特定内容字符串所在的行。随后,内容字符串又被扩展成正则表达式。如果想看到文件的变化,你需要把它打印出来。相对于穿孔机来说,人们认为这种基于行的文本编辑器具有革命性的进步。如果没有它,用户就需要把那些处理文本的命令打成专用的卡片,并在编辑文件时使用这些卡片。 当带有显示屏的计算机终端出现后,基于显示屏的文本编辑器开始流行起来。最早的全屏编辑器中,有一种叫做O26,它是于1967年为CDC 6000系列机器的操作控制台而作的。另外一个早期的全屏编辑器是vi。vi诞生于20世纪70年代,至今,它仍是Unix和Linux的标准编辑器。全屏编辑器对视频终端的销售起到了促进的作用。 文本编辑器在Windows的应用中是一个非常重要的项目,在过去十数年中,微软对windows文本编辑器有多个版本的升级改进,而基于其他的编程环境的文本编辑器也是多如牛毛,今天我们用MFC可视化编译环境做一个简易的文本编辑器。

引言 (2) 1.课程设计目的和意义 (4) 2.详细设计 (4) 2.1需求描述 (4) 2.1.1文件 (4) 2.1.2编辑 (4) 2.1.3应用 (5) 2.1.4帮助 (5) 2.1.5高级 (5) 2.2功能描述 (5) 2.2.1文本编辑区 (5) 2.2.2文件 (7) 2.2.3编辑 (15) 2.2.4应用 (16) 2.2.5帮助 (21) 2.2.6高级 (22) 2.2.7菜单栏 (25) 2.2.7图标 (26) 2.3程序运行说明 (27) 3.课程设计总结 (30) 3.1编程日志 (30) 3.3测试报告 (31) 4.心得体会 (31) 5.参考文献 (31)

Pascal语言编译器的设计与实现

Pascal语言编译器的设计与实现 我们设计的编译程序涉及到编译五个阶段中的三个,即词法分析器、语法分析器和中间代码生成器。编译程序的输出结果包括词法分析后的二元式序列、变量名表、状态栈分析过程显示及四元式序列程序,整个编译程序分为三部分: (1) 词法分析部分 (2) 语法分析处理及四元式生成部分 (3) 输出显示部分 一.词法分析器设计 于我们规定的程序语句中涉及单词较少,故在词法分析阶段忽略了单词输入错误的检查,而将编译程序的重点放在中间代码生成阶段。词法分析器的功能是输入源程序,输出单词符号。我们规定输出的单词符号格式为如下的二元式:(单词种别,单词自身的值) #define ACC -2 #define sy_if 0 #define sy_then 1 #define sy_else 2 #define sy_while 3 #define sy_begin 4 #define sy_do 5 #define sy_end 6 #define a 7 #define semicolon 8 #define e 9 #define sharp 10 #define S 11 #define L 12 #define tempsy15 #define EA 18 //E and #define EO 19 //E or

#define plus 34 #define subtract 35 #define times 36 #define divide 37 #define bexxes 38 #define op_and 39 #define op_or 40 #define op_not 41 #define rop 42 #define lparent 48 #define rparent 49 #define ident 56 #define intconst 57 函数说明 1.读取函数 readline( )、readchar ( ) 词法分析包含从源文件读取字符的操作,但频繁的读文件操作会影响程序执行效率,故实际上是从源程序文件””中读取一行到输入缓冲区,而词法分析过程中每次读取一个字符时则是通过执行 readchar ( )从输入缓冲区获得的;若缓冲区已被读空,则再执行readline( )从中读取下一行至输入缓冲区。 2.扫描函数 scan( ) 扫描函数 scan( )的功能是滤除多余空格并对主要单词进行分析处理,将分析得到的二元式存入二元式结果缓冲区。 3.变量处理 find 变量处理中首先把以字母开头的字母数字串存到spelling[ ]数组中,然后进行识别。识别过程是先让它与保留关键字表中的所有关键字进行匹配,若获得成功则说明它为保留关键字,即将其内码值写入二元式结果缓冲区;否则说明其为变量,这时让它与变量名表中的变量进行匹配),如果成功,则说明该变量已存在并在二元式结果缓

编译原理课程设计报告-简单文法的编译器的设计与实现

提供全套毕业论文,各专业都有 课程设计报告 设计题目:简单文法的编译器的设计和实现 班级:计算机1206 组长学号: 组长姓名: 指导教师: 设计时间:2014年12月 摘要 编译原理是计算机科学和技术专业一门重要的专业课, 它具有很强的理论性和实践性,目的是系统地向学生介绍编译系统的结构、工作原理以及编译程序各组成部分的设计原理和实现技术,在计算机本科教学中占有十分重要的地位。计算机语言之所以能由单一的机器语言发展到现今的数千种高级语言,就是因为有了编译技术。编译技术是计算机科学中发展得最迅速、最成熟的一个分支,它集中体现了计算机发展的成果和精华。 本课设是词法分析、语法分析、语义分析的综合,外加上扩展任务中间代码的优化和目标代码的生成,主要是锻炼学生的逻辑思维能力,进一步理解编译原理的方法和步骤。 关键词:编译原理,前端,目标代码,后端

目录 摘要 (3) 1. 概述 (6) 2. 课程设计任务及要求 (8) 2.1 设计任务 (8) 2.2 设计要求 (9) 3. 算法及数据结构 (10) 3.1算法的总体思想 (10) 3.2 词法分析器模块 (11) 3.2.1 功能 (11) 3.2.2 数据结构 (11) 3.2.3 算法 (12) 3.3 语法分析器模块 (13) 3.3.1功能 (13) 3.3.2 数据结构 (13) 3.3.3算法 (14) 3.4 中间代码产生器模块 (24) 3.4.1 功能 (24) 3.4.2 数据结构 (24) 3.4.3 算法 (25) 3.5 优化器模块 (27) 3.5.1 功能 (27) 3.5.2 数据结构 (27) 3.5.3 算法 (28) 3.6 目标代码生成器模块 (30) 3.6.1功能 (30) 3.6.2 数据结构 (30) 3.6.3 算法 (31)

编译器设计

编译器设计 一、实习目的及意义 编译器是将便于人类编写、阅读、维护的计算机高级语言程序翻译为机器能够识别、运行的计算机低级语言程序的一种系统软件。通过上学年《编译原理》课程的学习,我们已经理解了编译程序的组成结构,基本掌握的编译程序的各个阶段以及各阶段涉及到的基础知识。本次实习的目的是应用编译原理的基础知识完成一个简单编译器的设计与实现,加深对编译原理的理解,提高应用理论知识解决实际问题的能力及软件开发的能力。 二、实习内容及要求 1.使用C语言完成一个简单的C语言编译器的设计 与实现。 2.重点实现符号表的构造,词法分析,语法分析等 子程序(其中词法分析、语法分析及语义分析功 能必须实现)。 三、实习考核方式及成绩评定 1.完成编译器的设计与实现,撰写设计报告。 2.功能实现,设计报告合格者参加答辩。 3.最终成绩=出勤(20%)+源代码及设计报告(30%) +答辩成绩(50%)

4.实习期间以自主解决问题为主,可以查阅各种资 料,相互讨论交流,但严禁抄袭,抄袭者与被抄袭者一律取消实习答辩资格,成绩为零。 5.具体时间安排: 09.08-09.14设计与实现编译器 09.18答辩(按规定时间答辩) 四、设计要求 1.设计符号表 确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成查找、更新和删除操作。 1)查找:根据给定的名字,在符号表中查找其 信息。如果该名字在符号表中不存在,则将 其加入的符号表中,否则返回指向该名字的 指针。 2)删除:从符号表中删除指定名字的表项。 2.设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计为语法分析器的子程序,供其调用。功能包括: 1)具备预处理功能。删除程序中的注释和空格

实验报告简单Simple语言编译器的实现

《编译原理》课程设计报告 简单Simple语言编译器的实现 学院(系):计算机科学与技术学院 班级:0404102 学生姓名:李超学号24 指导教师:张华 时间:从2007年3月6日到2007年3月16日

《编译原理》课程设计 目录 1、课程设计的目的 (2) 2、课程设计的内容及要求 (2) 2.1、设计符号表 (2) 2.2、语法分析与中间代码产生器 (2) 3、实现原理 (3) 3.1、词法分析原理 (3) 3.2、语法分析原理 (3) 3.3、语义分析原理 (4) 4、算法实现流程图 (4) 4.1、词法分析算法实现流程图 (4) 4.2、语法分析算法实现流程图 (5) 4.3、语义分析算法实现流程图 (6) 5、测试数据 (6) 6、结果输出及分析 (7) 7、软件运行环境及限制 (11) 8、心得体会 (11) 9、参考文献 (11)

1、课程设计的目的 1.锻炼编写程序的能力,提高自己利用某种编程语言编写应用程序的能力, 从而提高自己的综合能力。 2.熟悉编译原理词法分析、语法分析和语义分析的方法和原理,进一步掌 握《编译原理》课堂上老师所讲的知识点,了解和掌握编译程序的工作 原理,加深对基本方法的了解。 3.进一步的理解编译原理,更好的的学习它的一些思路,掌握编译原理的 理论基础。进一步理解高级语言在计算机中的执行过程,加深对编译原 理中重点算法和编译技术的理解,提高自己的编程能力,培养好的程序 设计风格。同时通过某种可视化编程语言(如vc++)的应用,具备初步的 Windows环境下的编程思想。 2、课程设计的内容及要求 2.1、设计符号表 确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作: a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针; b.删除:从符号表中删除给定名字的表项。 1、设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括: a.具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号 串,即要求设计一个供词法分析调用的预处理子程序; b.能够拼出语言中的各个单词; c.将拼出的标识符填入符号表; d.返回(种别码,属性值) 2.2、语法分析与中间代码产生器 要求用LL1 、递归下降、算符优先分析法、SLR分析法等方法之一或若干方法,实现对表达式、各种说明语句、控制语句进行语法分析。

C语言编译器设计与实现毕业论文(设计)

毕业设计(论文)任务书 第1页

第2页

第3页

毕业设计(论文)原创性声明和使用授权说明 原创性声明 本人郑重承诺:所呈交的毕业设计(论文),是我个人在指导教师的指导下进行的研究工作及取得的成果。尽我所知,除文中特别加以标注和致谢的地方外,不包含其他人或组织已经发表或公布过的研究成果,也不包含我为获得及其它教育机构的学位或学历而使用过的材料。对本研究提供过帮助和做出过贡献的个人或集体,均已在文中作了明确的说明并表示了谢意。 作者签名:日期: 指导教师签名:日期: 使用授权说明 本人完全了解大学关于收集、保存、使用毕业设计(论文)的规定,即:按照学校要求提交毕业设计(论文)的印刷本和电子版本;学校有权保存毕业设计(论文)的印刷本和电子版,并提供目录检索与阅览服务;学校可以采用影印、缩印、数字化或其它复制手段保存论文;在不以赢利为目的前提下,学校可以公布论文的部分或全部内容。 作者签名:日期:

学位论文原创性声明 本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。对本文的研究做出重要贡献的个人和集体,均已在文中以明确方式标明。本人完全意识到本声明的法律后果由本人承担。 作者签名:日期:年月日 学位论文版权使用授权书 本学位论文作者完全了解学校有关保留、使用学位论文的规定,同意学校保留并向国家有关部门或机构送交论文的复印件和电子版,允许论文被查阅和借阅。本人授权大学可以将本学位论文的全部或部分内容编入有关数据库进行检索,可以采用影印、缩印或扫描等复制手段保存和汇编本学位论文。 涉密论文按学校规定处理。 作者签名:日期:年月日 导师签名:日期:年月日

编译原理课程设计一个简单编译器的设计与分析

摘要 使用过现代计算机的人都知道,多数用户是应用高级语言来实现他们所需要的计算的。现在计算机系统一般都含有不只一个的高级语言的编译程序,对有些高级语言甚至配置了几个不同性能的编译程序,供用户按不同需要进行选择。高级语言编译程序是计算机系统软件最主要的组成部分之一,也是用户最直接关系的工具之一。 计算机上执行一个高级语言程序一般分为两步:第一,用一个编译程序把高级语言翻译成机器语言程序;第二,运行所得的机器语言程序求得计算结果。 通常说的翻译程序是指能够把某一种语言程序转换成另一种语言程序(目标语言程序)。如果源语言诸如Fortran,Pascal,C,Ada或java这样的高级语言,而目标程序是诸如汇编语言或者机器语言这类的低级语言,这样的一个翻译程序就是称为编译程序。 一个编译程序的工作过程一般可以划分为五个阶段:词法分析、语法分析、语义分析与中间代码生成、优化、目标代码生成。每个阶段都是从上一个阶段得到结果,对他进行分析,并且根据一些外部环境(例如符号表等)得到最终的输出结果。要构造一个编译程序,可以按照这样的阶段来分别构造,最后来连调。 现在人们已经建立了多种编制部分编译程序或整个编译程序的有效工具。有些能用于自动生成扫描器(如LEX),有些可以用于自动产生语法分析器(如YACC),有些甚至可以用来自动产生整个的编译程序。这些构造编译程序的工具成为编译程序-编译程序、编译程序产生器或翻译程序书写系统,他们是按照编译程序和目标语言的形式描述而自动产生编译程序的。 编译程序是一极其庞大而又复杂的系统,掌握它比较苦难。但是一旦对其掌握,对以后的程序语言设计,系统软件分析,系统软件设计,形式语言研究等方面都是非常有好处的。 关键字:C语言、、编译、扫描器、语法分析

一种简单的编译器的设计

一种简单的编译器的设计 摘要:基于编译理论与虚拟机技术,经过词法分析、语法分析、语义分析等过程,设计一个简单的编译器,将某一种源程序编译成目标程序,以验证结果的正确性。 关键词:编译器;词法分析;语法分析;语义分析 中图分类号:TP311文献标识码:A文章编号: 1009-3044(2008)33-1508-03 The Design of a Simple Compiler CHENG Hua (Jiangsu Food Science College, Huaian 223003, China) Abstract: Based on compile theory and Virtual Machine technology,to transfer source program into destination program by Lexical analyse, Parse, Semantic analyse, and to test and verify the results. Key words: compiler; lexical analyse; parse; semantic analyse 1 设计背景 目前,计算机无纸化考试系统的应用越来越广,选择题、判断题的自动评分基本完善,但对程序修改题、编程题等考题来说,运用简单地看结果或指定行、段等办法评分,不能从根本上达到客观、公正地评阅考生答案。要想让计算机评

分具有智能化,就必须让计算机具备“思想”,即让评分系统能“看懂”考生答案,能“感受”设计成果的优越之处与不足所在,能给“过程分”及“设计创新分”,而绝不单纯依赖“运行结果”。本文以此为切入点,基于编译理论与虚拟机技术,自主设计有限元编译系统,分课程、分模块,能自行分析、编译考生答案(如程序代码),进而判断其正确性、合理性及优越性。 2 编译程序的一般结构 编译程序结构框图如图1。 3 编译器的设计 3.1 建立符号表及其管理程序 建立符号表,收录某种语言(C、PASCAL等)的所有字符集,允许在编译的各个阶段插入或查找名字的相关信息,并且能够反映出名字所在的位置,编制相应的程序来实现对字符表的各种操作,主要操作有:查找操作、插入操作、定位操作、重定位操作。 3.2 建立一个词法分析器 图1 核心技术是处理单词符号的种类及内部的编码(需要设计翻译表)、行计数器等,把词法分析器作为语法分析器调用的函数,词法分析器以二进制的形式输出单词符号的类别

编译原理课程设计 C语言编译器的实现

编译原理课程设计报告 设计题目编译代码生成器设计 学生姓名 班级 学号 指导老师 成绩

一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块 主程序 词法分析程序语法分析 程序 中间代码 生成程序

2. 表2.1 各种单词符号对应的种别码 单词符号种别码单词符号种别码bgin 1 :17 If 2 := 18 Then 3 < 20 wile 4 <> 21 do 5 <= 22 end 6 > 23 lettet(letter|digit)* 10 >= 24 dight dight* 11 = 25 + 13 ;26 —14 ( 27 * 15 ) 28 / 16 # 0 详细设计: 4.1界面导入设计 (1)一共三个选项: ①choice 1--------cifafenxi ②choice 2--------yufafenxi ③choice 3--------zhongjiandaima (2)界面演示 图一

一个编译器实验的设计与实现

一个编译器实验的设计与实现 摘要:本文介绍了一个适合描述球类比赛战术特点的脚本描述语言,并把该语言作为实验题目进行实验教学,介绍了学生设计并实现的脚本描述语言编译器,该脚本描述语言的词法和文法描述定义,给出词法分析器和语法分析器的结构设计,最后介绍实现中采用的关键技术。 关键词:脚本描述语言;词法分析器;语法分析器 1球类脚本描述语言 随着社会文明的发展与进步,体育比赛已经成为人民文化生活中不可缺少的组成部分。2008年,北京成功举办了第29届奥林匹克运动会,运动员共打破38项世界纪录,取得了骄人的成绩。作为本次奥运会科技攻关课题组的成员,我们参加了国家乒乓球队攻关项目的研究工作,为中国乒乓球队设计实现了一个基于视频标注的技、战术分析系统。我们采用编译技术翻译乒乓球脚本描述语言,实时、准确地记录并分析比赛中发生的各种技、战术细节,为教练员提供客观翔实的分析数据。 作为“编译原理”的任课教师,我们认为该课对学生系统掌握计算机基础理论十分重要,但由于学生在今后工作中很难用到编译技术,就会产生厌学思想,因此为学生设计一个好的编译原理实验成为当务之急。为此,我们结合承担的科研课题,设计了一个既让学生感兴趣,又能加深他们对编译原理思想理解的实验。 根据球类比赛的特点和脚本描述语言的设计要求,球类比赛可分为两种:一是比赛需主、客队同台(场)竞技,如沙滩排球、乒乓球、篮球、足球和网球等;二是主、客队轮流上场,比赛对手不是同台竞技,如台球和保龄球等。第一种球类比赛具有以下特点:(1)进攻/防守形成博弈;(2)博弈双方的技术动作具有相似性。为此,我们把第一种比赛的相关技、战术描述抽象成如下形式: 队员+技术动作+技术动作发生区域+技术动作结束区域 我们的设计目标主要针对第一种比赛。脚本描述语言的语法结构如图1所示。

一个简单文法的编译器前端的设计与实现

课程设计报告 设计题目:一个简单文法的编译器前端的设计与实现 班级:计算机1208班 组长学号:20124016 组长姓名:樊荣 指导教师:张俐 设计时间:2014年12月

设计分工 组长学号及姓名:20124016 樊荣 分工:四元式生成、语义分析(未定义、重定义等)、整体设计组员1学号及姓名:20124020 李鑫 分工:符号表建立及其输入输出设计 组员2学号及姓名:20124032 杨学良 分工:词法分析 组员3学号及姓名:20124018 焦通 分工:语法分析 组员4学号及姓名:201240 陈凤 分工:简单C语言文法设计及部分简单函数编写

摘要 编译器是程序员使用的关键工具,程序员每天都在使用编译器,并且非常依赖于其正确性和可靠性。编译器作为广大IT从业者必须接触的系统软件,它的设计本身又是一个极其庞大的工程。编译器相关的各项技术经过近几十年的发展,已经日臻成熟,然而编译器构造原理和技术依然是计算机科学中理论与实践相结合的最好典范。本文重点介绍了编译器前端的详细开发过程,分为四个部分分别阐述:文法设计,词法分析器的设计,语法分析器的设计,语义分析部分。每个部分又分别从功能,数据结构和算法三个方面进行详尽阐述,。由于C语言本身的复杂性,很难面面俱到实现所有标准定义,所以本次设计只象征性的选择部分具有代表性的功能。在本文的第四章详细给出了此次设计所实现的功能和语法规范,同时也给出了编译器的运行方式。 关键词:编译原理,编译器前端,C源程序……

目录 摘要 (1) 1 概述 (2) 2 课程设计任务及要求 (3) 2.1 设计任务 (3) 2.2 设计要求 (3) 3 算法与数据结构 (4) 3.1算法的总体思想(流程) (4) 3.2词法分析模块 (5) 3.2.1 功能 (7) 3.2.2 数据结构 (8) 3.2.3 算法 (9) 3.3 语法分析模块 (10) 3.3.1功能 (11) 3.3.2 数据结构 (12) 3.3.3算法 (13) 3.4 符号表模块 (13) 3.4.1功能 (13) 3.4.2 数据结构 (14) 4序设计与实现 (14) 4.1 程序流程图 (14) 4.2 程序说明 (15) 4.3 实验结果 (15) 5. 结论 (16) 6. 参考文献。 (17) 7. 收获、体会和建议。 (17)

简单编译器的设计与实现1

一、课程设计的目的 在学习《程序设计语言编译原理》课程过程中,结合各章节构造编译程序的基本理论分别完成词法分析器、语法分析器和语义分析器实验,在基本实验完成的基础上,逐步完成课程设计。针对自己的理解和学习,实现一个小编译器括符号表的构造,词法分析,语法分析,目标代码生成等重要子程序,其中词法分析、语法分析及语义分析功能必须完成),并对其进行分析解释和总结,同时将理论与实际应用结合起来,接受软件设计等开发过程的全面训练,从而提高软件开发的能力。 二、课程设计的任务 (1)设计符号表 确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。要考虑能够存储有关名字的信息,并可以高效地完成如下操作: a.查找:根据给定的名字,在符号表中查找其信息。如果该名字在符号表中不存在,则将其加入到符号表中,否则返回指向该名字的指针; b.删除:从符号表中删除给定名字的表项。 (2)设计词法分析器 设计各单词的状态转换图,并为不同的单词设计种别码。将词法分析器设计成供语法分析器调用的子程序。功能包括: a.具备预处理功能。将不翻译的注释等符号先滤掉,只保留要翻译的符号串, 即要求设计一个供词法分析调用的预处理子程序; b.能够拼出语言中的各个单词; c.将拼出的标识符填入符号表; d.返回(种别码,属性值)。 (3)语法分析器 要求用预测分析法、递归下降分析法、算符优先分析法、SLR分析法(几种方法任选),实现对表达式、各种说明语句、控制语句进行语法分析。 (4)目标代码生成器 能完成指定寄存器个数的情况下将一中间代码程序段翻译成汇编语言目标代码(汇编指令应包括加、减、乘、除),要求指令条数最少的情况下,尽量使

编译原理-课程设计报告-简单编译器实现-精品

课程设计 题目:简单编译器实现 学院:信息工程学院计算机系专业:计算机科学与技术班级:计科1103班 组长: 小组成员: 指导教师: 2014 年12 月19 日

目录 1 概述 (3) 1.1源、目标语言简介 (3) 1.2实现平台与运行平台简介 (3) 1.3其它 (4) 2简单词法分析器的设计与实现 (4) 2.1 基础理论说明 (4) 2.2 需求分析 (4) 2.3 概要设计 (5) 2.4 详细设计 (5) 2.5 测试数据与结果 (7) 2.6 心得体会 (7) 3 简单语法分析器设计与实现 (8) 3.1 基础理论说明 (8) 3.2 需求分析 (8) 3.3 概要设计 (8) 3.4 详细设计 (8) 3.5 测试数据与结果 (9) 3.6 心得体会 (10) 4 中间代码产生器的设计与实现 (10) 4.1 基础理论说明 (10) 4.2 需求分析 (10) 4.3 概要设计 (10) 4.4 详细设计 (11) 4.5 测试数据与结果 (12) 4.6 心得体会 (12) 附录: (14) 附录A:主要源程序与系统截图 (14) 附录B:任务分配表及个人完成的程序模块 (33) 附录C:小组讨论与研发记录 (34)

编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。由编译程序的五个阶段就对应了编译系统的结构。 其中词法分析器利用超前搜索、状态转换等方法,将源程序转化成为一个一个的单词符号二元式。一般程序语言的单词符号包括关键字、运算符、常数、标识符和界符。语法分析器将这些单词符号作为输入,对它进行语法分析。语法分析分为两种方法:自上而下分析法和自下而上分析法。针对不同程序语言的语法规则可以采取不同的分析方法,当然两种方法也可以同时使用。语法分析器把语法单元作为输入供语义分析器使用。一般的语义分析器主要采用的是语法制导方法,即在语法分析的同时进行语法分析,并产生一定的语义动作,来生成中间代码。上面三个过程可以与硬件无关,而接下来的优化器和目标代码生成器是针对某一种处理器而言的。代码优化是将语义分析生成的中间代码进行优化,产生执行效率更高的代码。目标代码生成器最终生成可以在某种机器上运行的机器语言或者汇编语言。在整个编译过程中还包括对表格的操作和对错误的处理,这些也都是非常重要的环节。 1.1源、目标语言简介 使用C语言做简单语法分析器,C语言是一门高级计算机编程语言,设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言 1.2实现平台与运行平台简介 在win32环境下进行编译,Win32是指Microsoft Windows操作系统的32位环境,是目前使用最多的操作系统。 实验环境:需要TC、VC++ 6.0等开发工具作为本次试验的环境。

C语言编译器设计与实现

C语言编译器设计与实现 摘要 随着计算机的广泛应用,计算机程序设计语言也从初期的机器语言发展为汇编语言,以及现在的各种高级程序设计语言。而编译技术是计算机语言发展的支柱,也是计算机科学中发展最迅速、最成熟的一个分支,他集中体现了计算机发展的成果与精华。 其核心思想就是把同样的逻辑结构和思想从一种语言表示的程序转换为另外一种语言表示的程序。从高级语言,甚至运行与虚拟平台的高级语言,到机器语言,最终到硬件执行的物理信号,这一层层的转化,都涉及编译技术的应用。 本系统采用C++为编程语言。论文主要介绍了本课题的开发背景,所要完成的功能和开发的过程。重点的说明了系统设计的重点、设计思想、难点技术和解决方案。 关键词:编译技术,编程程序,高级语言

C language compiler design and Implementation Abstract With the wide application of the computer, computer programming languages are developed from the early machine language into assembly language , and now a variety of high-level programming language. The compiler technology is the backbone of computer language development, but also the fastest growing in computer science , a branch of the most mature , he epitomizes the essence of the computer and the fruits of development . The core idea is the same logical structure of the program and ideas expressed in the conversion from one language to another language program represented . From the high-level language , and even running with high-level language virtual platform to machine language , and ultimately to the hardware implementation of the physical signal , the layers of transformation involves application of compiler technology . System uses C++ as the programming language. Paper introduces the development background of the topic, the development and function to complete the process. Note the focus of systems design, design ideas, technologies and solutions difficult. Key Words:Compiler technology,Programming procedures,High-level programming language

编译原理课程设计____C语言编译器的实现

南华大学 编译原理课程设计名:编译代生 成器设计 专业计算机科学与技术 学生姓名熊浩斌 班级计算机01班 学号 20109440114 指导老师陈星 实验地点 8栋 2-209 完成日期:2013.6.2

一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、算法正 确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块

(完整版)编译原理毕业课程设计___C语言编译器的实现

南华大学 编译原理课程设计名:编译代 生成器设计 专业计算机科学与技术 学生姓名熊浩斌 班级计算机01班 指导老师陈星 实验地点 8栋 2-209

完成日期:2013.6.2 一、课程设计的目的 编译原理课程兼有很强的理论性和实践性,是计算机专业的一门非常重要的专业基础课程,它在系统软件中占有十分重要的地位,是计算机专业学生的一门主修课。为了让学生能够更好地掌握编译原理的基本理论和编译程序构造的基本方法和技巧,融会贯通本课程所学专业理论知识,提高他们的软件设计能力,特设定该课程的课程设计,通过设计一个简单的PASCAL语言(EL语言)的编译程序,提高学生设计程序的能力,加深对编译理论知识的理解与应用。 二、课程设计的要求 1、明确课程设计任务,复习编译理论知识,查阅复印相关的编译资料。 2、按要求完成课程设计内容,课程设计报告要求文字和图表工整、思路清晰、 算法正确。 3、写出完整的算法框架。 4、编写完整的编译程序。 三、课程设计的内容 课程设计是一项综合性实践环节,是对平时实验的一个补充,课程设计内容包括课程的主要理论知识,但由于编译的知识量较复杂而且综合性较强,因而对一个完整的编译程序不适合平时实验。通过课程设计可以达到综合设计编译程序的目的。本课程的课程设计要求学生编写一个完整的编译程序,包括词法分析器、语法分析器以及实现对简单程序设计语言中的逻辑运算表达式、算术运算表达式、赋值语句、IF语

句、While语句以及do…while语句进行编译,并生成中间代码和直接生汇编指令的代码生成器。 四、总体设计方案及详细设计 总体设计方案: 1.总体模块 2. 表2.1 各种单词符号对应的种别码 单词符号种别码单词符号种别码 bgin 1 :17 If 2 := 18 Then 3 < 20 wile 4 <> 21 do 5 <= 22 end 6 > 23 lettet(letter|digit) 10 >= 24 * dight dight* 11 = 25 + 13 ;26 —14 ( 27 * 15 ) 28 16 # 0 详细设计:

相关主题
文本预览
相关文档 最新文档