西南交大 实验1_第1页
西南交大 实验1_第2页
西南交大 实验1_第3页
西南交大 实验1_第4页
西南交大 实验1_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编译原理课程设计报告一姓名:学号:专业:班级:西南交通大学信息科学与技术学院■_rJ2017年5月25日课程设计一:手工设计C语言的词法分析器一、设计内容处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。二、设计目的通过本实验的设计更具体的理解词法分析器的工作机制。同时更理解C语言的结构体系。从而更深刻的透析编译原理过程。三、需求分析:词法分析程序又称词法分析器或词法扫描器。可以单独为一个程序;也可以作为整个编译程序的一个子程序,当需要一个单词时,就调用此法分析子程序返回一个单词,这里,作为子程序词法分析器的结构:状态转换图的程序实现为便于程序实现,假设每个单词间都有界符或运算符或空格隔开,并引入下面的全局变量及子程序:1) ch存放最新读进的源程序字符2) strToken存放构成单词符号的字符串3) Buffer 字符缓冲区4) structkeyType存放保留字的符号和种别算法设计简要描述要想手工设计词法分析器,实现C语言子集的识别,就要明白什么是词法分析器,它的功能是什么。词法分析是编译程序进行编译时第一个要进行的任务,主要是对源程序进行编译预处理(去除注释、无用的回车换行找到包含的文件等)之后,对整个源程序进行分解,分解成一个个单词,这些单词有且只有五类,分别是标识符、保留字、常数、运算符、界符。以便为下面的语法分析和语义分析做准备。可以说词法分析面向的对象是单个的字符,目的是把它们组成有效的单词(字符串);而语法的分析则是利用词法分析的结果作为输入来分析是否符合语法规则并且进行语法制导下的语义分析,最后产生四元组(中间代码),进行优化(可有可无)之后最终生成目标代码。可见词法分析是所有后续工作的基础,如果这一步出错,比如明明是‘<='却被拆分成‘<'和‘='就会对下文造成不可挽回的影响。因此,在进行词

法分析的时候一定要定义好这五种符号的集合。下面是我构造的一个C语言子集。第一类:标识符letter(letter|digit)*无穷集第二类:常数(digit)+无穷集第三类:保留字(32)autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile第四类:界符‘/*'、‘//'、(){}[]""'等第五类:运算符V、<=、>、>=、=、+、-、*、/、A、等对所有可数符号进行编码:{"$ID",0},{"$INT",1},{"auto",2},{"break",3},{"case",4},。。。。。。。。。{"-",36},{"/",38},{"%",39},{",",40},{";",41},{"(",42},{")",43},{"?",44},{"clear",45},{"#",46}{常数99,数值}{标识符100,标识符指针}上述二元组中左边是单词的符号,右边为其种别码,其中常数和标识符有点特别,因为是无穷集合,因此常数用自身来表示,种别码为99,标识符用标识符符号表的指针表示(当然也可用自身显示,比较容易观察),种别码100。保留字表的设计结构:

单诃符号种别码助记蒔内科直DB11SDDI⑴—)IF2SIF①)DO3SDO(3. )STOP4SSTDP(4 )END5SEND(筑—)标识符6SID",申働正常数7SDTT数值)3SASSIGN(8,)9SPLLSC )10SSTAH(10,―)11SPOWERdb)j12SCOMMA(12,一)13SLPAR门爲—))14SRPAR(14,—)基本功能状态转换:、0其它数匕^母严一、0其它数匕^母严一6非jO绕<3O二元组输出到文件可以用ofstream(写操作(输出)的文件类)函数来实现五、程序流程词法分析程序读入语句直到语句末尾。对读取的文件进行预处理,从头到尾进行扫描,去除//和/**/的内容,以及一些无用的、影响程序执行的符号如换行符、回车符、制表符等。但是千万注意不要在这个时候去除空格,因为空格在词法分析中有用,比如说inti=3;这个语句,如果去除空格就变成了“inti=3”,这样就失去了程序的本意,因此不能在这个时候去除空格。选下面就要对源文件从头到尾进行扫描了,从头开始扫描,这个时候扫描程序首先要询问当前的字符是不是空格,若是空格,则继续扫描下一个字符,直至不是空格,然后询问这个字符是不是字母,若是则进行标识符和保留字的识别;若这个字符为数字,则进行数字的判断。否则,依次对这个字符可能的情况进行判断,若是将所有可能都走了一遍还是没有知道它是谁,则认定为错误符号,输出该错误符号,然后结束。每次成功识别了一个单词后,单词都会存在token[]中。然后确定这个单词的种别码,最后进行下一个单词的识别。这就是扫描程序进行的工作,可以说这个程序彻底实现了确定有限自动机的某些功能,比如说识别标识符,识别数字等。为了简单起见,这里的数字只是整数。六、数据结构保留字结构:structkeyType{charkeyname[256];intvalue;}Key[N]={{"$ID",0},{"$INT",1},{"auto",2},{"break",3},{"case",4},{"char",5},{"const",6},{"continue",7},{"default",8},{"do",9},{"double",10},{"else",11},{"enum",12},{"extern",13},{"float",14},{"for",15},{"goto",16},{"if",17},{"int",18},{"long",19},{"register",20},{"return",21},{"short",22},{"signed",23},{"sizeof",24},{"static",25},{"struct",26},{"switch",27},{"typedef",28},{"union",29},{"unsigned",30},{"void",31},{"volatile",32},{"while",33},{"=",34},{"+",35},{"-",36},{"*",37},{"/",38},{"%",39},{",",40},{";",41},{"(",42},{")",43},{"?",44},{"clear",45},{"#",46}};七、主要函数说明voidGetChar()//读一个字符到ch中voidGetBC() 〃读一个非空白字符到ch中voidConCat()〃把ch连接到strToken之后boolLetter() 〃判断ch是否为字母boolDigit()//判断ch是否为数字6.intReserve。 〃用strToken中的字符查找保留字表,并返回保留字种别码,若返回0,则非保留字voidRetract()//把ch中的字符回送到缓冲区keyTypeReturnWord() //词法分析器八、源程序#include"stdio.h"#include"stdlib.h"#include"conio.h"#include"string.h"#defineN47 //保留字个数charch='\0'; //存放最新读进的源程序字符charstrToken[20]="\0"; //存放构成单词符号的字符串charbuffer[257]="\0";//字符缓冲区/* 保留字结构 */structkeyType{charkeyname[256];intvalue;}Key[N]={{"$ID",0},{"$INT",1},{"auto",2},{"break",3},{"case",4},{"char",5},{"const",6},{"continue",7},{"default",8},{"do",9},{"double",10},{"else",11},{"enum",12},{"extern",13},{"float",14},{"for",15},{"goto",16},{"if",17},{"int",18},{"long",19},{"register",20},{"return",21},{"short",22},{"signed",23},{"sizeof",24},{"static",25},{"struct",26},{"switch",27},{"typedef",28},{"union",29},{"unsigned",30},{"void",31},{"volatile",32},{"while",33},{"=",34},{"+",35},{"-",36},{"*",37},{"/",38},{"%",39},{",",40},{";",41},{"(",42},{")",43},{"?",44},{"clear",45},{"#",46}};

