《词法分析报告[1].docx》由会员分享,可在线阅读,更多相关《词法分析报告[1].docx(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、编译原理实验报告实验一 词法分析程序的设计与实现指导教师: 姓名: 学号: 班级:一、实验目的基本掌握计算机语言的词法分析程序的开发方法。二、实验内容编制一个能够分析三种整数、标识符、主要运算符和主要关键字的词法分析程序。三、实验要求1根据以下的正规式,编制正规文法,画出状态图;标识符 (|)*十进制整数 0 | (1|2|3|4|5|6|7|8|9) (0|1|2|3|4|5|6|7|8|9)*八进制整数 0 (0|1|2|3|4|5|6|7) (0|1|2|3|4|5|6|7)*十六进制整数 0 (x|X) (0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) (0|1|2|
2、3|4|5|6|7|8|9|a|b|c|d|e|f)*运算符和分隔符 + - * / 0x3f00 while八测试结果九,思考题1. 词法分析能否采用空格来区分单词?答:不能,因为比如abc+bcd中没有空格,但这是三个单词。2. 程序设计中哪些环节影响词法分析的效率?如何提高效率?答:整个程序都由状态转换图而来。由递归方法实现的状态转换图,影响了整个词法分析器的分析效率,可以考虑使用栈来非递归的实现词法分析。十实验心得 通过词法分析程序的实现,我理解了计算机是怎么去识别一个个单词的,或者可以说是各种命令的。这次实验使我对c语言中文件操作更加了解,了解文件指针的运行情况,还了解了编译原理中有
3、限自动机的概念,根据状态图写程序。十一源代码#include using namespace std;#include #define ASG1#define ADD2#define SUB3#define MUL4#define DIV5#define ID6#define IF7#define THEN8#define WHILE9#define DO10#define INT811 /八进制#define INT1012 /十进制#define INT1613#define SLP14/左括号(#define SRP15/右括号)#define SEMI16/分号;#define LP1
4、7/左花括号#define RP18/右花括号#define INC19/+#define DECC20/-#define NEQ21/不等于#define EQ22/等于#define JAE23/大于等于#define JA24/大于#define JBE25/小于等于#define JB26/小于struct wordint kind;int value;int fpoint; /文件字符指针int num_token;/一个单词中的字符数量,主要是数字长度char *token;fstream file;/所要读取的文件word handle_identifier(char *ch)/
5、处理标识符(包括关键字)struct word re;/返回值/关键字/if(strcmp(ch,if)=0) re.kind=IF;re.value=0;return re;if(strcmp(ch,then)=0)re.kind=THEN;re.value=0;return re;if(strcmp(ch,while)=0)re.kind=WHILE;re.value=0;return re;if(strcmp(ch,do)=0)re.kind=DO;re.value=0;return re;/标识符/re.kind=ID; re.value=0;return re;int convert
6、(char ch) /将字符转换成数字int number;switch(ch)case0: number=0;break;case1: number=1;break;case2: number=2;break;case3: number=3;break;case4: number=4;break;case5: number=5;break;case6: number=6;break;case7: number=7;break;case8: number=8;break;case9: number=9;break;caseA: number=10;break;casea: number=10;
7、break;caseB: number=11;break;caseb: number=11;break;caseC: number=12;break;casec: number=12;break;caseD: number=13;break;cased: number=13;break;caseE: number=14;break;casee: number=14;break;caseF: number=15;break;casef: number=15;break;default: number=-1;break;/非法字符转换成-1return number;word handle_num
8、ber(char *ch,int TN)/处理无符号整数int i,j;int number;/对应每一位上转换后的数字int dec=0,oct=0,hex=0;/最终的数值,三种进制word re;/返回值if(TN=1)/一位数,只能是十进制number=convert(ch0);if(number=-1|number9) cout=0)&(number=7) )re.kind=INT8;re.value=number;return re;else cout=2)&(ch0!=0) )/两位位数(含)以上,十进制int *num=new intTN;for(i=0;i9) ) coutE
9、rror!十进制非法; /报错for(i=0;i0;j-)numi*=10;dec+=numi;re.kind=INT10;re.value=dec;return re;else if( (TN=3)&(ch0=0)&(ch1!=x)&(ch1!=X) )/三位数(含)以上,八进制int *num=new intTN-1;for(i=1;i7) ) coutError!八进制非法; /报错for(i=1;i0;j-)numi*=8;oct+=numi;re.kind=INT8;re.value=oct;return re;else if( (TN=3)&(ch0=0)&(ch1=x)|(ch1
10、=X) )/三位数(含)以上,十六进制int *num=new intTN-2;for(i=2;iTN;i+)number=convert(chi);numi=number;if(number=-1) coutError!十六进制非法; /报错for(i=2;i0;j-)numi*=16;hex+=numi;re.kind=INT16;re.value=hex;return re;word scan(char ch)word re;/返回值while(ch= |ch=n) /空格或回车 fpoint+; if(ch=n) fpoint+; / n包括回车和换行所以再加1 (ch); num_t
11、oken=0; /每次要分析一个单词的时候,都要重新对单词中的字符计数tokennum_token=ch;/单词开始的一个字符都放到存放单词的数组中tokennum_token+1=0;num_token+;if(isalpha(ch) /第一个字符是字母的单词是标识符(ch);fpoint+;while(isalnum(ch)&!()/读取标识符的所有字母和数字tokennum_token=ch;tokennum_token+1=0;num_token+;(ch);fpoint+;fpoint-;(fpoint,ios:beg); /后退re=handle_identifier(token)
12、; /处理标识符return re;/返回单词信息(种别和属性值)else if(isdigit(ch)/第一个字符是数字的单词是整数(ch);fpoint+;while(isalnum(ch)&!()/十六进制中包含字母x和X,所以整数单词中不一定只包含数字tokennum_token=ch; tokennum_token+1=0;num_token+;(ch);fpoint+;fpoint-;(fpoint,ios:beg); /后退re=handle_number(token,num_token); return re;elseswitch(ch)case :/赋值符号(ch);fpoi
13、nt+;if(ch =)/以“:”开头的单词只能是赋值符号,否则出错re.kind=ASG;re.value=0;return re;else coutError!赋值出错; /报错break;/各种运算符/case+:(ch);fpoint+;if(ch=+)re.kind=INC;re.value=0;return re;elsefpoint-;(fpoint,ios:beg); /后退re.kind=ADD;re.value=0;return re;break;case-:(ch);fpoint+;if(ch=-)re.kind=DECC;re.value=0;return re;els
14、efpoint-;(fpoint,ios:beg); /后退re.kind=SUB;re.value=0;return re;break;case*:re.kind=MUL;re.value=0;return re ; break;case/:re.kind=DIV;re.value=0;return re; break;case!:/不等号(ch);fpoint+;if(ch=)/以“!”开头的单词只能是不等号,否则出错re.kind=NEQ;re.value=0;return re;else coutError!; /报错break;case=:/等号(ch);fpoint+;if(ch=
15、)/以“=”开头的单词只能是等号,否则出错re.kind=EQ;re.value=0;return re;else cout:(ch);fpoint+;if(ch=)re.kind=JAE;re.value=0;return re;elsefpoint-;(fpoint,ios:beg); /后退re.kind=JA;re.value=0;return re;break;case:(ch);fpoint+;if(ch=)re.kind=JBE;re.value=0;return re;elsefpoint-;(fpoint,ios:beg); /后退re.kind=JB;re.value=0;
16、return re;break;case(:re.kind=SLP;re.value=0;return re; break;case):re.kind=SRP;re.value=0;return re; break;case:re.kind=LP;re.value=0;return re; break;case:re.kind=RP;re.value=0;return re; break;case;:re.kind=SEMI;re.value=0;return re; break;/不是该语言所能识别的单词/default: coutError!; /报错/end switch/主程序/voi
17、d main()char ch;word reword; /接收词法分析程序返回的单词fpoint=0; /记录当前字符的位置,用于回退num_token=0;/记录一个单词中的字符数量token=new char30;/存放每个单词(word.txt);coutn词法程序分析结果:endl;while(1)(ch);fpoint+;if()!=0) break;reword=scan(ch);if(reword.kind!=0)switch(reword.kind) case 1: cout ASG ;break; case 2: cout ADD ;break; case 3: cout
18、SUB ;break; case 4: cout MUL ;break; case 5: cout DIV ;break; case 6: cout ID ;break; case 7: cout IF ;break; case 8: cout THEN ;break; case 9: cout WHILE ;break; case 10: cout DO ;break; case 11: cout INT8 ;break; case 12: cout INT10 ;break; case 13: cout INT16 ;break; case 14: cout SLP ;break; cas
19、e 15: cout SRP ;break; case 16: cout SEMI ;break; case 17: cout LP ;break; case 18: cout RP ;break; case 19: cout INC ;break; case 20: cout DECC ;break; case 21: cout NEQ ;break; case 22: cout DEQ ;break; case 23: cout JAE ;break; case 24: cout JA ;break; case 25: cout JBE ;break; case 26: cout JB ;break; default: cout 非法标识;break;if(reword.kind!=6)if(reword.kind=13|reword.kind=12|reword.kind=11) coutreword.valueendl; /输出数字 else coutendl; /输出无属性elsedocout*token;token+;while(*token!=0); /输出标示符 coutendl;system(pause);第 21 页