www.pudn.com > 编译原理LALR(1)文法分析器.zip > GRAMA.cpp
#include#include #include #include "GRAMA.h" CGRAMA::CGRAMA():start_symbol(-5) //构造函数 { char *buf,ch; List buflist; int i=0; ifstream fin("grama.txt",ios::nocreate); //打开文件 if(!fin){ cout<<"file not found!\n"; exit(0); } fin>>vnnum>>vtnum>>gncount; vnstring=new char[vnnum]; vtstring=new char[vtnum]; vn=new int[vnnum]; vt=new int[vtnum]; for(i=0;i >vnstring[i]; vn[i]=-10-5*i; } for(i=0;i >vtstring[i]; vt[i]=10+5*i; } Gener first_gener; //对文法进行拓广 first_gener.vn=start_symbol; //-5是文法开始符号 first_gener.sentence=new int[2]; first_gener.sentence[0]=vn[0]; first_gener.sentence[1]=END; gn_list.Insert(first_gener); fin.get(ch); for(i=0;i temp_list; gener.vn=EncodeVn(*pS); //产生式左部的编码 pS=pS+3; //跳过"->" int length=::GetStrLen(buf)-3; //length为产生式右部的最大长度 gener.sentence=new int[length+1]; //堆内存分配 for(int i=0;i *p=temp_list.first;p;p=p->link) { length=p->data.GetRightLength(); flag=0; for(i=0;i data.sentence[i]==-1) { flag=1; break; } } g1.vn=p->data.vn; if(flag==1) g1.sentence=new int[i+1]; else g1.sentence=new int[length]; for(int j=0;jdata.sentence[j]; g1.sentence[i]=END; gn_list.Insert(g1); if(flag==1){ g2.vn=p->data.vn; g2.sentence=new int[length-i]; for(j=0;j data.sentence[j+i+1]; g2.sentence[length-i-1]=END; temp_list.Insert(g2); } } } int CGRAMA::EncodeVn(char ch) //查找非终结符号表 { for(int i=0;i *p=gn_list.first;p;p=p->link) { gener_len=p->data.GetRightLength(); p->data.GenToItem(item_list,gener_len); } } void CGRAMA::Closure(List &kernel) //CLOSURE(I)函数 { Queue queue,item_q; ListNode *p,*q; CItem item,mid_item; int code,pos; List f_set; for(p=kernel.first;p;p=p->link) { if(p->data.vn==-5) { p->data.string.MakeEmpty(); p->data.string.Insert(5); } queue.QInsert(p->data); item_q.QInsert(p->data); } kernel.MakeEmpty(); while(!queue.QueueEmpty()) { item.string.MakeEmpty(); item=queue.QDelete(); if(item.IsForReduce()) { pos=item.GetDotPos(); f_set.MakeEmpty(); FirstX(item.sentence+pos+2,f_set); for(q=item_list.first;q;q=q->link) { if(q->data.vn==item.sentence[pos+1]&&q->data.sentence[0]==1) { mid_item=q->data; if(f_set.IsEmpty()) mid_item.string.Add(item.string); else mid_item.string.Add(f_set); item.string.MakeEmpty(); code=item_q.GetCode(mid_item); if(code==0){ queue.QInsert(mid_item); item_q.QInsert(mid_item); } else if(!(mid_item.string==item_q.queue[code].string)) item_q.queue[code].Merge(mid_item); } }//end for }//end if } for(int i=1;i<=item_q.rear;i++) kernel.Insert(item_q.queue[i]); } void CGRAMA::FromItoJ(CItem &item,List &J) //由A->a.Br找出 { //形如A->aB.r的式子 int pos=item.GetDotPos(); int temp=item.sentence[pos+1]; for(ListNode *p=item_list.first;p;p=p->link) { if(p->data.vn==item.vn) { int pos1=p->data.GetDotPos(); if(p->data.sentence[pos1-1]==temp&&pos1-pos==1){ if(!p->data.string.IsEmpty()) p->data.string.MakeEmpty(); p->data.string.Add(item.string); J.Insert(p->data); } } } } int CGRAMA::GO(const List &I,int X,List &J) //GO(I,X)函数 { int pos; for(ListNode *p=I.first;p;p=p->link) { pos=p->data.GetDotPos(); if(p->data.sentence[pos+1]==X) FromItoJ(p->data,J); } Closure(J); if(J.IsEmpty()) return 0; return 1; } void CGRAMA::GetSymbol(List &item_set,List &symbol_list) { int pos,temp; symbol_list.MakeEmpty(); for(ListNode *q=item_set.first;q;q=q->link) { pos=q->data.GetDotPos(); temp=q->data.sentence[pos+1]; if(temp!=END) symbol_list.Insert(temp); } symbol_list.DelRepeated(); //必须放到For的外面! } void CGRAMA::OutPut(List &list) { List char_list; char ch; for(ListNode *p=list.first;p;p=p->link) { char_list.MakeEmpty(); ch=Decode(p->data.vn); char_list.Insert(ch); char_list.Insert('-'); char_list.Insert('>'); if(p->data.sentence!=NULL){ for(int i=0;p->data.sentence[i]!=END;i++) { ch=Decode(p->data.sentence[i]); char_list.Insert(ch); } } char_list.Print(); cout<<" \t"; for(ListNode *q=p->data.string.first;q;q=q->link) cout< data)<<" "; cout< > q; //q1是分析中用 List start_set; start_set.Insert(item_list.first->data); Closure(start_set); q.QInsert(start_set); state_queue.QInsert(start_set); List sym_list; List go_list; List temp_list; CItem item; cout<<"********* LALR(1)文法分析程序 *********:\n"; List change_list; while(!q.QueueEmpty()) //用队列来实现 { temp_list.MakeEmpty(); temp_list=q.QDelete(); GetSymbol(temp_list,sym_list); //把求的的 X 存入链表 for(ListNode *p=sym_list.first;p;p=p->link)//对项目集中各个文法符号X用GO(I,X) { if(GO(temp_list,p->data,go_list)) { int code=state_queue.GetCode(go_list); if(code==0) { q.QInsert(go_list); //如果Ix还未出现过则进队列 state_queue.QInsert(go_list); } else{ state_queue.queue[code].MergeString(go_list); change_list.Insert(code); } item.vn=state_queue.GetCode(temp_list); item.sentence=new int[2]; item.sentence[0]=p->data; item.sentence[1]=state_queue.GetCode(go_list); convert_list.Insert(item); //convert_list记录转换关系 go_list.MakeEmpty(); } } } for(int k=1;k *p=sym_list.first;p;p=p->link)//对项目集中各个文法符号X用GO(I,X) { go_list.MakeEmpty(); if(GO(state_queue.queue[k],p->data,go_list)) { int code=state_queue.GetCode(go_list); state_queue.queue[code].MergeString(go_list); } } } } cout<<"\nDFA中所有状态列表:\n[X代表拓广文法开始符号]\n"; for(int i=1;i<=state_queue.rear;i++) //把DFA中所有状态输出 { cout<<"STATE "< *p; int newline=0; cout<<"\n状态间转换关系:\n"; for(p=convert_list.first;p;p=p->link) //打印转换关系 { cout<<"I"< data.vn<<"--- "< data.sentence[0]) <<" --> "<<"I"< data.sentence[1]<<" "<<"\t"; newline++; if(newline%2==0) cout< char_list; char ch; int count=0; for(ListNode *p=item_list.first;p;p=p->link) { if(p->data.IsReduce()) rule_list.Insert(p->data); } ofstream ofstr("rule.txt"); ofstr<<"规则列表:"< link,count++) { char_list.MakeEmpty(); ch=Decode(p->data.vn); char_list.Insert(ch); char_list.Insert('-'); char_list.Insert('>'); for(int i=0;p->data.sentence[i]!=END;i++) { ch=Decode(p->data.sentence[i]); char_list.Insert(ch); } ofstr< *q=char_list.first;q;q=q->link) ofstr< data; ofstr< &first_set) //递归求FIRST集合 { if(symbol>0){ //symbol为终结符的情况 first_set.Insert(symbol); return; } List temp,mid; for(ListNode *p=gn_list.first;p;p=p->link) //先不考虑A->A…的情况 if(p->data.vn==symbol&&p->data.sentence[0]!=symbol) //找到形如A->…的产生式 { if(p->data.sentence[0]>=0){ //A->a…的情况 first_set.Insert(p->data.sentence[0]); continue; }//end if else{ //A->X1…Xn的情况 for(int i=0;p->data.sentence[i]!=END;i++) { temp.MakeEmpty(); First(p->data.sentence[i],temp); mid=temp; if(p->data.sentence[i+1]!=END) mid.Remove(0); first_set.Add(mid); //First(Xi)=>First(symbol) mid.MakeEmpty(); if(temp.Contains(0)) continue; //First(Xi)包含ε则继续求 else break; } }//end else } for(p=gn_list.first;p;p=p->link) { if(p->data.vn==symbol&&p->data.sentence[0]==symbol){ if(first_set.Contains(0)){ FirstX(p->data.sentence+1,mid); first_set.Add(mid); mid.MakeEmpty(); } } } first_set.DelRepeated(); } void CGRAMA::FirstX(int *array,List &first_set) //First(X1…Xn) { first_set.MakeEmpty(); if(*array==END) return; List temp; First(*array,temp); if(!temp.Contains(0)){ first_set.Add(temp); return; } temp.Remove(0); first_set.Add(temp); FirstX(array+1,first_set); first_set.DelRepeated(); } void CGRAMA::PrintTable() //打印分析表 { int i; ListNode *p; ofstream ofstr("table.txt"); ofstr<<"LALR(1)分析表:\n"; for(i=0;i<(vtnum+vnnum+1);i++) ofstr<<"________"; ofstr<<"__"< *pItem; for(i=1;i<=state_queue.count;i++) { ofstr<<"I"<data.IsReduce()&&pItem->data.string.Contains(vt[j])) ofstr<<"r"< data); for(p=convert_list.first;p;p=p->link) if(p->data.sentence[0]==vt[j]&&p->data.vn==i) ofstr<<"s"< data.sentence[1]; ofstr<<" \t"; } if(pItem->data.IsReduce()&&pItem->data.string.Contains(5)) { if(pItem->data.IsAccept()) ofstr<<"acc"; else ofstr<<"r"< data); } ofstr<<"\t"; /************GOTO部分************/ for(j=0;j link) if(p->data.sentence[0]==vn[j]&&p->data.vn==i) ofstr< data.sentence[1];//<<"\t"; ofstr<<"\t"; } ofstr<