实验二(递归下降分析)_第1页
实验二(递归下降分析)_第2页
实验二(递归下降分析)_第3页
实验二(递归下降分析)_第4页
实验二(递归下降分析)_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验二递归下降语法分析实验目的按照语言的语法要求编写文法的规那么转化文法的规那么,使之具有EBCF,消除左递归和左因子掌握编程形式的语法分析器的实现实验内容在TINY计算机语言的编译程序的词法分析局部实现的根底上,采用递归下降的方法实现语法分析,形成语法树。语法分析的输入是记号串,按照从左到右扫描,按照文法规那么的要求,判断语句是否符合文法要求,如果符合要求那么形成语法数,不符合那么指出原因。为了简化程序的编写,对语法有具体如下的要求:只有5中语句if、repeat、read、write、assignment。read只作用一个变量,实现输入。write只作用一个表达式,实现输出。表达式只有两类:布尔表达式,只用于if和repeat语句的测试,算术表达式采用左结合和优先级的方式组成。没有变量的声明,仅仅在赋值时采用隐性的方式说明,只有整型变量;每个语句序列采用‘;’的形式分开,最后一个语句没有分号没有函数或过程实验要求要求实现语法分析程序的以下功能:在实现之前首先实现EBNF,消除左递归和左因子,为递归下降程序做好准备对于语句和表达式采用枚举的形式定义,形成一个统一的树结点结构把正确源程序的首先经过词法分析形成二元式记号提供应语法分析程序如果出现错误,指出错误的位置和类型把语法树按照树的前序遍历的形式把所有的结点按照某种形式输出语法分析进行具体的要求:语法分析的具体功能实现是一个函数TreeNode*parse(),分析记号串,形成一个语法数。编写一个单独的函数parseTree(TreeNode*)遍历整个语法树,把每个结点信息输出程序:头文件:#include<string>usingnamespacestd;enumWordType{WRONG,NUMBER,IDENTIFIER,IF,THEN,ELSE,END,//7REPEAT,UNTIL,READ,WRITE,FALSE,PLUS,SUBTRACT,MULTIPLY,//16DIVIDEY,EQUAL,LESSTHAN,SEMICOLON,FINAL,ASSIGNMENT,S_BRACKET_L,S_BRACKET_R,//24LINE_FEED,SPACE,TAB,BIG_BRACKET_L,BIG_BRACKET_R};//29voidCiFa();voidYufa2();stringIntToStr(intn);//将数字转换成字符串intEqulStr(strings1,strings2);//比拟两个字符串是否相等,相等返回1,否那么返回0源文件:头文件中函数:#include<iostream>#include<string>#include<sstream>#include<stdexcept>#include"head.h"usingnamespacestd;stringIntToStr(intn){ostringstreamresult;result<<n;returnresult.str();}intEqulStr(strings1,strings2){if(s1==s2)return1;elsereturn0;}词法分析:#include<iostream>#include<iomanip>#include<ctype.h>#include<fstream>#include<string>#include"head.h"usingnamespacestd;enumCharType{ALPHABET,OTHER};enumWrongType1{ZERO,ALP_NUM,NUM_ALP,UNLEAGL_S,NO_MATCH,UNKNOW};char*Words[]={"wrong","number","identifier","if","then","else","end",//7"repeat","until","read","write","false","+","-","*",//16"/","=","<",";","$",":=","(",")",//24"\n",""," ","{","}"};//29typedefstruct{char*str;intwordtype;}Two;charArrayChar[100],cbuffer;inti=-1,numline=1,wordtype;stringLineChar;TwoT;ifstreamfp("source.txt",ios::in);ofstreamoutfile("cifa.txt",ios::out);voidCiFa(){ TwoGetToken();if(!fp) cout<<"文件翻开错误!!"<<endl;else { cout<<setiosflags(ios::left)<<setw(6)<<"行数"<<"("; cout<<setiosflags(ios::left)<<setw(10)<<"类别编码"<<","; cout<<setiosflags(ios::left)<<setw(20)<<"字符"<<")"<<endl; fp.get(cbuffer);while(!fp.eof()) { GetToken(); } outfile<<numline<<","<<FINAL<<","; } cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; fp.close(); outfile.close();}intMatch(charstr[],intchartype)//查找匹配的字符{inti;switch(chartype) {caseALPHABET:for(i=IF;i<=FALSE;i++) {if(strcmp(Words[i],str)==0)returni; }caseOTHER:for(i=PLUS;i<=S_BRACKET_R;i++) {if(strcmp(Words[i],str)==0)returni; } }return WRONG;}voidTypeWrong(intwrongtype,intline){switch(wrongtype) {caseZERO:break;caseALP_NUM: cout<<"字母后面不能紧跟数字!";break;caseNUM_ALP: cout<<"数字后面不能紧跟字母!";break;caseUNLEAGL_S: cout<<"非法特殊符号!";break;caseNO_MATCH: cout<<"没有与第"<<line<<"行“{〞匹配的“}〞!";break;default: cout<<"其它类型错误!";break; }}TwoConvertTwo(charstr[],intwordtype,intwrongtype,intnumline,intline)//进行二元转换{ TwoT; T.wordtype=wordtype; T.str=str; cout<<setiosflags(ios::left)<<setw(6)<<numline<<"("; cout<<setiosflags(ios::left)<<setw(10) <<T.wordtype<<","; cout<<setiosflags(ios::left)<<setw(20)<<T.str<<")";if(T.wordtype==WRONG) TypeWrong(wrongtype,line); cout<<endl; outfile<<numline<<","<<T.wordtype<<",";returnT;}voidHandleAlphabet()//首字符为字母时的处理{boolmark=true;while(!fp.eof()&&isalpha(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); }if(isdigit(cbuffer)) { mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\0'; LineChar+=ArrayChar;if(mark) { wordtype=Match(ArrayChar,ALPHABET); T=ConvertTwo(ArrayChar,(IDENTIFIER>wordtype?IDENTIFIER:wordtype),ZERO,numline,numline); }else T=ConvertTwo(ArrayChar,WRONG,ALP_NUM,numline,numline);}voidHandleNumber()//首字符为数字时的处理{boolmark=true;while(!fp.eof()&&isdigit(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); }if(isalpha(cbuffer)) { mark=false;while(!fp.eof()&&(isalpha(cbuffer)||isdigit(cbuffer))) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } } ArrayChar[i+1]='\0'; LineChar+=ArrayChar;if(mark) T=ConvertTwo(ArrayChar,NUMBER,ZERO,numline,numline);else T=ConvertTwo(ArrayChar,WRONG,NUM_ALP,numline,numline);}voidDeleteNote()//删除注释{intrecord=numline;while(!fp.eof()&&cbuffer!='}') { fp.get(cbuffer);while(!fp.eof()&&cbuffer!='}') {if(cbuffer=='\n') { ArrayChar[i+1]='\0'; LineChar+=ArrayChar; cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; LineChar=""; numline++; i=-1; fp.get(cbuffer); } ArrayChar[++i]=cbuffer; fp.get(cbuffer); } ArrayChar[i+1]='\0'; if(cbuffer=='}') { ArrayChar[++i]='}'; ArrayChar[i+1]='\0'; }else { T=ConvertTwo("",WRONG,NO_MATCH,numline,record); } } LineChar+=ArrayChar; fp.get(cbuffer);}voidHandleOther()//字符为特殊字符时的处理{ ArrayChar[++i]=cbuffer;if(ArrayChar[i]=='{')//删除注释 { DeleteNote(); }else//其他字符 { fp.get(cbuffer); ArrayChar[++i]=cbuffer; ArrayChar[i+1]='\0';charTemp1[2]; Temp1[0]=ArrayChar[0]; Temp1[1]='\0';if(!(wordtype=Match(ArrayChar,OTHER)))//当双字符没有匹配的时候,看单字符是否有匹配的 { ArrayChar[i]='\0';if(!wordtype) wordtype=Match(Temp1,OTHER); }else { fp.get(cbuffer);while(!fp.eof()&&cbuffer!='\n'&&cbuffer!=''&&cbuffer!=' '&&!isalpha(cbuffer)&&!isdigit(cbuffer)) { ArrayChar[++i]=cbuffer; fp.get(cbuffer); } ArrayChar[i+1]='\0'; wordtype=Match(ArrayChar,OTHER); } LineChar+=ArrayChar; T=ConvertTwo(ArrayChar,wordtype,(wordtype>0?0:UNLEAGL_S),numline,numline); }}TwoGetToken(){if(cbuffer=='\n')//忽略换行符 { cout<<"第"<<numline<<"行所有字符:"<<LineChar<<endl; numline++; LineChar=""; fp.get(cbuffer); }elseif(cbuffer=='')//忽略空字符 { LineChar+=""; fp.get(cbuffer); }elseif(cbuffer==' ')//忽略制表符 { LineChar+=" "; fp.get(cbuffer); }elseif(isalpha(cbuffer))//判断是否是字母 { HandleAlphabet(); }elseif(isdigit(cbuffer))//判断是否是数字 { HandleNumber(); }else//其他字符 HandleOther(); i=-1;returnT;}语法分析:#include<iostream>#include<iomanip>#include<ctype.h>#include<fstream>#include<string>#include<sstream>#include<stdexcept>#include"head.h"usingnamespacestd;ifstreamfp2("cifa.txt",ios::in);intSPro();//1intSStm();//2intSStms();//3intSSta();//4intSIf();//5intSRep();//6intSAss();//7intSRea();//8intSWri();//9intSExp();//10intSCom();//11intSSim();//12intSSims();//13intSAdd();//14intSTer();//15intSTers();//16intSMul();//17intSFac();//18charlastline[4],line[4],ch2[4];boolOK=true;voidGetWord(char*line,char*ch2){ strcpy_s(lastline,line); fp2.getline(line,3,','); fp2.getline(ch2,3,',');}voidYufa2(){ CiFa(); if(!fp2) cout<<"文件翻开错误!!"<<endl; else { cout<<"文件翻开成功!"<<endl; GetWord(line,ch2); while(!EqulStr(ch2,IntToStr(FINAL))) SPro(); if(OK) cout<<"OK源文件符合该文法!"<<endl; else cout<<"Wrong源文件不符合该文法!"<<endl; } fp2.close();}intSPro()//1{ if(SStm()) return1; //如果此次读入的第一个字符不是开始符号,那么继续读取下一个 cout<<"第"<<lastline<<"行错误!"<<endl; GetWord(line,ch2); OK=false; return0;}intSStm()//2{ if(SSta()) { if(SStms()) return1; else cout<<"第"<<lastline<<"行缺少语句的结束符;!"<<endl; OK=false; return1; } return0;}intSStms()//3{ if(EqulStr(ch2,IntToStr(SEMICOLON))) { GetWord(line,ch2); if(SSta()) { if(SStms()) return1; else cout<<"第"<<lastline<<"行缺少有效的语句!"<<endl; } else cout<<"第"<<lastline<<"行;后面没有有效的语句!"<<endl; OK=false; return1; } elseif(EqulStr(ch2,IntToStr(END))||EqulStr(ch2,IntToStr(ELSE)) ||EqulStr(ch2,IntToStr(UNTIL))||EqulStr(ch2,IntToStr(FINAL))) return1; return0;}intSSta()//4{ if(SIf()||SRep()||SAss()||SRea()||SWri()) return1; return0;}intSIf()//5{ if(EqulStr(ch2,IntToStr(IF))) { GetWord(line,ch2); if(SExp()) { if(EqulStr(ch2,IntToStr(THEN))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(END))) { GetWord(line,ch2); return1; } elseif(EqulStr(ch2,IntToStr(ELSE))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(END))) { GetWord(line,ch2); return1; } else { cout<<"第"<<lastline<<"行缺少语句的结束符end!"<<endl; } } else { cout<<"第"<<lastline<<"行else后面没有有效的语句!"<<endl; } } else { cout<<"第"<<lastline<<"行缺少语句的结束符end!"<<endl; } } else { cout<<"第"<<lastline<<"行缺少关键字else!"<<endl; } } else { cout<<"第"<<lastline<<"行then后面没有有效的语句!"<<endl; } } else cout<<"第"<<lastline<<"行if后面没有有效的表达式!"<<endl; OK=false; return1; } return0;}intSRep()//6{ if(EqulStr(ch2,IntToStr(REPEAT))) { GetWord(line,ch2); if(SStm()) { if(EqulStr(ch2,IntToStr(UNTIL))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行until后面没有有效的表达式!"<<endl; } else { cout<<"第"<<lastline<<"行缺少关键字until!"<<endl; } } else cout<<"第"<<lastline<<"行repeat后面没有有效的语句!"<<endl; OK=false; return1; } return0;}intSAss()//7{ if(EqulStr(ch2,IntToStr(IDENTIFIER))) { GetWord(line,ch2); if(EqulStr(ch2,IntToStr(ASSIGNMENT))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行:=后面没有有效的表达式!"<<endl; } else { cout<<"第"<<lastline<<"行缺少关键字:=!"<<endl; } OK=false; return1; } return0;}intSRea()//8{ if(EqulStr(ch2,IntToStr(READ))) { GetWord(line,ch2); if(EqulStr(ch2,IntToStr(IDENTIFIER))) { GetWord(line,ch2); return1; } else { cout<<"第"<<lastline<<"行read后面没有有效的标识符!"<<endl; } OK=false; return1; } return0;}intSWri()//9{ if(EqulStr(ch2,IntToStr(WRITE))) { GetWord(line,ch2); if(SExp()) return1; else cout<<"第"<<lastline<<"行write后面没有有效的表达式!"<<endl; OK=false; return1; } return0;}intSExp()//10{ if(SSim()) { if(SCom()) { if(SSim()) return1; else cout<<"第"<<lastline<<"行缺少〔或者数字或者标识符!"<<endl; OK=false; } return1; } return0;}intSCom()//11{ if(EqulStr(ch2,IntToStr(LESSTHAN))||EqulStr(ch2,IntToStr(EQUAL))) { GetWord(line,ch2); return1; } return0;}intSSim()//12{ if(STer()) { if(SSims()) return1; else cout<<"第"<<lastline<<"行缺少有效的关键字!"<<endl; OK=false; return1; } return0;}intSSims()//13{ if(SAdd()) { if(STer()) { if(SSims()) return1; else cout<<"第"<<lastline<<"行缺少有效的关键字!"<<endl; } else cout<<"第"<<lastline<<"行缺少〔或者数字或者标识符!"<<endl; OK=false; return1; } else if(EqulStr(ch2,IntToStr(THEN))||EqulStr(ch2,IntToStr(END))||EqulStr(ch2,IntToStr(ELSE)) ||EqulStr(ch2,IntToStr(UNTIL))||EqulStr(ch2,IntToStr(S_BRACKET_R))||EqulStr(ch2,IntToStr(LESSTHAN)) ||EqulStr(ch2,IntToStr(EQUAL))||EqulStr(ch2,IntToStr(FINAL))||EqulStr(ch2,IntToStr(SEMICOLON))) return1; return0;}intSAdd()//14{ if(EqulStr(ch2,IntToStr(PLUS))||EqulStr(ch2,IntToStr(SUBTRACT))) { GetWord(line,ch2); return1; } return0;}intSTer()//15{ if(SFac()) { if(STers()) return1; else cout<<"第"<<lastline<<"行缺少有效的关键字!"<<endl; OK=false; return1; } return0;}intSTers()//16{ if(SMul()) { if(SFac()) { if(STers()) return1; else cout<<"第"<<lastline<<"行缺少有效的表

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论