您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 词法分析器语法分析器实验报告(编译原理超实用)
山东大学编译技术课程设计班级软件一班学号2008008000XX姓名软件一班万岁指导老师贺老师二零一一年三月一、目的编译技术是理论与实践并重的课程,而其实验课要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。从而巩固和加强对词法分析、语法分析、语义分析、代码生成和报错处理等理论的认识和理解;培养学生对完整系统的独立分析和设计的能力,进一步培养学生的独立编程能力。二、任务及要求基本要求:1.词法分析器产生下述小语言的单词序列这个小语言的所有的单词符号,以及它们的种别编码和内部值如下表:单词符号种别编码助记符内码值DIMIFDOSTOPEND标识符常数(整)=+***,()1234567891011121314$DIM$IF$DO$STOP$END$ID$INT$ASSIGN$PLUS$STAR$POWER$COMMA$LPAR$RPAR------内部字符串标准二进形式------对于这个小语言,有几点重要的限制:首先,所有的关键字(如IF﹑WHILE等)都是“保留字”。所谓的保留字的意思是,用户不得使用它们作为自己定义的标示符。例如,下面的写法是绝对禁止的:IF(5)=x其次,由于把关键字作为保留字,故可以把关键字作为一类特殊标示符来处理。也就是说,对于关键字不专设对应的转换图。但把它们(及其种别编码)预先安排在一张表格中(此表叫作保留字表)。当转换图识别出一个标识符时,就去查对这张表,确定它是否为一个关键字。再次,如果关键字、标识符和常数之间没有确定的运算符或界符作间隔,则必须至少用一个空白符作间隔(此时,空白符不再是完全没有意义的了)。例如,一个条件语句应写为IFi0i=1;而绝对不要写成IFi0i=1;因为对于后者,我们的分析器将无条件地将IFI看成一个标识符。这个小语言的单词符号的状态转换图,如下图:2.语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的算术表达式,其文法如下:E→E+T|E-T|TT→T*F|T/F|FF→P^F|Pp→(E)|i使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。3.中间代码生成器产生上述算术表达式的中间代码(四元式序列)三、实现过程说明给出各题目的详细算法描述,数据结构和函数说明,流程图。1、词法分析器的流程图开始输入源文件路径路径是否有效是初始化文件指针否将字符加入字符数组Word[]是空格,空白或换行吗是字母吗是数字吗否否是界符吗否打开源文件跳过该字符是是文件结束?否将字符加入字符数组Word[]否将字符加入字符数组Word[]是指向下一字符识别指针内容指向下一字符是字母惑数字吗是将word与关键字表key进行匹配否匹配?是输出word为关键字输出word为普通标示符否将字符加入字符数组Word[]指向下一字符输出word为常数识别指针内容回退是数字吗是否输出word为界符指向下一字符结束是输出Word内容为不可识别将字符加入字符数组Word[]2、语法分析器主程序图3、中间代码生成器流程图:四、源程序清单词法分析器#includestdafx.h#includeWord.h//构造函数,对数据成员初始化,并将关键字以及运算符读入Word::Word(){//打开关键字文件fstreamkeywordfile(keyword.txt);if(!keywordfile){couterror!can'topenkeywordfile!endl;system(pause);exit(1);}//设置临时变量将关键字、符号文件中的内容存储stringtempword;inttempencode;stringtempre;inttempvalue;//开始读关键字文件while(!(keywordfile.eof())){keywordfiletempwordtempencodetempretempvalue;keywordlist.push_back(tempword);keywordencode.push_back(tempencode);keywordre.push_back(tempre);keywordcodevalue.push_back(tempvalue);}//关闭关键字文件keywordfile.close();for(inti=0;ikeywordlist.size();i++){coutsetw(16)keywordlist[i]setw(16)keywordencode[i]setw(12)keywordre[i]setw(12)keywordcodevalue[i]endl;}fstreamsignwordfile(signword.txt);if(!signwordfile){couterror!can'topensignwordfile!endl;system(pause);exit(1);}//开始读符号文件while(!(signwordfile.eof())){signwordfiletempwordtempencodetempretempvalue;signlist.push_back(tempword);signencode.push_back(tempencode);signre.push_back(tempre);signcodevalue.push_back(tempvalue);}//关闭符号文件signwordfile.close();for(inti=0;isignlist.size();i++){coutsetw(16)signlist[i]setw(16)signencode[i]setw(12)signre[i]setw(12)signcodevalue[i]endl;}}//将token中的字符串与character中的字符连接作为token中新的字符串voidWord::concatentation(){for(inti=0;i100;i++){if(token[i]==NULL){token[i]=s;break;}}}//判断character中的字符是否为字母和数字的布尔函数,是则返回true,否则返回falseboolWord::letter(){if(s='z'&&s='a')returntrue;elseif(s='Z'&&s='A')returntrue;elsereturnfalse;}boolWord::digit(){if(s='9'&&s='0')returntrue;returnfalse;}//按token数组中的字符串中的前五项(即判别其是否为保留字),若是保留字则返回它的编码intWord::reserve(){intleng;//记录token数组中单词的长度for(inti=0;i100;i++)//计算token数组中单词的长度{if(token[i]==NULL){leng=i;break;}}for(inti=0;ikeywordlist.size();i++){for(intj=0;jkeywordlist[i].length();j++){if(keywordlist[i][j]!=token[j])//若某个字符不等则终止此次循环break;if(j+1==keywordlist[i].length())//若比较字符全部相等,则判断两者是否长度相等{if(leng==keywordlist[i].length()){returni+1;}elsereturn0;}}}return0;}//将标识符登录到符号表中或将常数登录到常数表中voidWord::buildlist(){//设置临时变量将标识符的助记符保存stringtempword;inttempencode;stringtempre;//标识符助记inttempvalue;inttempconstre;//常数助记s=token[0];if(letter())//第一个字符如果为字母,则将标识符登录到符号表中{fstreamchartostring(convert.txt);if(!chartostring){coutError!Can'topenconvertfileendl;system(pause);}for(inti=0;i100;i++){if(token[i]==NULL)break;else{chartostringtoken[i];}}chartostringendl;chartostring.close();chartostring.open(convert.txt);if(!chartostring){coutError!Can'topenconvertfileendl;system(pause);}chartostringtempre;chartostring.close();indentityre.push_back(tempre);tempword=标识符;tempencode=6;tempvalue=indentityre.size();indentitylist.push_back(tempword);indentityencode.push_back(tempencode);indentitycodevalue.push_back(tempvalue);fstreamindentityfile(indentityword.txt);if(!indentityfile){coutError!Can'topenindentitywordfileendl;system(pause);}//先将文件指针移到最后去,再写入一个endlindentityfile.seekg(0,ios::end);indentityfiletempwordsetw(8)tempencodesetw(12)tempresetw(12)tempvalue;indentityfile.seekg(0,ios::end);indentityfileendl;indentityfile.close();}else//token中存储的是常数{//将token中的字符数字转换为int类型fstreamchartoint(convert.txt);if(!chartoint){coutError!Can'topenconvertfileendl;system(pause);}for(inti=0;i100;i++){if(token[i]==NULL)break;else{chartointtoken[i];}}chartointendl;chartoint.close();chartoint.open(convert.txt);if(!chartoint){coutError!Can'topenconvertfileendl;system(pause);exit(1);}chartointtempconstre;chartoint.close();constlist.push_back(tempword);tempword=常数;tempencode=7;tempvalue=indentityre.size();constencode.push_back(tempencode);constre.push_back(tempconstre);constvalue.push_back(tempvalue);fstreamconstdigit(constdigit.txt);if(!constdigit){coutError!Can'topenconstdigitfile!endl;system(pau
本文标题:词法分析器语法分析器实验报告(编译原理超实用)
链接地址:https://www.777doc.com/doc-7382683 .html