收藏 分销(赏)

编译原理实验词法分析器的设计和实现.doc

上传人:天**** 文档编号:2954516 上传时间:2024-06-12 格式:DOC 页数:33 大小:446.54KB 下载积分:12 金币
下载 相关 举报
编译原理实验词法分析器的设计和实现.doc_第1页
第1页 / 共33页
编译原理实验词法分析器的设计和实现.doc_第2页
第2页 / 共33页


点击查看更多>>
资源描述
南华大学 计算机科学与技术学院 实 验 报 告 ( ~ 第二学期 ) 课程名称 编译原理 实验名称 词法分析器设计与实现 姓名 学号 专业 班级 地点 教师 1. 实验目及规定 实验目 加深对词法分析器工作过程理解;加强对词法分析办法掌握;可以采用一种编程语言实现简朴词法分析程序;可以使用自己编写分析程序对简朴程序段进行词法分析。 实验规定 1. 对单词构词规则有明拟定义; 2. 编写分析程序可以对的辨认源程序中单词符号; 3. 辨认出单词以<种别码,值>形式保存在符号表中,对的设计和维护符号表; 4. 对于源程序中词法错误,可以做出简朴错误解决,给出简朴错误提示,保证顺利完毕整个源程序词法分析; 2. 实验环节 1.词法分析规则 <标记符>::=<字母>|<标记符><字母>|<标记符><数字> <常数>::=<数字>|<数字序列><数字> <数字序列>::=<数字序列><数字>|<数字>|<.> <字母>::=a|b|c|……|x|y|z <数字>::=0|1|2|3|4|5|6|7|8|9 <运算符>::=<关系运算符>|<算术运算符>|<逻辑运算符>|<位运算符>|<赋值运算符> <算数运算符>::=+|-|*|/|...|-- <关系运算符>::=<|>|!=|>=|<=|== <逻辑运算符>::=&&| || |! <位运算符>::=&| | |! <赋值运算符>::==|+=|-=|/=|*= <分界符>::=,|;|(|)|{|}|:| // |/**/ <保存字>::=main|if|else|while|do|for|...|void 2.单词符号编码 单词符号 种别码 单词符号 种别码 main 0 > 26 if 1 >= 27 else 2 < 28 while 3 <= 29 do 4 ! 30 for 5 != 31 switch 6 = 32 case 7 == 33 int 8 ( 34 double 9 ) 35 float 10 { 36 long 11 } 37 void 12 ; 38 + 13 : 39 += 14 | 40 ++ 15 || 41 - 16 数字 42 -= 17 标记符 43 -- 18 , 44 & 19 // 45 && 20 /**/ 46 # 21 * 22 *= 23 / 24 /= 25 3.状态转换图 2 字母 非字母与数字 1 字母与数字 0 空白 4 数字 非数字 数字 3 8 / 6 11 + 10 = 12 ! 13 = 15 其他 34 18 < 其他 17 19 21 ...... & ; , ( { } , : ) 33 其他 22 20 = 其他 > 16 14 + 其他 7 9 * / = 其他 5 4.算法分析 ①词法分析器工作第一步是输入源程序文本。为了更好地对单词符号辨认,把输入串预解决一下。预解决重要滤掉空格,跳过注释、换行符等。 ②对预解决后输入串依次扫描单个字符,使用if-while嵌套语句和switch case语句判断字符类型,详细辨认办法可看状态转换图。有时为了拟定词性,需要超前扫描,若超前扫描字符对辨认当前单词无用处,则需要退还给输入串,以备辨认下一单词字符时使用。 ③若读入字符与单词符号编码表字符匹配不上,则报错,并输出出错行数。对辨认处单词符号以(单词符号,种别码)二元式形式输出。 3. 实验内容 1. 流程图 2. 程序变量与函数阐明 (1) input 全局字符数组,用来存储输入串 (2) word 全局字符数组,用来存储获取到单词符号,限定长度为8 (3) ch 全局字符变量,用来存储最新读入字符 (4) syn 全局整型变量,表达单词符号编码 (5) p 全局整型变量,表达当前字符在input数组位置 (6) m 全局整型变量,表达最新读入字符在word数组下标 (7) line 全局整型变量,当前行数 (8) keyword 全局字符数组,存储核心字 (9) init() 获取输入串 (10) isKey() 判断核心字函数,若参数数组中是核心字,则把syn置为该核心字相应编码并返回1,否则返回0 (11) isLetter() 判断字母函数,若参数字符是字母,则返回1,否则返回0 (12) isDigit() 判断数字函数,若参数字符是数字,则返回1,否则返回0 (13) isSpace() 判断空白符函数,若参数字符是空格、TAB或换行符,则返回1,否则返回0 (14) scaner() 扫描输入串函数,对读出字符进行判断,若是单词符号表中符号,则将syn置为相应编码 3. 源程序 #include <stdio.h> #include <string.h> char input[1000];//输入串 char word[8];//获取到单词 char ch; int syn;//种别码 int p; int m; int line;//行数 //核心字 char keyword[][8]={"main","if","else","while","do","for","switch","case","int","double","float","long","void"}; void scaner(void); //获取输入串 void init() { int i=0; printf("\n please input a string(end with '#'):\n"); do{ scanf("%c",&ch); input[i++]=ch; }while(ch!='#'); } //判断是不是核心字 int isKey(char *str) { int n; for(n=0;n<13;n++) { if(strcmp(str,keyword[n])==0) { syn=n; return 1; } } return 0; } //判断是不是数字 int isDigit(char c) { if (c>='0'&&c<='9') return 1; else return 0; } //判断是不是字母 int isLetter(char c) { if ((c<='z'&&c>='a')||(c>='A'&&c<='Z')) return 1; else return 0; } int isSpace(char c) { if (c==' '||c=='\t'||c=='\n') { return 1; } return 0; } void main() { init();//输入字符串 line=0; p=0; do{ scaner(); switch(syn) { case -1: printf("you have input a wrong string in line %d\n",line); break; default: printf("( %s,%d )\n",word,syn); break; } }while(syn!=21); } void scaner(void) { //清空word for(m=0;m<8;m++) { word[m] = ' '; } //读取字符 ch=input[p++]; m=0; //当ch为空格或换行符时,继续往下读 while(isSpace(ch)) { if (ch=='\n') { line++; } ch=input[p++]; } //如果以字母开头 if(isLetter(ch)) { //如果往后是字母或数字,把字符存入word中,然后往下继续读 //串长超过8则截断 while((isLetter(ch)||isDigit(ch))&&m<8) { word[m++]=ch; ch=input[p++]; } p--; syn=43; word[m++]='\0'; isKey(word);//判断是不是核心字 } //如果是以数字开头,并且往后是数字 else if(isDigit(ch)) { while((isDigit(ch)||ch=='.')&&m<8) { word[m++]=ch; ch=input[p++]; } //如果数字之后是字母 ,则出错 if (isLetter(ch)) { while(!isSpace(ch)) { ch=input[p++]; } syn=-1; return ; } p--; syn=42; } else { switch(ch) { //比较运算符 case '<': word[m++]=ch; ch=input[p++]; if(ch=='=') { syn=29; word[m++]=ch; } else { syn=28; p--; } break; case '>': word[m++]=ch; ch=input[p++]; if(ch=='=') { syn=27; word[m++]=ch; } else { syn=26; p--; } break; case '!': ch=input[p++]; if(ch=='=') { syn=31; word[m++]=ch; } else { syn=30; p--; } break; case '=': word[m++]=ch; ch=input[p++]; if(ch=='=') { syn=33; word[m++]=ch; } else { syn=32; p--; } break; //算术运算符+、-、*、/ case '+': word[m++]=ch; ch=input[p++]; if(ch=='+') { syn=15; word[m++]=ch; } else if(ch=='=') { syn=14; word[m++]=ch; } else { syn=13; p--; } break; case '-': word[m++]=ch; ch=input[p++]; if(ch=='-') { syn=18; word[m++]=ch; } else if(ch=='=') { syn=17; word[m++]=ch; } else if (isDigit(ch)) { while(isDigit(ch)) { word[m++]=ch; ch=input[p++]; } p--; syn=42; } else { syn=16; p--; } break; case '*': word[m++]=ch; ch=input[p++]; if(ch=='=') { syn=23; word[m++]=ch; } else { syn=22; p--; } break; case '/': word[m++]=ch; ch=input[p++]; if(ch=='=') { syn=25; word[m++]=ch; } //如果是单行注释,则读到换行符为止 else if (ch=='/') { word[m++]=ch; syn=45; while (ch!='\n') { ch=input[p++]; } line++; } //如果是多行注释,则读到匹配*/为止 else if(ch=='*') { word[m++]=ch; syn=46; int flag=1; while (flag) { ch=input[p++]; if (ch=='*') { if (input[p++]=='/') { word[m++]='*'; word[m++]='/'; flag=0; } else { p--; } } if (ch=='\n') { line++; } } } else { syn=24; p--; } break; //界符 case '(': syn=34; word[m++]=ch; break; case ')': syn=35; word[m++]=ch; break; case '{': syn=36; word[m++]=ch; break; case '}': syn=37; word[m++]=ch; break; case ';': syn=38; word[m++]=ch; break; case '#': syn=21; word[m++]=ch; break; case ':': syn=39; word[m++]=ch; break; case ',': syn=44; word[m++]=ch; break; //逻辑运算符 case '&': word[m++]=ch; ch=input[p++]; if(ch=='&') { syn=20; word[m++]=ch; } else { syn=19; p--; } break; case '|': word[m++]=ch; ch=input[p++]; if(ch=='|') { syn=41; word[m++]=ch; } else { syn=40; p--; } break; default: syn=-1; break; } } //字符串结束符 word[m++]='\0'; } 4. 实验成果 由于printf和""不是单词符号表中符号,因而鉴定输入有错 5. 实验总结分析 这个程序实现了对所选词法子集单词辨认,并对辨认出单词以二元式形式输出,对于存在某些词法错误,可以做出简朴错误解决,例如,若标记符以数字开头或单词符号在符号表中不存在,则输出错误信息,并给出行号;同步该程序也能清除掉源程序中注释,辨认出实型常数。固然,由于能力局限性,该程序还存在着某些瑕疵,存在着对以数字开头标记符错误解决不够全面,注释内容不能保存下来、对以\开头字符串辨认不够全面等问题。 在设计和实现算法过程中,我徐徐地弄懂了自己之前不懂知识,理解了状态转换图中状态是如何转换,每个单词是如何辨认出来。综上所述,这次实验加深了我对词法分析原理理解,加深了对词法分析器工作过程结识,使我纯熟掌握了扫描和分析源程序中各类单词办法,对编译原理进一步学习有很大协助。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:4009-655-100  投诉/维权电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服