版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、编译原理课程设计c语言词法分析器语法分析器 姓名: 某某某 学号: 班级: 软件一班 学院: 信息科学与技术学院2014年11月17日目录1c语言词法分析器的设计31.1实验目的31.2实验要求31.3实验环境31.4实现分析31.4.1词法分析的理论构架31.4.2程序入口设计41.4.3程序执行中的流程41.4.4程序的出口设计51.5源代码51.6结果分析81.7收获与体会112语法分析器122.1实验目的122.2实验要求122.3实验环境122.4实现分析122.4.1ll(1)分析方法的思想122.4.2程序的入口分析122.4.3程序运行的流程132.4.4程序的出口设计142.
2、5源代码142.6结果分析272.7收获与体会30参考文献:311 c语言词法分析器的设计1.1 实验目的通过设计、编制、调试一个具体的词法分析程序,加深对词法分析原理的理解,并掌握在对程序设计语言源程序进行扫描过程中将其分解为各类单词的词法分析方法。1.2 实验要求所编写的词法分析器要能对最基本的c语言程序进行词法分析。1.3 实验环境1. windows 7操作系统2. 华硕笔记本,内存4g,处理器i53. 装有microsoft visual studio 2010,并安装framework4.01.4 实现分析1.4.1 词法分析的理论构架词法分析器的功能输入源程序,按照构词规则分解成
3、一系列单词符号。单词是语言中具有独立意义的最小单位,包括关键字、标识符、运算符、界符和常量等(1) c语言的关键字经过搜索共有32个, 是由程序语言定义的具有固定意义的标识符。我编写的词法分析器只将其中的一部分常用的定义在程序中,他们有break,case,char,const,continue,default,do,double,else,enun, extern,float,for,goto,if,int,long,return,static,struct,switch,sizeof,typedef,union,unsigned,void,volatile,while而对于c语言的一些保留
4、字如“main”、“return”等我没有将其放入关键字的范围内。(2) 标识符 用来表示各种名字,如变量名,数组名,过程名等等。(3) 常数 常数的类型一般有整型、实型、布尔型、文字型等。(4) 运算符 我在本词法分析器里面定义了“+”、“-”、“*”、“/”四种运算符。(5) 界符 我则定义了如下11种, ; . ( ) = : 1.4.2 程序入口设计次法分析入口的设计方法很多,为了我们每次运行时方便起见,我们将我们的c语言程序放入一个txt文件中,每次我们运行程序时,程序将自行读取文件中的c语言代码,并将对其进行词法分析将分析结果输出到控制台,这样的输入方法避免了我们重复输入程序的问题
5、,我们需要对某程序进行词法分析时,我们只需要将我们的c语言程序拷贝到我们的txt文件中,运行程序即可进行词法分析了。开始1.4.3 程序执行中的流程打开txt文件读取c语言代码扫描、是否读取到相应字符nnnn n nyyy y yy界符?关键字?标识符?运算符?常数?记录标号记录标号记录标号记录标号记录标号输出结束1.4.4 程序的出口设计上面我们讲解了我们词法分析器的入口,但是我们的输出是怎样设计的呢。首先为了使我们的程序有参考对照,我将我们的c语言程序首先输出到控制台上,以便与后面的词法分析是做一个参考,无需再去打开我们相应的txt文件做对照了。其次,我将我的关键字和相应的界符以及相应的运
6、算符都编上一个序号,并且将其一一个二元式的方式输出到控制台上,以便灾后面的词法分析结果中形成对比。最后我们将词法分析的结果输出到控制台上,输出格式为,我们将每一句代码作为一个单位,在每句代码后面我们将给出本局代码分析得到词法分析后的字符标号。例如:typedef struct |22|19| 其意义就是typedef 和struct对应的标号为22和19这两种种别1.5 源代码/ cifa.cpp : 定义控制台应用程序的入口点。#include stdafx.h#include #include #include #include #include #include #includeusin
7、g namespace std;bool isletter(char ch) if (ch=a & ch=a & ch=0 & ch=9) return true; else return false;bool isp(char ch) if(ch=+|ch=*|ch=-|ch=/) return true; else return false;bool isj(char ch) if(ch=,|ch=;|ch=.|ch=(|ch=)|ch=|ch=|ch=|ch=:|ch=|ch=|ch=|ch=#) return true; / else return false;bool isblank
8、(char ch) if(ch= |ch=t) return true; else return false;int main() string src,ste,s; char ch0,ch,ch12; char ktt5520=break,case,char,const,continue,default,do,double,else,enun,extern,float,for,goto,if,int,long,return,static,struct,switch,sizeof, typedef,union,unsigned,void,volatile, while,标识符,无符号数 ,;,
9、:,.,(,),?,+,-,+,-,*,/,=,=,=,!=,#; / int pos=0; file *fp; fp=fopen(d:in.txt,r); ch0=fgetc(fp); while(ch0!=eof) /if(ch0!=t)src+=ch0; src+=ch0; ch0=fgetc(fp); src+=#; coutsrcendl; ch=srcpos+; ste= ; for(int j=0;j54;j+)coutjkttjendl; cout词法分析:n; while(ch!=#) char str20; if(ch!=n) if(isdigit(ch) /判断常数 in
10、t i=0; while(isdigit(ch)|ch=.) stri+=ch; /i+; ch=srcpos+; stri=0; ste=ste+|+22; coutstr; continue; else if(isletter(ch) /判断字符 int i=0,j; while(isletter(ch)|isdigit(ch) stri+=ch; /i+; ch=srcpos+; stri=0; for(j=0;j28;j+) /判断是否关键字 int t=strcmp(str,kttj); if(t=0) stringstream ss; ste+=|; ssste;ssste; br
11、eak; if(j=28)ste=ste+|+28; / cout ; coutstr; continue; else if(isp(ch) /判断是否运算符 int i=0,j; stri+=ch; stri=0; for(j=34;j38;j+) int t=strcmp(str,kttj); if(t=0) stringstream ss; ste+=|; ssste;ssste; break; coutstr; ch=srcpos+; continue; else if(isj(ch) /判断是否界符 int i=0,j; while(isj(ch) stri+=ch; ch=srcp
12、os+; stri=0; for(j=23;j47;j+) int t=strcmp(str,kttj); if(t=0) stringstream ss; ste+=|; ssste;ssste; break; coutstr; continue; else if(isblank(ch) coutch; ch=srcpos+; continue; else coutstebase=(int *)malloc(maxqsize*sizeof(int);/为base申请空间 if(!q-base) printf(队列构建失败(按任意键返回主菜单)n);getch();system(cls);ch
13、oice(q);q-front =q-rear = 0;/队列头,尾的初始化 return ok;int main()sqqueue *q;/定义队列 qq = (sqqueue*) malloc(maxqsize*sizeof(sqqueue);/为q申请空间initqueue(q);/构造空队列choice(q);/调用选择函数,获取主菜单return ok;运行后的结果:如图1.1 我先将txt文件中的代码取出图 1.1如图1.2 将我的标号显示在控制台上图 1.2如图1.3 输出词法分析结果图 1.3上述结果和我的预期一样,实现了对c语言的词法分析。1.7 收获与体会首先,这个词法分析
14、器我是用c语言编写,工作量确实有点大,但是由于扎实的c语言基本功,我还是很快的编写出了程序,是我对c语言的使用更加熟练了,此外由于是编写的c语言词法分析器,所以我需要更全面深刻的去了解c语言的知识,使我找到了一些盲区,比如有一些c语言的关键字还不是很熟悉。其次,我还认真的学习了编译原理的词法分析知识,对正规式,状态转换图,以及自动机的知识有了新的理解,并将其运用到我的程序中来,大大的开阔了我的视野,使我的编程能力又上了一个台阶2 语法分析器2.1 实验目的通过设计、编制、调试一个具体的语法分析程序,加深对语法分析原理的理解,学习并掌握一种语法分析的方法,让我们巩固上课内容,学习ll(1)分析法
15、,学会自上而下的文法分析方法。2.2 实验要求语法分析是编译过程的核心部分。他的任务是在词法分析识别单词符号串的基础上,分析并判断程序的的语法结构是否符合语法规则。由此编写一个语法分析器。2.3 实验环境1、 windows 7操作系统2、 华硕笔记本,内存4g,处理器i53、 装有visual c+ 6.0,并安装framework4.0注:因为本程序使用到了fprintf和fscanf两个系统函数,由于microsoft visual studio 2010出于安全考虑将这两个函数的参数增加为了4个,但是本程序依旧使用的老版本时的三个参数,所以本程序只能在visual c+ 6.0上运行。
16、2.4 实现分析2.4.1 ll(1)分析方法的思想自定向下分析时从左向右扫描输入串,分析过程中采用的最左推导,并且只需向右看一个符号就可以决定如何推导,通过给定的文法构造预测分析表和实现某个符号串 的分析。 我们知道一个文法要能进行ll(1)分析,那么这个文法应该满足:无二义性,无左递归,无左公因子。当文法满足条件后,再分别构造文法每个非终结符的first和follow集合,然后根据first和follow集合构造ll(1)分析表,最后利用分析表,根据ll(1)语法分析构造一个分析器。ll(1)的语法分析程序包含了三个部分,总控程序,预测分析表函数,先进先出的语法分析栈。2.4.2 程序的入
17、口分析本程序为了实现语法分析器的重用性,我设置了必须先将我们需要分析的文法输入,但是为了能够高效的输入文法,我设定了将文法的产生式放在相应的txt文件中,每次我们只需将我们的文法产生式放入次txt文件,运行程序就会自动将该文法的ll(1)分析表生成,如此我们便可以高效的实现语法分析。除此之外我还设定了本程序的编写者,和文件位置的指定。会在结果分析中有具体反映。输以输入以#结束的符号串。2.4.3 程序运行的流程#和文法开始符号进栈第一个输入符号读进a栈顶符号托出去放x中x弹栈,将y1y2yk逆序放入s栈中,若右部符号串为,则不进栈x=a?xvt?x=#?查mx,a=xy1y2ykx=a?将下一
18、个输入符号读进axvt?出错出错stopyyyyynnnnn2.4.4 程序的出口设计为了方便,我先将txt文件中的产生式输出到了控制台上以便观察,我将读出的产生式分为左部,中部,右部,并将其分别读入pronodei.leftsym,、 pronodei.midsym0 、pronodei.midsym1)、pronodei.rightsymj。因为中部我定义的是“-”符号故必须需要两个结构参数来存储。将产生式输出后,我用读到的产生式构造文法每个非终结符的first和follow集合,然后根据first和follow集合构造ll(1)分析表。并将其输出到控制台上。最后读入我们将需要分析的式子,
19、通过ll(1)分析表生成的规约,把式子放入规约栈中分析,并将分析过程输出到控制台上。2.5 源代码/ yufa2.cpp : 定义控制台应用程序的入口点。#include #include #include #include #include using namespace std; #define pro_midsym_max 2#define pro_rightsym_max 10#define untinfo_fir_max 10#define untinfo_fol_max 10#define stack_init_size 100#define stackincrement 10 t
20、ypedef struct pronode /产生式结构 char leftsym; /产生式左边的符号 char midsympro_midsym_max; /产生式推导符号 char rightsympro_rightsym_max; /产生式右边的符号,不超过十个 int length; /产生式长度pronode; typedef struct untinfo /每个非终结符的信息结构,包括first和follow集合 char firstuntinfo_fir_max; char followuntinfo_fol_max;untinfo;typedef struct /构造顺序栈,
21、存储符号 char *base; char *top; int stacksize;sqstack;typedef struct qnode /构造单链队列,存储输入符号串 char data; struct qnode *next;qnode,*queueptr; typedef struct queueptr front; /队头指针 queueptr rear; /队尾指针linkqueue;int pronum; /产生式个数char unterminate15; /非终结符表char terminate15; /终结符表char pronull20; /记录能产生空字符的非终结符pr
22、onode sheet1515; /分析表char select1515; /select集合,以便于构造分析表linkqueue remain; /剩余符号串 void inituntinfo(untinfo untinfo,int untinfonum); /初始化函数,对每个非终结符的信息结构进行初始化void initpronode(pronode pronode,int pronum); /初始化函数,对每个非终结符的产生式结构进行初始化void initstack(sqstack &s); /初始化栈void initqueue(linkqueue &q); /初始化队列void
23、enqueue(linkqueue &q,char c); /在队尾插入新的元素void exit(); /栈溢出处理函数void error();/出错处理void push(sqstack &s, char c); /入栈char pop(sqstack &s); /出栈void initsheet(pronode* sheet,int m,int n) ; /初始化分析表函数bool readpro(pronode pronode,char filename);/从文件读取产生式函数void printpro(pronode pronode,int pronum); /显示产生式void
24、 setunterminate(char unterminate,pronode pronode,int pronum); /设置非终结符表void setterminate(char unterminate,pronode pronode,int pronum); /设置终结符表int getnumofut(char unterminate); /获得非终结符个数int getnumoft(char terminate); /获得终结符个数int getutloaction(char unterminate,char c); /获得非终结符在非终结符表中的位置int gettlocactio
25、n(char unterminate,char c); /获得终结符在终结符表中的位置void first(pronode pronode,untinfo untinfo); /计算各非终结符的first集void follow(pronode pronode,untinfo untinfo); /计算各非终结符的follow集void addchar(char charray,char c); /将非终结符的所有first值加入first集void addchartochar(char charray,char otherarray); /将非终结符的所有first集加入first集void
26、 addfollow(char follow,char c); /将非终结符的所有follow值加入follow集bool isnull(char c); /非终结符能否产生空字符bool isterminate(char c); /判断是否为终结符号void setsheet(pronode pronode,untinfo untinfo); /设置分析表void setselect(pronode pronode,untinfo untinfo);/设置select集合void inputsym(); /输入字符串函数void scan(); /分析扫描的主控程序char getsym(l
27、inkqueue &q) ; /获取下一字符void printsym(sqstack &s); /显示符号栈符号void printremain(linkqueue &q); /显示剩余符号串void printsheet(int row,int col); /显示所使用产生式void success(); /分析成功void main() char filename10; cout编制人:徐玉松,20122617,软件一班endl; cout请输入放有产生式的文件(如:xuyusong.txt):filename; pronode pronode20; initpronode(pronod
28、e,20); if(readpro(pronode,filename) /*输出文法产生式*/ cout该文法产生式为:endl; printpro(pronode,pronum); /*设置非终结符表和终结符表*/ setunterminate(unterminate,pronode,pronum); setterminate(terminate,pronode,pronum); /* 输出first集*/ int numofut = getnumofut(unterminate); int numoft = getnumoft(terminate); untinfo untinfo20;
29、inituntinfo(untinfo,20); /* 输出first集*/ first(pronode,untinfo); /* 输出follow集*/ follow(pronode,untinfo); /*设置select*/ setselect(pronode,untinfo); /*输出sheet*/ coutendl分析表:endl; setsheet(pronode,untinfo); coutt; for(int jj = 0 ; jj numoft ; jj+) coutterminatejjt; coutendl; for(int mm = 0 ; mm numofut ;
30、mm+) coutunterminatemmt; for(int mn = 0 ; mn numoft; mn+) printsheet(mm,mn); coutt; coutendl; inputsym(); /输入字符串 scan(); /主控程序 else error(); void initpronode(pronode pronode,int pronum) /初始化函数,对每个非终结符的产生式结构进行初始化 for(int i = 0 ; i pronum ; i+) pronodei.leftsym = 0; memset(pronodei.midsym,0,pro_midsym
31、_max); memset(pronodei.rightsym,0,pro_rightsym_max); pronodei.length = 0; void inituntinfo(untinfo untinfo,int untinfonum) /初始化函数,对每个非终结符的信息结构进行初始化 for(int i = 0 ; i = s.stacksize) /栈满,追加存储空间 s.base = (char *)realloc(s.base,(s.stacksize + stackincrement) * sizeof(char); if(!s.base) exit(); /存储分配失败 s
32、.top = s.base + s.stacksize; s.stacksize += stackincrement; *(s.top) = c; s.top = s.top + 1; char pop(sqstack &s) /出栈 if(s.top = s.base ) return null; s.top = s.top - 1; char tmpchar = *(s.top); return tmpchar; void initqueue(linkqueue &q) /初始化队列 q.front = q.rear = (queueptr)malloc(sizeof(qnode); if
33、(!q.front) exit(); /存储分配失败 q.front-next = null; void enqueue(linkqueue &q,char c) /在队尾插入新的元素 queueptr p = (queueptr)malloc(sizeof(qnode); if(!p) exit(); /存储分配失败 p-data = c; p-next = null; q.rear-next = p; q.rear = p; void exit() /溢出处理 cout溢出!endl; void error() /出错处理 cout分析出错!endl; void initsheet(pro
34、node* sheet,int m,int n) /初始化分析表函数,以便将无定义的表格定义为error for (int i = 0 ; i m;i+) for(int j = 0 ; j n ; j+) sheetij.leftsym = 0; /用0标记无定义的表格 bool readpro(pronode pronode,char filename) file* pfile; if(pfile = fopen(filename,r) = null) cout打开文件出错!endl; return false; char tmpchar; int tmpindex = 0; fscanf
35、(pfile,%c,&tmpchar); while(tmpchar != #) /求出产生式的个数 if(tmpchar = ;) tmpindex+; fscanf(pfile,%c,&tmpchar); pronum = tmpindex; rewind(pfile); for(int i = 0;i pronum;i+) /读出各产生式并置于已定义的数据结构pronode中, /同时可将非终结符置于非终结符号表 fscanf(pfile,%c %c %c,&pronodei.leftsym,&pronodei.midsym0, &pronodei.midsym1); pronodei.midsym2 = 0; fscanf(pfile,%c,&tmpchar); int j = 0; while(tmpchar != ;) pronodei.rightsymj = tmpchar; fscanf(pfile,%c,&tmpchar); j+; pronodei.rightsy
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2019-2020南昌市期末检测卷
- 甲型副伤寒病因介绍
- 教科版小学综合实践6下(教案+课件)27 综合实践活动计划表
- 牙齿治疗病因介绍
- 满月脸病因介绍
- 《文献的类型及识别》课件
- (高考英语作文炼句)第15篇译文老师笔记
- 2024年中考英语复习冲刺过关专题07 阅读理解(解析版)
- 开题报告:智能时代应用型本科高校教师核心素养研究
- 开题报告:支撑教育高质量发展的国家教育管理信息化体系研究
- 人教版八年级上册地理《第4章 中国的经济发展 第2节 农业 第1课时 农业及其重要性 农业的地区分布》课件
- 高考日语语法之授受关系的动词课件
- 人体解剖生理学理论知识考核试题题库及答案
- 英语专业英语作文范文精选61篇
- 园林景观工程施工组织机构
- 新青年的责任与担当PPT中国青年始终是实现中华民族伟大复兴的先锋力量PPT课件(带内容)
- 《国际结算(第五版)》第九章 跨境贸易人民币结算
- 习题2:山地回忆
- 坍落度试验课件
- 消防设施操作员报名承诺书
- 中医方剂学之祛湿剂课件
评论
0/150
提交评论