编译原理实验报告——实验三语法分析器1.实验目的熟悉并掌握语法分析器的工作原理和一般设计方法。通过本实验,进一步提高实际问题分析与解决的能力,以及程序设计能力。2.实验要求:(1)简单语言的语法规则如下:①SS→→ii::==EE;;②②SS→→iiffCCtthheennSS③③SS→→wwhhiilleeCCddooSS④④CC→→EEEE⑤⑤CC→→EE==EE以C语言系统为工具,用用递递归归子子程程序序法法设设计计并并实实现现上述简单语言的语法分析器,实现以下功能:对于给定的简单语言的“句子”,经语法分析,能输出分析过程产生的“产生式”序列(或“语法树”)。能调用“词法分析器”识别出简单语言源程序中的一个个单词符号。(2)对如上简单语言设计测试用例,使用“简单语言语法分析器”,对该测试用例进行语法分析,给出测试用例的语法分析结果。3.实验模块(1)词法分析,识别单词符号单词符号的转换图(2)语法分析器能识别由加+减-乘*除/乘方^括号()操作数所组成的算术表达式,其文法如下:①①SS→→ii::==EE;;②②SS→→iiffCCtthheennSS③③SS→→wwhhiilleeCCddooSS④④CC→→EEEE⑤⑤CC→→EE==EE使用的算法可以是:预测分析法;递归下降分析法;算符优先分析法;LR分析法等。(3)中间代码生成器产生上述算术表达式的中间代码(四元式序列)4.实现过程说明语法分析器主程序图5.实验结果截屏测试用例为while(a+15)0doifx2=7theni=z;6.实验总结通过这次实验,我对词法分析器有了进一步的了解,把理论知识应用于实验中。也让我重新熟悉了C和C++语言的相关内容,加深了对C、C++语言知识的深化和用途的理解。通过这次语义分析的实验,我对高级语言的学习有了更深的认识,了解得更透彻。我了解了高级语言转化为目标代码或汇编指令的过程,。对今后的学习将起很大的作用,对以后的编程有很大的帮助.并且通过此次实验,我了解了LR语法分析的实质和过程。实验虽然只是完成了一个简单的程序,并且程序的主要框架课本上有给出,但在组织程序结构和深入了确上学到了很多,加深对编译原理的理解,掌握编译程序的实现方法和技术。巩固了前面所学的知识。7.程序源代码词法分析器#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(pause);exit(1);}//先将文件指针移到最后去,再写入一个endlconstdigit.seekg(0,ios::end);constdigittempwordsetw(8)tempencodesetw(12)tempconstresetw(12)tempvalue;constdigit.seekg(0,ios::end);constdigitendl;constdigit.close();coutsetw(16)tempwordsetw(16)tempencodesetw(12)tempconstresetw(12)tempvalueendl;}}//出现