您好,欢迎访问三七文档
编译原理实验代码:对于任意给定的文法,判断其是否是算符优先文法。代码如下:#includeiostream#includestdlib.h#includefstream#definerow50#definecol50#defineSIZE50usingnamespacestd;//两个重要结构体的定义//FIRSTVT表或LASTVT表中一个表项(A,a)结构体的初始化typedefstruct{charnonterm;//非终结符charterm;//终结符}StackElement;//存放(A,a)的栈的初始化typedefstruct{StackElement*top;StackElement*bottom;intstacksize;}stack;//初始化(A,a)栈voidInitStack(stack&S){S.bottom=newStackElement[SIZE];if(!S.bottom)cout存储空间分配失败!endl;S.top=S.bottom;S.stacksize=SIZE;}//判断(A,a)栈是否为空boolifEmpty(stackS){if(S.top==S.bottom)returntrue;//如果栈为空,则返回trueelsereturnfalse;//否则不为空,返回false}//插入栈顶(A,a)元素voidInsert(stack&S,StackElemente){if(S.top-S.bottom=S.stacksize)cout栈已满,无法插入!endl;else{S.top-nonterm=e.nonterm;S.top-term=e.term;S.top++;}}//弹出栈顶(A,a)元素StackElementPop(stack&S){StackElemente;e.nonterm='\0';e.term='\0';if(S.top==S.bottom){cout栈为空,无法进行删除操作!endl;returne;}else{S.top--;e.nonterm=S.top-nonterm;e.term=S.top-term;returne;}}//终结符与非终结符的判断函数(布尔类型)boolTerminalJud(charc){if(c='A'&&c='Z')returnfalse;//非终结符返回false//elseif(c='a'&&c='z')returnfalse;elsereturntrue;//终结符返回true}//判断非终结符在first表中是否已存在boolItemJud(charfirst[][col],intfrist_len,charC){for(inti=0;ifrist_len;i++){if(first[i][0]==C)returntrue;//如果first表中已存在此非终结符,则返回true}returnfalse;}//读文件函数intreadfile(charsen[][col]){charaddr[50];cout请输入要读文件的地址(\\用\\\\表示):endl;cinaddr;ifstreamfin;fin.open(addr,ios::in);if(!fin){coutCannotopenfile!\nendl;}inti,mm,l,z,k,j;charD[100][100];for(i=0;!fin.eof();i++){finD[i];coutD[i]endl;}k=0;//coutiiiiiendl;//coutkendl;//for(j=0;ji;j++)//coutD[j]gggendl;for(z=0;zi;z++){mm=0;l=0;for(j=0;j=strlen(D[z]);j++){if(D[z][j]=='|'){sen[k][l]='\0';mm=1;k++;sen[k][0]=D[z][0];sen[k][1]='-';sen[k][2]='';l=3;j++;}if(mm==0){sen[k][l]=D[z][j];l++;}if(mm==1){sen[k][l]=D[z][j];l++;}}k++;}//coutkkkkkkkendl;//for(i=0;ik;i++)//coutsen[i]endl;returnk;}//FIRSTVT表和LASTVT表中表项(非终结符)的初始化voidItemInit(charsen[][col],charfirst[][col],charlast[][col],intsen_len,int&frist_len){inti;frist_len=1;first[0][0]=sen[0][0];last[0][0]=sen[0][0];for(i=1;isen_len;i++){if(TerminalJud(sen[i][0])==false&&ItemJud(first,frist_len,sen[i][0])==false)//k是当前first和last表的长度{first[frist_len][0]=sen[i][0];last[frist_len][0]=sen[i][0];frist_len++;}}}voidFirstVt(charsen[][col],charfirst[][col],intsen_len,intfrist_len)//frist_len是first表的行数sen_len是产生式的个数{StackElementDFS,record[SIZE];//StackElementcharnonterm;//非终结符charterm;//终结符stackOperator;//创建存放(A,a)的栈StackElement*top;StackElement*bottom;intstacksize;InitStack(Operator);inti,j,r=0;for(i=0;isen_len;i++)//第一次扫描,将能直接得出的first(A,a)放进栈中{for(j=3;sen[i][j]!='\0';j++){if(TerminalJud(sen[i][j])==true)//遇到的第一个终结符压入{intexist=0;DFS.nonterm=sen[i][0];DFS.term=sen[i][j];for(inti1=0;ir;i++){if(record[i1].nonterm==sen[i][0]&&record[i1].term==sen[i][j]){exist=1;break;}}record[r].nonterm=sen[i][0];record[r].term=sen[i][j];if(exist==0){Insert(Operator,DFS);//A-aBA-aC(A,a)压栈两次?record[r].nonterm=sen[i][0];record[r].term=sen[i][j];r++;}break;}}}intlocation[col];//辅助数组,用来记录first表中放入终结符的位置for(i=0;ifrist_len;i++)location[i]=1;while(!ifEmpty(Operator)){intexist=0;//标志位,记录即将入栈的元素是否已经存在StackElementIDElement,DElement;DElement=Pop(Operator);//弹出栈顶元素for(i=0;ifrist_len;i++){if(first[i][0]==DElement.nonterm){intn=location[i];first[i][n]=DElement.term;//将终结符填入相应的first表中location[i]++;break;}}for(j=0;jsen_len;j++){if(sen[j][3]==DElement.nonterm)//找出能推出当前非终结符的产生式的左部{IDElement.nonterm=sen[j][0];IDElement.term=DElement.term;//判断将要放进栈里的元素曾经是否出现过,若没有,才压入栈for(intr0=0;r0r;r0++)//r记录record数组中的元素个数{if(record[r0].nonterm==IDElement.nonterm&&record[r0].term==IDElement.term){exist=1;break;}}if(exist==0){Insert(Operator,IDElement);record[r].nonterm=IDElement.nonterm;record[r].term=IDElement.term;r++;}}}}}voidLastVt(charsen[][col],charlast[][col],intsen_len,intfrist_len)//firstvt表与lastvt表行数一样first_len表示last表的行数{inti,j,i1,j1;charc,record[row][col]={'\0'};for(i=0;isen_len;i++){for(j=0;sen[i][j]!='\0';j++){record[i][j]=sen[i][j];}j=j-1;for(i1=3,j1=j;i1j1;i1++,j1--)//做翻转,就可以用求first的方法求last{c=record[i][i1];record[i][i1]=record[i][j1];record[i][j1]=c;}}//forFirstVt(record,last,sen_len,frist_len);}//判断非终结符在term表中是否已存在boolTermTableJud(charterm[col],intterm_len,charC){for(inti=0;iterm_len;i++){if(term[i]==C)returntrue;//如果first表中已存在此非终结符,则返回1}returnfalse;}//构造算符优先关系表boolOpPriotable(charsen[][col],charfirst[][col],charlast[][col],charopTable[][col],intsen_len,intfirst_len,int&opTable_len){inti,j,term_len=0;inti2,i3,opr,opc;charc1,c2,c3;charterm[SIZE]={'\0'};for(i=0;isen_len;i++)//一维数组term记录关系表中存在的所有终结符{for(j=3;sen[i][j]!='\0';j++){if(TerminalJud(sen[i][j])==true)if(TermTableJud(term,term_len,sen[i][j])==false)//term_len记录term表的长度{term[term_len]=sen[i][j];term_len++;}}}//得到终结符表for(i=0;iterm_len+1;i++)//给优先关系表赋初值,都等于空for(j=0;jterm_len+1;j++)opTable[i][j]='';for(i=1;iterm_len+1;i++)//设置优先关系表的表头{opTable[i][0]=term[i-1];opTable[0][i]=term[i-1];}opTable[i][0]='$';opTable[0][i]='$';for(i=0;isen_len;i++)//找等于关系{for(j=4;sen[i][j]!='\0';j+
本文标题:算符优先文法
链接地址:https://www.777doc.com/doc-5407609 .html