logo资料库

构造优先表,判断算符优先算法.docx

第1页 / 共16页
第2页 / 共16页
第3页 / 共16页
第4页 / 共16页
第5页 / 共16页
第6页 / 共16页
第7页 / 共16页
第8页 / 共16页
资料共16页,剩余部分请下载后查看
编译原理课程设计 目录 1
程序功能描述----------------------------------3 程序测试用例----------------------------------3 程序的不足与缺陷------------------------------5 源代码----------------------------------------5 一.程序功能描述: 本程序用于判断某种文法是否为算符优先文法,并构造 FIRSTVT 集与 LASTVT 集 和优先表。如果不是算符优先算法,则在优先表中相应位置用“/”表示有多种 2
关系存在。 二.测试用例: 测试用例 1: 例如书本 90 页的文法: (1) E->E+T|T T->T*F|F F->P^F|P P->(E)|i (2) (3) (4) 其中 E,T,F,P 为非终结符,其余为终结符。 测试输入与输出: 输入终结符名:(输入#并输入回车结束) + * ^ i ( )# 输入非终结符名:(输入#并输入回车结束) E T F P# 输入产生式:(第一个符号为左部,其余为右部,每个产生式以回车间隔,输入 #结束,例 如:Xasd Casd#) EE+T ET TT*F TF FP^F FP P(E) Pi# 确认所输入的产生式: E—>E+T E—>T T—>T*F T—>F F—>P^F F—>P 3
* ^ i ( P—>(E) P—>i E 的 FIRSTVT 集: + T 的 FIRSTVT 集: * F 的 FIRSTVT 集: ^ P 的 FIRSTVT 集: i * E 的 LASTVT 集: + ^ T 的 LASTVT 集: * i F 的 LASTVT 集: ^ P 的 LASTVT 集: i ) 此文法为算符优先算法 ( i ( ) i ) ^ i ( ^ i ) 优先表 + > > > > < > * < > > > < > + * ^ i ( ) Press any key to continue < ^ < < < > < > i < < < ( < < < < ) > > > > = > 测试用例 2: 有下列文法: (1)S->bAb (2)A->(B|a (3)B->Aa) 测试输入与输出: 输入终结符名:(输入#并输入回车结束) b a ( )# 输入非终结符名:(输入#并输入回车结束) S A B# 输入产生式:(第一个符号为左部,其余为右部,每个产生式以回车间隔,输入 #结束,例 如:Xasd Casd#) SbAb A(B Aa 4
BAa)# 确认所输入的产生式: S—>bAb A—>(B A—>a B—>Aa) S 的 FIRSTVT 集: b A 的 FIRSTVT 集: a B 的 FIRSTVT 集: a S 的 LASTVT 集: b A 的 LASTVT 集: a B 的 LASTVT 集: ) 此文法不是算符优先算法,优先表中“/”处表示有多个关系 ( ( ( ) b = > > > a < > / > 优先表 ) ( < b a ( ) Press any key to continue 不难证明,在优先表第三行第二列有下划线处,同时有<,>两种关系,所以不是 = < 算符优先算法。 三.程序的缺陷与不足 本程序存在未能将#加入到优先表中,输入方式不太方便,不能把结果保存到文 件中等不足。 四.源代码 #include #include using namespace std; typedef struct { char name; char belong; char FIRSTVT[20]; char LASTVT[20]; int FIRSTVTnum; int LASTVTnum; }character; //每个符号为一个结构体 5
//用于存储存入栈中的结构体 typedef struct { char VTname; char VNname; }combine; typedef struct { combine *base; combine *top; int stacksize; int stacknumber; }SqStack; //以下为栈的基本操作 void InitStack(SqStack &S) { //构件栈的结构体 //创建栈 S.base=(combine *)malloc(20*sizeof(combine)); if(!S.base) exit(0); S.top=S.base; S.stacksize=20; S.stacknumber=0; } int Pop(SqStack &S,combine &e) 并返回 1,若栈空,则返回 0 { if(S.top==S.base) return 0; e=*--S.top; S.stacknumber--; return 1; } //以下为其他函数 6 } void Push(SqStack &S,combine e) { //将 e 压入栈内 if(S.top-S.base>=S.stacksize) { S.base=(combine *)realloc(S.base,(S.stacksize+10*sizeof(combine))); if(!S.base) exit(0); S.top=S.base+S.stacksize; S.stacksize+=10; } *S.top++=e; S.stacknumber++; //若栈不空,删除栈顶元素,用 e 返回其值,
void getloc(char A,character ALLCHAR[2][10],int allterlen,int allunterlen,int *l,int *r) { //寻找 A 所在 ALLCHAR 的位置 int i,j=0; for(i=0;i>ter; i=0; while(ter!='#') { ALLCHAR[0][i].belong='T'; ALLCHAR[0][i].name=ter; ALLCHAR[0][i].FIRSTVTnum=0; ALLCHAR[0][i].LASTVTnum=0; cin>>ter; i++; cout<<"输入非终结符名:(输入#并输入回车结束)"<>unter; j=0; } } } while(unter!='#') { ALLCHAR[1][j].belong='N'; ALLCHAR[1][j].name=unter; ALLCHAR[1][j].FIRSTVTnum=0; ALLCHAR[1][j].LASTVTnum=0; 7
cin.ignore(); cin.get(L); i=0;j=0;k=0; while(L!='#') {if(L=='\n') {j++;genlen[j-1]=i;i=0;cin.get(L);} //若输入回车,记 cin>>unter; j++; } *allterlen=i; *allunterlen=j; for(i=0;i<*allunterlen;i++) for(j=0;j<*allterlen;j++) {F[i][j]=0;F1[i][j]=0;} } //初始化矩阵 F void creatgen(character gen[20][20],int genlen[20],character ALLCHAR[2][10],int allterlen,int allunterlen,int *NUM) { //创建产生式表 int i,j,k,n; int *l,*r; l=&k;r=&n; char L; cout<<"输入产生式:(第一个符号为左部,其余为右部,每个产生式以回车间 隔,输入#结束,例如:Xasd\n Casd#)"<"; } 8
分享到:
收藏