1、编译原理实验3算符优先分析编译原理 实验 3 算符优先分析一、实验目的通过设计编制调试构造 FIRSTVT 集、 LASTVT集和构造算符优先表、对给定符号串进行分析的程序,了解构造算符优先分析表的步骤, 对文法的要求, 生成算符优先关系表的算法,对给定的符号串进行分析的方法。二、实验内容1.给定一文法 G,输出 G的每个非终结符的 FIRSTVT集和 LASTVT集。2.构造算符优先表。3.对给定的符号串进行分析, 包含符号栈, 符号栈栈顶符号和输入串当前符号的优先级,最左素短语和使用的产生式和采取的动作。三、程序思路在文法框内输入待判断文法产生式,格式E-a|S, 注意左部和右部之间是“
2、- ”,每个产生式一行, ENTER键换行。文法结束再输入一行 G-#E#1.先做文法判断,即可判断文法情况。2.若是算符优先文法,则在优先表栏显示优先表。3.写入要分析的句子,按回车即可。4.在分析过程栏,可以看到整个归约过程情况四、实验结果FunctorFirst.h#include #include #include #include using namespacestd;#definerightlength 20#defineproduct_num 20/产生式最多个数#definenum_noterminal26/非终结符最多个数#definenum_terminal26/终结符最多
3、个数structProductionchar Left;char Right rightlength;intnum;struct VTbool vt num_noterminal num_terminal ;struct Stackchar P;char a;classCMyDlgpublic:CMyDlg();voidInputRule();CStringshowLastVT();CStringshowFirstVT();CStringshownoTerminal(char G);CStringshowTerminal( char g);CStringshowLeftS(charS,intj
4、,intk);voidInitAll();CStringshowSentence( CStringsen,intstart);CStringshowStack(charS,intn);voidInitarry(chararry,intn);CStringProdtoCStr(Productionprod);intselectProd(inti,intj,charS);voidpreFunctor( CString sen);voidinsertFirstVT(StackS,int&sp,char P,char a);voidinsertLastVT(Stack S,int &sp,char P
5、,char a);voidShowPreTable();voidcreatePreTable();char pretablenum_terminal num_terminal ;boollike_Q( Production prod,char Q);voidcreateLastVT();boollikeQ_( Production prod,char Q);boollikeQa_( Production prod);boollike_aQ( Production prod);boollike_a( Production prod);boollikea_( Production prod);bo
6、olDignose( char c);intfindg(charc);intfindG(charc);voidcreateFirstVT();voidcreateTerminal();voidcreatenoTerminal();voidbuildProduction(CStrings);booltest(CString s);voidparse();/语法分析CStringgram;/存放文法;Productionproductionproduct_num ;VT FirstVT;VT LastVT;intlocProduct;/ 已有产生式个数char G num_noterminal ;
7、char g num_terminal ;inti_G;inti_g;CStringm_sen;FunctorFirst.cpp#include FunctorFirst.hCMyDlg:CMyDlg()boolCMyDlg:test(CStrings )/ 测试是否是算符优先文法boolfor (t = 1;int i = 0;i 64 & s i 64 & s i + 1 91)t = 0;break ;returnt;void CMyDlg:InputRule()string infile;string line;cout infile;cout endl;ifstream input(
8、infile.c_str();if ( ! input)cout endl # 打不开文件,请确认输入的路径有效 # endl;cout ! 请再次运行本程序 ! endl endl;exit(0);while (getline(input, line)if (test(line.c_str() = 0)cout endl 这不是算符优先文法! endl;exit(0);buildProduction(line.c_str();cout endl 这是算符优先文法! endl;input.close();voidCMyDlg:buildProduction(CStrings)intintint
9、i = 0;j = 0;k = 0;for(k = 0;k s.GetLength();k+)/ 得到左部if( s k != )productionlocProduct.Left =break ;s k ;for(i = k + 1;i )break ;intfortemp = i;(i = temp + 1;i s .GetLength();i+)if( s i !=|)if( s i != )productionlocProduct.Rightj =j+;productionlocProduct.num = j;s i ;elselocProduct+;productionlocProd
10、uct.Left = productionlocProduct - 1.Left;j = 0;locProduct+;voidCMyDlg:createnoTerminal()/ 建立非终结符索引i_G = 0;/ 最后一个位置的下一个下标int j = 0;for ( inti = 0;i locProduct;i+)for(j = 0;j i_G - 1)Gi_G = productioni.Left;i_G+;voidCMyDlg:createTerminal()/ 建立终结符索引i_g = 0;/ 最后一个位置的下一个下标int j = 0;for ( int i = 0;i locP
11、roduct;i+)for ( int k = 0;k productioni.num;k+)char temp = productioni.Rightk;if (Dignose(temp)for (j = 0;j i_g - 1)gi_g = temp;i_g+;voidCMyDlg:createFirstVT()/ production已完成,创建FirstVTint i, j;Stack S100;int sp = 0;for (i = 0;i i_G;i+)/ 初始化 FirstVTfor (j = 0;j i_g;j+)FirstVT.vtij =false ;for (i = 0;
12、i 0)sp-;char Q = Ssp.P;char a = Ssp.a;for (i = 0;i locProduct;i+)if (likeQ_(productioni, Q)insertFirstVT(S, sp, productioni.Left, a);void CMyDlg:createLastVT() / 创建 Last 集int i, j;Stack S100;int sp = 0;for (i = 0;i i_G;i+) / 初始化 FirstVTfor (j = 0;j i_g;j+)LastVT.vtij = false ;for (i = 0;i 0)sp-;char
13、 Q = Ssp.P;char a = Ssp.a;for (i = 0;i locProduct;i+)if (like_Q(productioni, Q)insertLastVT(S, sp, productioni.Left, a);intCMyDlg:findG(charc)/ 定位 c在G中的下标intfori = 0;(i = 0;i i_G;i+)if ( c = Gi)break ;returni;intCMyDlg:findg(charc)/ 定位 c在g中的下标intfori = 0;(i = 0;i 64 & c a型产生式if(Dignose( returnprod .
14、Right true ;prod .num - 1)elsereturnfalse ;bool CMyDlg:like_aQ(Productionprod )/ 形如 P-aQ型产生式if ( prod .num 1)return false ;elseif (Dignose( prod .Rightprod .num - 2) & (!Dignose(prod .Right prod .num -1)returntrue ;elsereturnfalse ;bool CMyDlg:likeQa_(Productionprod )if ( prod .num 1)return false ;e
15、lseif (Dignose( prod .Right1) & (!Dignose( return true ;prod .Right0)elsereturnfalse ;bool CMyDlg:likeQ_(Productionprod , char Q)if ( prod .Right0 =return true ;Q)elsereturnfalse ;bool CMyDlg:like_Q(Productionprod , char Q)if ( prod .Right prod .num - 1 = return true ;Q)elsereturn false ;void CMyDlg
16、:createPreTable()/ 创建优先表/初始化优先表 pretable int i, j;for (i = 0;i i_g;i+)for (j = 0;j i_g;j+)pretableij = ; / 表错误for (j = 0;j locProduct;j+)for (i = 0;i productionj.num - 1;i+)char xi, xi1, xi2;xi = productionj.Righti;xi1 = productionj.Righti + 1;xi2 = productionj.Righti + 2;if (Dignose(xi) & Dignose(x
17、i1)pretablefindg(xi)findg(xi1) = = ;if (i productionj.num - 2 & Dignose(xi) & Dignose(xi2) &(!Dignose(xi1)pretablefindg(xi)findg(xi2) =if (Dignose(xi) & (!Dignose(xi1)= ;int N = findG(xi1);for ( int k = 0;k i_g;k+)if (FirstVT.vtNk =true )pretablefindg(xi)k = ;if (!Dignose(xi) & Dignose(xi1)int N = f
18、indG(xi);for ( int k = 0;k ;void CMyDlg:ShowPreTable()/显示相关集合和优先表CStringstr = ;str= str+终结符+ showTerminal(g) + rn ;str= str+ 非终结符 + shownoTerminal(G)+ rn ;str= str+First集合: rn+ showFirstVT();str= str+Lasst集合: rn+ showLastVT();str= str+| ;inti, j;for(i = 0;i i_g;i+)str= str+ gi+|;str= str+rn;for(j = 0;j i_g;j+)str= str+ ;str+= rn;for(i = 0;i i_g;i+)str= str+ gi+|;for (j = 0;j
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1