S语言词法分析程序
- 格式:doc
- 大小:315.00 KB
- 文档页数:20
编译原理课程设计 1 编译原理课程设计 ——S语言词法分析
班别:计算机023班 姓名:范绍森 学号:17号 一、设计任务 本实验的任务是编写一个S语言的词法分析程序,它从左至右逐个字符地对S语言源程序进行扫描,产生一个个的单词符号的机内表示。 在此,将词法分析作为单独的一遍,如下图所示:
源程序词法分析程序token文件
符号表文件具体任务有: 组织源程序的输入。 拼出单词并转换成机内表示形式,形成token文件(单词序列)、符号表文件。 删除注释、空格和无用符号。 发现并定位词法错误。 列表打印错误信息。 二、设计要求 1、能对任何S语言源程序进行分析 为此,在运行词法分析程序时,应用问答方式输入要被扫描的S语言源程序的文件名,然后对该源程序完成词法分析任务。 2、能检查并处理某些词法错误 词法分析程序应给出处理以下三种词法错误(编号分别为1、2、3),其他错误可不必考虑(即认为不会出现): (1)非法字符。处理方式是删去该字符(即不写入token文件)。 (2)不正确的单词,包括以下三种情况: 编译原理课程设计 2 数字开头的数字、字母串,如3a56。 实数中出现二个小数点,如3.14.15。 实数的小数部分出现字母,如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 name[30]; int code; int addr; }token; 说明: label:单词序号; name[30]:单词本身; code:单词的机内码。 addr:地址,单词为保留字时值为—1,为标识符或常数时为大于0的数值,即该标识符或常数在符号表中的入口地址。 (2)符号表文件结构 符号表用于存放S语言源程序中出现的标识符、实常数、整常数,其文件的结构如下: 编译原理课程设计 3 typedef struct symble { int number; int type; char name[30]; }symble; 说明: number:序号; type:类型; name[30]:名字。 四、程序参考结构及模块说明 这里给出一个程序结构的参考方案,设计思路如下: Scanner
IsAlphaIsNumberIsAnotationIsCharIsOther
OutPutError 1、Scanner() 功能:完成初始化,并循环调用子模块完成单词的识别。 算法描述: Void Scanner() { 调用Scanner()进行初始化; 读取源程序的第一个字符; while(字符!=EOF) {if (字符= =字母) IsAlpha(); else if (字符= =数字) IsNumber(); else if (字符= =’/’) IsAnotation(); 编译原理课程设计 4 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; 读下一字符; 编译原理课程设计 5 跳出循环; } } 记单词编码为整数的编码(当前token为整数); if(flag) { if(当前字符为数字) { 记录当前字符; while(当前字符为数字) { 记录字符; 读取下一字符; } 记单词编码为实数的编码(当前token为实数); } else Error(2); if(当前字符为’.’号)过滤掉余下的数字; } if(当前字符为字母)舍去尾部; OutPut(); } 4、IsAnotation() 功能:处理除号和注释。 算法描述: Void IsAnotation() { 读取下一字符; if(当前字符!=*) { 调OutPut()输出除号; } else{读取下一字符; while(当前字符!=*且!=EOF) { 读取下一字符; 编译原理课程设计 6 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() 功能:进行初始化,主要包括: 编译原理课程设计 7 (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 100
typedef struct token {int label; char name[30]; int code; int addr; }token; typedef struct KeyWord {char name[30]; 编译原理课程设计 8 int code; }KeyWord; typedef struct symble {int number; int type; char name[30]; }symble;
char ch; int var_count; int error_count; int label_count; int code_count; int addr_count; int LineOfPro; char filename[30]; FILE*KeyFin; FILE*SourceFin; FILE*TokenFout; FILE*SymbleFout; KeyWord key[LENGTH]; token CurrentToken; symble CurrentSimble; symble SymbleList[N];
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;