




已阅读5页,还剩15页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
编译原理课程设计编译原理课程设计 S语言词法分析班别:计算机023班 姓名:范绍森 学号:17号一、设计任务本实验的任务是编写一个S语言的词法分析程序,它从左至右逐个字符地对S语言源程序进行扫描,产生一个个的单词符号的机内表示。在此,将词法分析作为单独的一遍,如下图所示:具体任务有:l 组织源程序的输入。l 拼出单词并转换成机内表示形式,形成token文件(单词序列)、符号表文件。l 删除注释、空格和无用符号。l 发现并定位词法错误。l 列表打印错误信息。二、设计要求1、能对任何S语言源程序进行分析为此,在运行词法分析程序时,应用问答方式输入要被扫描的S语言源程序的文件名,然后对该源程序完成词法分析任务。2、能检查并处理某些词法错误词法分析程序应给出处理以下三种词法错误(编号分别为1、2、3),其他错误可不必考虑(即认为不会出现):(1)非法字符。处理方式是删去该字符(即不写入token文件)。(2)不正确的单词,包括以下三种情况:l 数字开头的数字、字母串,如3a56。l 实数中出现二个小数点,如3.14.15。l 实数的小数部分出现字母,如5.26B78。以上三种情况处理方法是:截去后面出错部分,使其成为一个正确单词(即常数)。如:3a56转换成3,3.14.15转换成3.14,5.26B78转换成5.26。(3)源程序文件已结束而注释未结束(即程序最后的注释没有结束符*/)。三、程序数据结构1、输入S语言源程序,为文本文件。2、输出词法分析程序的运行结果是:产生一个单词序列文件(即token文件)和一个符号表文件,并输出错误信息。(1)token文件结构token文件用于存放从S语言源程序中扫描出来的一个个单词符号的机内表示,其文件结构如下: typedef struct token int label; char name30; int code; int addr; token;说明:l label:单词序号;l name30:单词本身;l code:单词的机内码。l addr:地址,单词为保留字时值为1,为标识符或常数时为大于0的数值,即该标识符或常数在符号表中的入口地址。(2)符号表文件结构符号表用于存放S语言源程序中出现的标识符、实常数、整常数,其文件的结构如下: typedef struct symble int number; int type; char name30; symble; 说明:l number:序号;l type:类型;l name30:名字。四、程序参考结构及模块说明这里给出一个程序结构的参考方案,设计思路如下:1、Scanner()功能:完成初始化,并循环调用子模块完成单词的识别。算法描述:Void Scanner() 调用Scanner()进行初始化; 读取源程序的第一个字符; while(字符!=EOF) if (字符= =字母) IsAlpha(); else if (字符= =数字) IsNumber(); else if (字符= =/) IsAnotation(); else if (字符= =) IsChar(); else IsOther();打印结束信息;结束操作;2、IsAlpha()功能:识别保留字和标识符。算法描述:Void IsAlpha() 1、while(字符为字母或数字或_号) 记录当前字符; 读取下一个字符; 2、判断所记字符串是否为保留字并置标志符h /*为保留字,则标志符h=1;否则为标识符h=0*/ 3、调OutPut()输出保留字或标识符; 3、IsNumber()功能:识别整数和实数。算法描述:Void IsNumber() int flag=0; while(字符为数字) 记录当前字符; 读取下一字符; if(字符为.号) 记录当前字符 flag=1; 读下一字符; 跳出循环; 记单词编码为整数的编码(当前token为整数);if(flag) if(当前字符为数字) 记录当前字符; while(当前字符为数字) 记录字符; 读取下一字符; 记单词编码为实数的编码(当前token为实数); else Error(2); if(当前字符为.号)过滤掉余下的数字; if(当前字符为字母)舍去尾部;OutPut();4、IsAnotation()功能:处理除号和注释。算法描述:Void IsAnotation() 读取下一字符; if(当前字符!=*) 调OutPut()输出除号; else读取下一字符; while(当前字符!=*且!=EOF) 读取下一字符; if(当前字符= =/)跳出循环; 5、IsChar()功能:识别字符串。算法描述:Void IsChar()for(;) 读取下一字符; 现行token为字符串; if(当前字符!=号) 记录字符; else break;OutPut();读取下一字符;6、IsOther()功能:识别其他单词。算法描述:Void IsOther()switch(当前字符) 对于各个不同符号作出不同的处理,主要有:1、 符号内容的记取;2、 查出机内码;3、 调OutPut()输出至token文件;4、 读取下一符号;5、 对于错误符号要将其删除,并报错。7、 ScannerInit()功能:进行初始化,主要包括:(1)建立单词编码表、token表、符号表、并将它们清空。(2)打开单词编码文件,并将单词编码读到编码表中。注:单词编码预先存在一个文本文件中。8、OutPut()功能:输出识别出的单词,包括:(1)将单词写入token表。(2)若单词为标识符或常数再查、填符号表。9、Error()功能:出错处理。算法描述:Void Error(int a) 错误记数器加1; switch(a) case1:非法字符,屏幕显示1号错误信息; case2:常数出错,屏幕显示2号错误信息; case3:没有匹配的注释符*/,屏幕显示3号错误信息; default:break; 五、源程序#include#include#include#define LENGTH 61#define N 100typedef struct token int label; char name30; int code; int addr;token;typedef struct KeyWordchar name30; int code;KeyWord;typedef struct symbleint number; int type; char name30;symble;char ch;int var_count;int error_count;int label_count;int code_count;int addr_count;int LineOfPro;char filename30;FILE*KeyFin;FILE*SourceFin;FILE*TokenFout;FILE*SymbleFout;KeyWord keyLENGTH;token CurrentToken;symble CurrentSimble;symble SymbleListN;void Scanner();void ScannerInit();void IsAlpha();void IsNumber();void IsAnotation();void IsChar();void IsOther();void OutPut();void Error(int a);int WordHave();int strcmp(char *s,char *t) /*比较函数*/ for(;*s=*t;s+,t+) if(*s=0)return 0; return 1;int main() int i=0,j=0; code_count=0; LineOfPro=0; var_count=0; addr_count=1; label_count=1; for(i=0;iN;i+) SymbleListi.number=0; SymbleListi.type=0; for(j=0;j30;j+)SymbleLj=0; Scanner(); return 0;/*主程序*/void Scanner()int i=0;error_count=0;ScannerInit();printf( *n);printf( *S语言词法分析器n); printf( *n);printf(输入源文件名:);for(;)scanf(%c,&filenamei); if(filenamei=10)break;i+;filenamei=0;if(SourceFin=fopen(filename,rt)=NULL)printf(无法打开文件 %s.n,filename);exit(1);if(TokenFout=fopen(token.txt,wt+)=NULL)printf(无法打开文件 token.txt.n);exit(1); if(SymbleFout=fopen(symble.txt,wt+)=NULL)printf(无法打开文件 symble.txt.n);exit(1);ch=fgetc(SourceFin); /*读取第一个字符*/while(ch!=EOF) /*循环处理字符串*/for(i=0;i47)&(ch64)&(ch96)&(ch123)|ch=_)IsAlpha();elseif(ch=/)IsAnotation();else if(ch=)IsChar();else IsOther();fclose(SourceFin);fclose(TokenFout);fclose(SymbleFout);printf(分析完毕.n);/*初始化*/void ScannerInit()int i=1;int k=0;if(KeyFin=fopen(ni.txt,rt)=NULL)printf(cannot open ni.txt.n);exit(1);for(i=0;i60;i+)for(k=0;k30;k+)k=0;for(i=1;i47)&(ch47)&(ch147)&(ch58) CurrentTk+=ch; ch=fgetc(SourceFin); CurrentToken.code=29;if(ch=.)Error(2);ch=fgetc(SourceFin);while(ch47)&(ch64)&(ch96)&(ch64)&(ch96)&(ch47)&(ch64)&(ch96)&(ch123)|ch=_)CurrentTi+=ch;ch=fgetc(SourceFin);for(i=1;iLENGTH;i+) /*判断输入字符是否为保留字*/h=strcmp(CurrentT,);if(!h)break;if(!h)CurrentToken.code=keyi.code;CurrentToken.addr=-1;elseCurrentToken.code=27; CurrentToken.addr=addr_count+;CurrentToken.label=label_count+;OutPut();/* 注释处理*/void IsAnotation()char ch1;ch1=ch;ch=fgetc(SourceFin);if(ch=*)for(;)ch=fgetc(SourceFin);if(ch=EOF)Error(3);break;if(ch=*)ch1=ch;ch=fgetc(SourceFin);if(ch=/)ch=fgetc(SourceFin);break;elseCurrentT0=/;CurrentToken.code=39; CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();/*字符串处理*/void IsChar()int i=0;for(;)ch=fgetc(SourceFin);CurrentToken.code=30;if(ch!=)CurrentTi+=ch;else break;CurrentToken.addr=addr_count+;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);/*其他情况的处理*/void IsOther()char ch1;int i;for(i=0;i30;i+)CurrentTi=0;switch(ch)case(:CurrentT0=); CurrentToken.code=32;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break; case):CurrentT0=); CurrentToken.code=33;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break; case*:CurrentT0=*; CurrentToken.code=34;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case+:CurrentT0=+; CurrentToken.code=35;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case,:CurrentT0=,; CurrentToken.code=37;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case-:CurrentT0=-; CurrentToken.code=36;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break;case.:CurrentT0=.; CurrentToken.code=38;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break; case:ch1=ch; ch=fgetc(SourceFin);if(ch!=) CurrentT0=:; CurrentToken.code=40;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut(); elseCurrentT0=:; CurrentT1=; CurrentToken.code=41; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut(); ch=fgetc(SourceFin);break;case;:CurrentT0=; CurrentToken.code=42;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch=fgetc(SourceFin);break; case:ch1=fgetc(SourceFin);if(ch1=) CurrentT0=) CurrentT0=; CurrentToken.code=45; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut(); ch1=fgetc(SourceFin);else CurrentT0=:ch1=fgetc(SourceFin); if(ch1=) CurrentT0=;CurrentT1=; CurrentToken.code=48;CurrentToken.addr=-1;CurrentToken.label=label_count+;OutPut();ch1=fgetc(SourceFin);else CurrentT0=; CurrentToken.code=47; CurrentToken.addr=-1; CurrentToken.label=label_count+; OutPut();ch=ch1;break; case 10:LineOfPro+; ch=fgetc(SourceFin);break;case 13:LineOfPro+; ch=fgetc(SourceFin);break;case :ch=fgetc(SourceFin); break;case EOF:Error(4);break; default:Error(1); ch=fgetc(SourceFin);break;/*输出模块*/void OutPut()int flag,i=0;int k;/*查填符号表*/if(CurrentToken.code=27)|(CurrentToken.code=30)|(CurrentToken.code=28)|(CurrentToken.code=29)CurrentSimble.number=CurrentToken.addr; CurrentSimble.type=CurrentToken.code;strcpy(CurrentS,CurrentT);flag=WordHave();if(CurrentToken.code=27)&(flag=1)|(CurrentToken.code=30)|(CurrentToken.code=28)|(CurrentToken.code=29)fprintf(SymbleFout,%3d %3d %sn,CurrentSimble.number,CurrentSimble.type,CurrentS);/*输出到token表*/for(;)if(CurrentTi+=0)break; fprintf(SymbleFout,%3d %s,CurrentToken.label,CurrentT); printf(%3d %s,CurrentToken.label,CurrentT); for(k=20-i;k0;k-) fprintf(TokenFout, ); printf( );fprintf(TokenFout,%3d %3dn,CurrentToken.code,CurrentToken.addr);printf(%3d %3dn,CurrentToken.code,CurrentToken.addr);void Error(int a)error_count+;switch(a)case 1:printf(error %2d 非法字符于 %3d 行.n, error_count,LineOfPro+1);break;case 2:printf(error %2d 实常数出错于 %3d 行.n, error_count,LineOfPro+1);break;case 3:printf(error %2d 没有匹配的注释符 */n,error_count);break;case 4:printf(error %2d 非正常结束!n,error_count);break;default:break;return;int WordHave()int flag,i=0;for(i=0;ivar_count;i+)flag=strcmp(CurrentS,SymbleL);if(flag=0)CurrentToken.addr=SymbleListi.number;return 0;SymbleListvar_count.number=CurrentToken.addr;SymbleListvar_count.type=CurrentToken.code;strcpy(SymbleListvar_,CurrentToken.n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 财务管理资金运作分析试题及答案在2025年
- 2025年儿童青少年心理健康考试题及答案
- 海安融信面试题库及答案
- 基础医学知识试题库
- 知识经济与公共政策关系试题及答案
- 软件设计师考试反馈与试题及答案总结
- 软考网络工程师试题及答案全媒体传播2025年
- 机电工程2025年成功案例试题及答案
- 前端与后端结合的2025年软件设计师试题及答案
- 网络工程师复习计划及试题及答案
- 房产抵押合同模板格式
- 第18课《中国人失掉自信力了吗》课件-2024-2025学年统编版语文九年级上册
- 人教版中考物理一轮大单元复习第二单元声现象【中考演练】(原卷版+解析)
- 深圳小孩上学租房合同
- 接地电阻、绝缘电阻和漏电保护器漏电动作参数测定记录表
- 2024-2025学年高中物理1.1质点参考系教学设计新人教版必修第一册
- 高原湿地- 三江源地区说课课件-2023-2024学年人教版地理八年级下册
- SH/T 3046-2024 石油化工立式圆筒形钢制焊接储罐设计规范(正式版)
- (高清版)JTGT D31-06-2017 季节性冻土地区公路设计与施工技术规范
- 机房搬迁服务搬迁实施方案
- DLT电力建设施工及验收技术规范锅炉机组篇
评论
0/150
提交评论