华北水利水电学院编译原理实验报告2012~2013学年第一学期2011级计算机科学与技术专业班级:2011179学号:2011179姓名:一、实验题目:语法分析(LR分析程序)(1)选择最有代表性的语法分析方法LR分析法;(2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。二、实验内容(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)(3)给定表达式文法为:G(E’):E’→#E#E→E+T|TT→T*F|FF→(E)|i(4)分析的句子为:(i+i)*i和i+i)*i三、根据以上文法构造出的LR(1)分析表为:+*()I#ETF0S4S51231S6Acc2R2S7R2R23R4R4R4R44S4S58235R6R6R6R66S4S5937S4S5108S6S119R1S7R1R110R3R3R3R311R5R5R5R5四、程序源代usingSystem;usingSystem.Text;usingSystem.IO;namespaceSyntax_Analyzer{classSyntax{StreamReadermyStreamReader;intt;int[]lengh;intl=0;string[]grammar;ints=0;string[]Word;intw=0;int[]wordNum;intn=0;int[,]LR;publicSyntax(){lengh=newint[7];grammar=newstring[7];Word=newstring[100];wordNum=newint[100];LR=newint[30,30];}publicvoidanalyzer(){//读入grammarSyntaxmyTextRead=newSyntax();Console.WriteLine(-----------------------------语法分析开始---------------------------------\n);//***************************//循环读取文法//***************************stringstrStart;strStart=grammar.txt;myTextRead.myStreamReader=newStreamReader(strStart);stringstrBufferStart;intuu=0;do{strBufferStart=myTextRead.myStreamReader.ReadLine();if(strBufferStart==null)break;foreach(StringsubStringinstrBufferStart.Split()){grammar[uu]=subString;//每行文法存入grammar[]uu++;}}while(strBufferStart!=null);myTextRead.myStreamReader.Close();//***************************//循环读取lengh//***************************strStart=lengh.txt;myTextRead.myStreamReader=newStreamReader(strStart);uu=0;do{strBufferStart=myTextRead.myStreamReader.ReadLine();if(strBufferStart==null)break;foreach(StringsubStringinstrBufferStart.Split()){lengh[uu]=Convert.ToInt32(subString);//每行文法存入grammar[]uu++;}}while(strBufferStart!=null);myTextRead.myStreamReader.Close();//****************************//读入文件,进行语法分析////****************************stringstrReadFile;strReadFile=input.txt;myTextRead.myStreamReader=newStreamReader(strReadFile);stringstrBufferText;intwid=0;Console.WriteLine(分析读入程序(记号ID):\n);do{strBufferText=myTextRead.myStreamReader.ReadLine();if(strBufferText==null)break;foreach(StringsubStringinstrBufferText.Split()){if(subString!=){intll;if(subString!=null){ll=subString.Length;//每一个长度}else{break;}inta=ll+1;char[]b=newchar[a];StringReadersr=newStringReader(subString);sr.Read(b,0,ll);//把substring读到char[]数组里intsort=(int)b[0];//word[i]和wordNum[i]对应//先识别出一整个串,再根据开头识别是数字还是字母Word[wid]=subString;if(subString.Equals(+)){wordNum[wid]=0;}else{if(subString.Equals(*)){wordNum[wid]=1;}else{if(subString.Equals(()){wordNum[wid]=2;}else{if(subString.Equals())){wordNum[wid]=3;}else{if(subString.Equals(i)){wordNum[wid]=4;}}}}}Console.Write(subString+(+wordNum[wid]+)+);wid++;}}Console.WriteLine(\n);}while(strBufferText!=null);wordNum[wid]=5;myTextRead.myStreamReader.Close();//*********************************//读入LR分析表////***********************************stringstrLR;strLR=LR-table.txt;myTextRead.myStreamReader=newStreamReader(strLR);stringstrBufferLR;intpp=0;do{strBufferLR=myTextRead.myStreamReader.ReadLine();if(strBufferLR==null)break;else{intj=0;foreach(StringsubStringinstrBufferLR.Split()){if(subString!=null){intlllr=Convert.ToInt16(subString);LR[pp,j]=lllr;//把行与列读入数组j++;}}}pp++;}while(strBufferLR!=null);myTextRead.myStreamReader.Close();int[]state=newint[100];string[]symbol=newstring[100];state[0]=0;symbol[0]=#;intp1=0;intp2=0;Console.WriteLine(\n按文法规则归约顺序如下:\n);//***************//归约算法//***************while(true){intj,k;j=state[p2];k=wordNum[p1];t=LR[j,k];//当出现t为的时候if(t==0){//错误类型stringerror=;if(k==0)error=+;elseif(k==1)error=*;elseif(k==2)error=(;elseif(k==3)error=);elseif(k==4)error=i;elseerror=其它错误!;Console.WriteLine(\n检测结果:);Console.WriteLine(代码中存在语法错误);Console.WriteLine(错误状况:错误状态编号为+j+读头下符号为+error);break;}else{if(t==-100)//-100为达到接受状态{Console.WriteLine(\n);Console.WriteLine(\n检测结果:);Console.WriteLine(代码通过语法检测);break;}if(t0&&t!=-100)//归约{stringm=grammar[-t];Console.Write(m+);//输出开始符intlength=lengh[-t];p2=p2-(length-1);SearchmySearch=newSearch();intright=mySearch.search(m);if(right==0){Console.WriteLine(\n);Console.WriteLine(代码中有语法错误);break;}inta=state[p2-1];intLRresult=LR[a,right];state[p2]=LRresult;symbol[p2]=m;}if(t0){p2=p2+1;state[p2]=t;symbol[p2]=Convert.ToString(wordNum[p1]);p1=p1+1;}}}myTextRead.myStreamReader.Close();Console.WriteLine(-----------------------------语法分析结束---------------------------------\n);Console.Read();}}classSearch{publicintsearch(stringx){string[]mysymbol=newstring[3];mysymbol[0]=E;mysymbol[1]=T;mysymbol[2]=F;intr=0;for(ints=0;s=2;s++){if(mysymbol[s].Equals(x))r=s+6;}returnr;}}}五、测试结果输入”(i+i)*i”字符串,分析如下图所示输入”i+i”字符串,分析如下图所示六、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)本次实验是LR分析法,LR分析法是一种有效的自上而下分析技术,在自左向右扫描输入串时就能发现其中的任何错误。不会的要在书中去寻找;要会运用现代的网络去寻找新知识;要对新知识不断的探索;要有勇于探索与创新的精神。经过这次实验,使我的编程能力得到了很大的锻炼。