1《编译原理》综合性实验报告实验学期2016至2017学年第1学期专业计算机科学与技术班级1403学生姓名黄世增学号1411640305任课教师赵曦实验成绩2《编译原理》课程综合性实验报告开课实验室:C2102016年12月6日实验题目词法分析器的设计一、实验目的通过设计、编制、调试一个具体的词法分析程序,实现对高级程序设计语言源程序进行扫描,并将其分解为各种单词的词法分析方法;加深对课堂教学的理解;提高词法分析方法的实践能力。二、实验要求任选一种高级程序设计语言编程完成词法分析器。词法分析器应以教材所述分词原理为依据,使用恰当的数据结构和方法,结构清晰、高效。编制一个读单词过程,源程序保存在文本文件中(也可键盘输入),读取该文件,识别出各个具有独立意义的单词,即关键字、标识符、常数、运算符、分界符五大类。依次输出各个单词的内部单词种别及单词符号自身值,遇到错误时可显示“Eorror”,然后跳过错误部分继续显示。二、实验设备与环境1.硬件:PC机Pentium100以上。2.软件:Win10,VS2010。三、实验内容1.正规文法关键字-int|for|while|do|return|break|continue运算符和界符-|+|-|*|/|==||=|!=||=|,|;|(|)|{|}标识符-letter(letter|digit)*整型常数-digitdigit*2.算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼接出相应的单词符号。2.1主程序3否是图1词法分析主程序示意图其中初始包括关键字、运算符、界限符的置初值。2.2扫描子程序的算法思想:在词法分析中,先以只读方式读取一个文件,自文件头开始扫描文本,滤去开头的空格、回车符、换行符等。读取的字符送入word。扫描第一个字符,看匹配的类型,并进行相应的类型分析,满足判断类型时,输出其种别码和值。置初值调用扫描子程序将结果存入结构体输入串结束结束输出单词二元组4是是否字母数字其他运算符、符号界符等符号否是图2扫描子程序四、实验步骤编写程序时,先定义几个全局变量,key[]事先存放7个关键字,words[]用来存放识别出来的单词二元组,text用来存放从文件读取的内容,word用于存放识别出来的单词,length存放字符个数,k存放识别出来的单词个数。首先,将文本内容读取到text中,文本内容最后一个字符是空白符,然后调用scan方法,逐个扫描每个字符,如果word的第一个字符是字母,则进行拼字符串,再判断是关键字还是标识符;如果word的第一个字符是数字,则在word清空之前判断是否有识别出非数字字符,若有,则出错,若没有,则识别出来的字符串是常数;若word第一个字符是运算符或界限符,则各自存到words[]中。忽略空格text是否扫描结束返回拼数返回(4/5,单词自身值)报错拼字符串是否关键字?(1,单词自身值)(2,单词自身值)(3,单词自身值)5最后扫描结束后输出。五、实验结果及分析六、实验小结和思考通过这次实验,我对词法分析器有了进一步的了解,而且对词法分析和语法分析在实践中的应用有了深入的掌握,让我对高级语言的学习有了更深的认识,了解得更透彻。七、源程序清单6#includestdio.h#includestdlib.h#includestringusingnamespacestd;#defineMAX10000structWordString{stringWord;//单词intcategory;//类别};char*key[7]={int,for,while,do,return,break,continue};//关键字WordStringwords[MAX];//创建一个单词符号串stringtext;//读入的文本存入text中stringword;//分割出的单词用word表示intlength;//字符个数intk;//总单词个数voidscan(){inti,j;k=0;word=;for(i=0;i=length-1;i++){if(word!=){if(((word[0]='A')&&(word[0]='Z'))||((word[0]='a')&&(word[0]='z')))//首字符是字母{if(((text[i]='A')&&(text[i]='Z'))||((text[i]='a')&&(text[i]='z'))||((text[i]=48)&&(text[i]=57))){word+=text[i];}else{words[k].Word=word;for(j=0;j7;j++){if(words[k].Word==key[j]){words[k].category=1;//表示关键字7break;}elseif(j==6)words[k].category=2;//表示标识符}k++;word=;i--;}}elseif(word[0]==','||word[0]==';'||word[0]=='{'||word[0]=='}'||word[0]=='('||word[0]==')')//首字符是界限符{words[k].Word=word;words[k].category=5;//表示界限符k++;word=;i--;}elseif(word[0]=='+'||word[0]=='-'||word[0]=='*'||word[0]=='/'||word[0]=='='||word[0]==''||word[0]==''||word[0]=='!')//首字符是运算符{if(text[i]=='='){word+=text[i];words[k].Word=word;words[k].category=4;//表示运算符k++;word=;}else{words[k].Word=word;words[k].category=4;//表示运算符k++;word=;i--;}}elseif(word[0]=48&&word[0]=57)//首字符是数字{if(text[i]=48&&text[i]=57)8{word+=text[i];}elseif((text[i]='A'&&text[i]='Z')||(text[i]='a'&&text[i]='z')){word+=text[i];words[k].category=6;//表示出错,标识符以数字开头}else{words[k].Word=word;if(words[k].category!=6)words[k].category=3;//表示常数k++;word=;i--;}}}else{if(text[i]!=10&&text[i]!=32&&text[i]!=9){word+=text[i];}}}}intmain(){FILE*fp;//文件指针fp=fopen(text.txt,r);//打开文件if(fp==NULL){printf(Can'topenthisfile!\n);exit(0);}inti=0;while(!feof(fp))//判断是否到文件结尾{text+=fgetc(fp);i++;9}length=i;//text最后一个字符是空字符fclose(fp);//关闭文件scan();for(i=0;ik;i++)//输出{if(words[i].category==6)printf(%sEorror\n,words[i].Word.c_str());elseprintf((%d,%s)\n,words[i].category,words[i].Word.c_str());}getchar();return0;}10开课实验室:C2102016年12月8日实验题目语法分析——LL(1)语法分析方法的实现一、实验目的通过设计、开发一个高级语言的LL(1)语法分析程序,实现对源程序的语法检查和结构分析,加深对相关课堂教学内容(包括自顶向下语法分析、First集、Follow集、Select集、判断LL(1)文法的方法、文法等价变换、LL(1)分析表的构造、对某一输入串的分析过程的理解,提高语法分析方法的实践能力。二、实验要求消除直接左递归前的文法消除直接左递归后的等价文法G[E]:E→E+TG’[E]:E→TE’E→TE’→+TE’|εT→T*FT→FT’T→FT’→*FT’|εF→(E)|iF→(E)|i根据文法建立LL(1)分析表,并对输入串i+i*i进行语法分析,判断其是否是合法的句子,给出句子的分析过程。具体要求如下:1、理解语法分析在编译程序中的作用;2、理解LL(1)语法分析方法对文法的要求(必须是LL(1)文法);3、理解LL(1)分析器模型;4、熟练掌握文法变换方法(消除直接左递归和提取左公共因子)。5、熟练掌握Select集合的求解方法和LL(1)分析表的构造方法;二、实验设备与环境1.硬件:PC机Pentium100以上。2.软件:Win10,VS2010。三、实验内容给定一个上下文无关文法G,在LL(1)语法分析方法中,必须先求出Select集,通过Select集判断是否是LL(1)文法,若是,则构造预测分析表。求出预测分析表之后,键盘输入一个字符串,依据LL(1)分析表单步输出字符串的分析过程。四、实验步骤11NYYNYNNYYYNN五、实验结果及分析输入字符串和初始符号栈符号栈大小大于等于0?待分析字符是否为合法字符?栈顶字符是否为合法字符?待分析字符是否和符号栈栈顶字符相等?对照分析表判断采用产生式待分析字符和栈顶字符同时为“#”产生式右部为空?弹出栈顶符号,产生式右部逆序入栈弹出栈顶符号,不压入栈修改栈大小匹配分析字符分析下一个字符修改栈大小分析成功12六、实验小结和思考本实验加深了我对LL(1)分析法的算法和思想的理解。七、源程序清单#includestring.h#includestdio.h#includestdlib.h#includeconio.h/*1:E-TE'2:E'-+TE'3:E'-ε?4:T-FT'5:T'-*FT'6:T'-ε?7:F-(E)8:F-i*/intll1[5][6]={{1,0,0,1,0,0},{0,2,0,0,3,3},{4,0,0,4,0,0},{0,6,5,0,6,6},{8,0,0,7,0,0}};//表示LL(1)分析表内容intmain(){charch[10]={'#','E'};//用于存放符号栈内容charstr[10];//存放输入串charstr1[10];//用于存放最初输入的字符串charcha;//分析字符inti,j,m,n;//j:终结符所代表数字;m:非终结符所代表数字;n:产生式右部大小13intl=1;//符号栈大小intk=1;//分析输入串的第几个字符inthow;//利用哪个产生式intstep=1;//步骤intlength=0;printf(请输入一串字符串,以#结尾:);do{scanf(%c,&cha);str[length]=cha;str1[length]=cha;length++;}while(cha!='#');printf(步骤\t符号栈\t\t输入串\t\t所用产生式\n);do{cha=str1[k-1];printf(%d\t,step);for(i=0;i=l;i++)printf(%c,ch[i]);//输出符号栈printf(\t\t);for(i=k-1;ilength;i++)printf(%c,str[i]);printf(\t\t);switch(cha){case'i':j=0;break;case'+':j=1;break;case'*':j=2;break;case'('