数学与计算机学院编译原理实验报告年级09软工学号姓名成绩专业软件工程实验地点主楼指导教师湛燕实验项目算符优先关系算法实验日期2012.6.6一、实验目的和要求设计一个算符优先分析器,理解优先分析方法的原理。
重点和难点:本实验的重点是理解优先分析方法的原理;难点是如何构造算符优先关系。
二、实验内容使用算符优先分析算法分析下面的文法:E’→ #E#E → E+T | TT → T*F | FF → P^F | PP → (E) | i其中i可以看作是一个终结符,无需作词法分析。
具体要求如下:1、如果输入符号串为正确句子,显示分析步骤,包括分析栈中的内容、优先关系、输入符号串的变化情况;2、如果输入符号串不是正确句子,则指示出错位置。
三、程序设计全局变量有一下几个:static string input;//记录输入串char s[20];//栈int top=-1;//栈顶指针有三个函数:int analyze(string input);//分析输入的串是否符合标准void process();//进行归约的函数int main()input是一个全局变量,记录输入串,用analyze(input)分析输入的是不是符合标准的字符串,(例如“i+i*i^(i+i)”)如果不符合标准,提示用户重新输入。
进行归约的函数主要思想是:先构造优先关系矩阵,有“<”,“>”,“=”和空格四种关系。
Char a 记录栈中最高位的终结符,如果栈中是#E+E,则 a 的赋值是“+”,如果形如“#E+”或“#E+i”则a 赋值“+”或“i”。
charnowchar 记录当前的字符。
a 与 nowchar 按照算符优先关系矩阵找出优先关系。
如果优先关系是“<”,则进行移进;如果优先关系是“>”,则进行归约;如果是“=”,则去掉括号或分析成功。
五、代码和截图自己编写代码如下:#include <iostream>#include <string>using namespace std;static string input;//输入串char s[20];//栈int top=-1;//栈顶指针char VT[7]={'+','*','^','i','(',')','#'};//终结符static char matrix[7][7]={'>','<','<','<','<','>','>','>','>','<','<','<','>','>','>','>','<','<','<','>','>','>','>','>',' ',' ','>','>','<','<','<','<','<','=',' ','>','>','>',' ',' ','>','>','<','<','<','<','<',' ','='}; //优先关系矩阵,不存在优先关系时为空格int analyze(string input);//分析输入的串是否符合标准void process();//规约int main(){//cout<<"输入一个符号串!"<<endl;int flag=1;while(flag==1){cout<<"输入一个符号串!"<<endl;cin>>input;if(analyze(input)==0)flag=1;elseflag=0;}cout<<"***********************************************************"<<endl;cout<<" 表达式文法算符优先关系表"<<endl;cout<<endl;for(inti=0;i<8;i++){cout<<" "<<VT[i];}cout<<endl;cout<<endl;for(i=0;i<7;i++){cout<<VT[i];for(int j=0;j<7;j++){cout<<" ";cout<<matrix[i][j];}cout<<endl;}//cout<<<<endl;cout<<"***********************************************************"<< endl;cout<<"对输入串"<<input<<"的算符优先分析过程如下:"<<endl;process();cout<<""<<endl;//cout<<" 栈"<<" 优先关系"<<" 当前符号"<<" 剩余输入串"<<" 移进或规约"<<endl;cout<<""<<endl;cout<<""<<endl;cout<<""<<endl;return 1;}int analyze(string input)//分析输入的串是否符合标准{//cout<<input[0]<<input[1]<<input[2]<<input[3]<<endl;intlen = input.length();//获得输入串长度//cout<<len<<endl;int flag=0;//char t;////char temp;for(inti=0;i<len;i++){if((input[len-1]!='i')&&(input[len-1]!=')')) {flag=1;break;}//cout<<input[len-1]<<endl;switch(input[i]){case '(':if(i==0){}else if(input[i-1]=='^'||'+'||'*'){}elseflag=1;break;case ')':if(input[i-1]=='i'){}elseflag=1;break;case '*':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case '^':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case '+':if(input[i-1]=='i'||')'){}//cout<<i<<flag<<endl;elseflag=1;break;case 'i':{if(input[len-1]=='i')flag=1;else{}}//cout<<i<<flag<<"输入的是正确的字符串!"<<endl;break;default://cout<<flag<<endl;flag=1;break;}}//int flag=0;if(flag==0){cout<<"输入的是正确的句子!"<<endl;return 1;}else{cout<<"输入的是错误的句子!"<<endl;return 0;}}void process()//规约{//cout<<s<<endl;//cout<<top;int row;//列int line;//行s[++top]='#';//input="i+i*(i+i)";//cout<<input<<endl;input=input+'#';////cout<<input<<endl;//char temp;inti=0;int k=0;int g;char a;//char nowchar;//++top;//s[top]=input[i];//cout<<s[top-1]<<endl;//cout<<input[i]<<endl;//cout<<s[top]<<endl;int flag=0;char nowchar;//记录当前字符cout<<endl;cout<<"栈"<<" 优先关系"<<" 当前符号"<<" 剩余输入串"<<" 移进或归约"<<endl;nowchar=input[0];while(flag==0)//s[2]!='#'{ //k++;if(s[top]=='E')a=s[top-1];elsea=s[top];for(int n=0;n<7;n++)//记录行{if(a==VT[n])line=n;}for(n=0;n<7;n++)//记录列{if(nowchar==VT[n])row=n;}char compare;for(int m=0;m<7;m++)for(n=0;n<7;n++){if((line==m)&&(row==n))compare=matrix[m][n];}int j;//i=top;///cout<<"******"<<compare<<"******"<<endl;switch(compare){case '<':{//cout<<" ";for(j=0;j<=top;j++)cout<<s[j];//cout<<"@"<<a;//cout<<line<<row;cout<<"&&&"<<s[top]<<a<<c ompare;//cout<<"(栈)";cout<<" <";cout<<" "<<input[i]<<" ";for(j=strlen(s);j<input.length ();j++)cout<<input[j];cout<<" 移进";//<<10-strlen(s)s[++top]=input[i];//移进if(nowchar=='#'){}elsenowchar=input[strlen(s)-1];//cout<<nowchar;cout<<endl;//cout<<"(剩余输入串)"<<endl;//cout<<endl;i++;break;}case '>'://cout<<" ";for(j=0;j<=top;j++)cout<<s[j];//cout<<"@"<<a;///cout<<"&&&"<<s[top]<<a; cout<<" >";cout<<" "<<input[i]<<" ";//cout<<" ";for(j=strlen(s);j<input.length ();j++)cout<<input[j];//cout<<" "<<endl;cout<<endl;if(s[top]=='E'){top=top-2;s[top]='E';}else if(s[top]==')'){top=top-2;s[top]='E';}elses[top]='E';//归约//cout<<s[top];//if((s[top]=='E')||(s[top]==')'))//i++;if(nowchar=='#'){}elsenowchar=input[strlen(s)-1];cout<<" 归约"<<endl;break;case '=':if(s[top-1]=='('){top=top-1;//a=s[top];s[top]='E';nowchar='#';}//if(s[top-1]=='(')// {//nowchar='#';// }else//cout<<"规约成功"<<endl;{cout<<"#E# 接受"<<endl;flag=1;}break;}//cout<<s[j];}//}如果输入的句子是错误的,提示错误,并要求重新输入。