/*子过程*//*子过程*/voidGetChar()//读一个字符到ch中{inti;if(strlen(buffer)>0){ch=buffer[0];for(i=0;i<256;i++)buffer[i]=buffer[i+1];}elsech='\0';}voidGetBC()//读一个非空白字符到ch中{inti;while(strlen(buffer)){i=0;ch=buffer[i];for(;i<256;i++)buffer[i]=buffer[i+1];if(ch!=''&&ch!='\n'&&ch!='\0')break;}}voidConCat() //把ch连接到strToken之后{chartemp[2];temp[0]=ch;temp[1]='\0';strcat(strToken,temp);}boolLetter()//判断ch是否为字母{if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z')returntrue;elsereturnfalse;}boolDigit()〃判断ch是否为数字{ if(ch>='0'&&ch<='9')returntrue;elsereturnfalse;}intReserve()//用strToken中的字符查找保留字表,并返回保留字种别码,若返回0,则非保留字{inti;for(i=0;i<N;i++)if(strcmp(strToken,Key[i].keyname)==0)returnKey[i].value;return0;voidRetract() //把ch中的字符回送到缓冲区{inti;if(ch!='\0'){buffer[256]='\0';for(i=255;i>0;i--)buffer[i]=buffer[i-1];buffer[0]=ch;}ch='\0';}/* 词法分析器 */keyTypeReturnWord(){strcpy(strToken,"\0");intc;keyTypetempkey;GetBC();if(ch>='A'&&ch<='Z'||ch>='a'&&ch<='z'){ConCat();GetChar();while(Letter()||Digit()){ConCat();GetChar();}Retract();c=Reserve();strcpy(tempkey.keyname,strToken);if(c==0)tempkey.value=0;elsetempkey.value=Key[c].value;}elseif(ch>='0'&&ch<='9'){ConCat();GetChar();while(Digit()){ConCat();GetChar();}Retract();strcpy(tempkey.keyname,strToken);tempkey.value=1;else{ConCat();strcpy(tempkey.keyname,strToken);tempkey.value=Reserve();}returntempkey;}/* 主函数 */intmain(){ofstreamout("out.txt");keyTypetemp;strcpy(buffer,"for(inti=1;;i++){inttmp=2147483647;if(tmp<=b)break;}");cout<<"Pleaseinputstring:"<<endl<<buffer<<endl;out<<"(单词,种别号)"<<endl;while(strlen(buffer)){temp=ReturnWord();out<<'('<<temp.keyname<<','<<temp.value<<')'<<endl;}cout<<

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论