您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 编译原理实验报告1王豪
编译原理实验报告(词法分析部分)姓名:王豪学号:20132164专业:软件工程班级:软件1班一、实验题目:《手工设计c语言的词法分析器(可以是c语言的子集)》二、实验内容:处理c语言源程序,过滤掉无用符号,判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。三、实验目的:了解高级语言单词的分类,了解状态图以及如何表示并识别单词规则,掌握状态图到识别程序的编程。四、实验环境:1.系统:Win102.编译工具:VS20103.语言:C++五、需求分析:1.要求手工设计c语言的词法分析器(可以是c语言的子集)。2.词法分析器需要先处理c语言源程序,过滤掉无用符号。3.词法分析器的主要功能是判断源程序中单词的合法性,并分解出正确的单词,以二元组形式存放在文件中。六、概要设计:可以将词法分析程序分为字符文件缓冲区、词法分析、结果输出三部分。1.基本流程:开始字符缓冲区读入数据词法分析器从缓冲区提取字符,并利用状态转换图进行分析分析结束?否输出结果是结束2.使用的数据结构://词法分析器返回类型结构体structWORD_TYPE{intID;charvalue[MAX_TOKEN_SIZE];};//WORD_TYPE的缺省空值WORD_TYPENULL_WT={0,0};//WORD_TYPE的错误值WORD_TYPEERR_WT={-1,-1};七、详细设计:IsLetter函数判断是否为字母、IsKey函数判断是否为关键字、IsDigit判断是否为数字,通过analyse()函数进行分析,analyse()为主要的函数体,主要通过case语句和if—else语句实现各种各种运算符的判别过程,最后main()函数调用并且输出结果。八、结果测试1.测试程序代码:#includestdafx.h#includeGetWord.hint_tmain(intargc,_TCHAR*argv[]){fstreamfile(H:\\test2.txt,ios_base::trunc|ios::out);WORD_TYPEwt;InitBuffer(H:\\test.txt);wt=GetWord();fileID:wt.IDValue:wt.valueendl;while(wt.ID!=0){wt=GetWord();if(wt.ID!=0)fileID:wt.IDValue:wt.valueendl;if(wt.ID==-1){break;}}file.close();return0;}2.输入的原始数据:3.测试结果:截图1截图2九、小结通过编写这次的课程设计,学会了用C++语言编写词法分析器,掌握了词法分析器的原理以及功能且加深对编译原理和应用程序的理解。通过设计调试词法分析程序,实现了从程序中分出各种单词的方法,从而加深了对该知识的理解,提高了词法分析的实践能力。总之,通过本次实验,提高了自己的能力,使我受益匪浅。附代码://=======================//定义的宏//=======================#defineMAX_BUFFER_SIZE256#defineMAX_TOKEN_SIZE128#defineSIGN_SIZE12#defineOTHER_SYMBOL_SIZE2#defineREVERSE_SIZE1#defineSIGN_START_ID1#defineREVERSE_START_ID11//=======================//词法分析全局变量的定义//=======================WORD_TYPENULL_WT={0,0};WORD_TYPEERR_WT={-1,-1};fstreamsource_File;charBuffer[MAX_BUFFER_SIZE];intbuffer_Index;intbuffer_Size;charCHAR;charTOKEN[MAX_TOKEN_SIZE];inttoken_Index;charReserveTable[REVERSE_SIZE][30]={clear};charSignTable[SIGN_SIZE]={'=','?','+','-','*','/','(',')','X','X','X',';'};//================================//词法分析的函数声明//================================//**初始化文件缓冲区函数**//参数:charaddr[]:要读取的文件的地址//返回:地址合法初始化成功返回true,地址非法初始化失败返回falseexternboolInitBuffer(charaddr[]);//**关闭文件缓冲区函数**//注:编译结束后调用该函数关闭读取的文件externvoidCloseBuffer();//**更新缓冲区数据函数**//返回:调用成功返回true,调用失败返回false//注:该函数只有在缓冲区索引指到缓冲区末尾时才能调用成功,//否则在缓冲区没有被扫描完毕时调用该函数更新缓冲区都会失败externboolUpdateBuffer();//**从缓冲区读取一个字符到全局字符变量CHAR中的函数**//返回:成功从缓冲区读取一个字符返回true,缓冲区为空读取失败时返回false//注:在缓冲区被扫描完毕时该函数会调用UpdateBuffer()刷新缓冲区,当缓冲区//为空(既文件为空或已经结束)该函数调用失败返回falseexternboolGetChar();//**从缓冲区读取一个非空字符到全局字符变量CHAR中的函数**//返回:成功从缓冲区读取非空字符返回true,缓冲区为空读取失败时返回false//注:该函数内部调用GetChar(),只要当前读取的字符为空该函数会一直被调用//GetChar()直至读取的为非空字符或者达到文件结尾externboolGetBC();//**把CHAR中字符连接到全局字符串TOKEN中的函数**//返回:连接成功返回true,TOKEN已经达到最大长度无法加入新的字符返回falseexternboolConcat();//**判断字符是否为“字母”的函数**//返回:字符是“字母”返回true,不是“字母”返回falseexternboolLetter();//**判断字符是否为“数字”的函数**//返回:字符是“数字”返回true,不是“数字”返回falseexternboolDigit();//**判断是否为“保留字”的函数**//返回:若TOKEN中的字符串为“保留字”返回保留字在保留字表中的ID,若不//是“保留字”则返回-1//注:保留字的ID为:保留字在保留字表中的序号+REVERSE_START_ID(这样做是//为了保留字ID,算符/标点ID,一般标识符的ID,数字的ID,非终结符ID之间//不会冲突)externintReserve();//**判断是否为“算符/标点”的函数**//返回:若TOKEN中的字符串为“算符或者标点”返回保留字在保留字表中的ID,//若不是“算符或者标点”则返回-1//注:“算符/标点”的ID为:“算符/标点”在“算符/标点”表中的序号//+SIGN_START_ID(这样做是为了保留字ID,算符/标点ID,一般标识符的ID,//数字的ID,非终结符ID之间不会冲突)externintSign();//**把CHAR中字符回退到缓冲区的函数**//注:该函数是把已经读取到CHAR中的字符回退到缓冲区中,回退后缓冲区索引//自动减一externvoidRetract();//**词法分析函数**//返回:返回一个分析后的词类型的结构体,形式为(符号类型号,符号值)//特殊情况:若语法出错返回(-1,-1),若文件为空或已经结束返回(0,0)externWORD_TYPEGetWord();//================================//词法分析的函数定义//================================//**初始化文件缓冲区函数**boolInitBuffer(charaddr[]){source_File.open(addr);if(!source_File)returnfalse;buffer_Index=0;token_Index=0;source_File.read(Buffer,MAX_BUFFER_SIZE);buffer_Size=source_File.gcount();//获取当前缓冲的大小(既读入缓冲区//的字节数)returntrue;}//**关闭文件缓冲区函数**voidCloseBuffer(){buffer_Index=0;buffer_Size=0;token_Index=0;if(source_File)source_File.close();}//**更新缓冲区数据函数**boolUpdateBuffer(){if(buffer_IndexMAX_BUFFER_SIZE-1)returnfalse;source_File.read(Buffer,MAX_BUFFER_SIZE);buffer_Index=0;buffer_Size=source_File.gcount();//获取当前缓冲的大小(既读入缓冲区//的字节数)returntrue;}//**从缓冲区读取一个字符到全局字符变量CHAR中的函数**boolGetChar(){if(buffer_Index=buffer_Size)CHAR=Buffer[buffer_Index++];else{UpdateBuffer();if(buffer_Size==0)returnfalse;elseCHAR=Buffer[buffer_Index++];}returntrue;}//**从缓冲区读取一个非空字符到全局字符变量CHAR中的函数**boolGetBC(){if(!GetChar())returnfalse;if(CHAR!=''&&CHAR!='\n'&&CHAR!='\t'&&CHAR!=0)//空格、回车、制表符、//还有空都视为无效字符returntrue;elsereturnGetBC();}//**把CHAR中字符连接到全局字符串TOKEN中的函数**boolConcat(){if(token_IndexMAX_TOKEN_SIZE-1)returnfalse;TOKEN[token_Index++]=CHAR;returntrue;}//**判断字符是否为“字母”的函数**boolLetter(){if((CHAR='A'&&CHAR='Z')||(CHAR='a'&&CHAR='z'))returntrue;returnfalse;}//**判断字符是否为“数字”的函数**boolDigit(){if(CHAR='0'&&CHAR='9')returntrue;elsereturnfalse;}//**判断是否为“保留字”的函数**intReserve(){for(inti=0;iREVERSE_SIZE;i++)//查询“保留字”表{if(strcmp(ReserveTable[i],TOKEN)==0)returni+REVERSE_START_ID;}return-1;}//**判断是否为“算符/标点”的函数**intSign(){for(inti=0;iSIGN_SIZE;i++)//查询“算符/标点”表{if(SignTable[i]==CHAR)returni+SIGN_START_ID;}return-1;}//**把CHAR中字符回退到缓冲区的函数**voidRetract(){CHAR=NULL;buffer_Index--;}//*
本文标题:编译原理实验报告1王豪
链接地址:https://www.777doc.com/doc-2068908 .html