www.pudn.com > SLRGrammar.rar > SLRGrammar.cpp
/*********************************************************** Copyright (c) 2004, RM.RYT. All rights reserved. Developed in Microsoft Visual C++ 6.0 Enterprise Edition. ***********************************************************/ #include#include #include #include #include #include ///////////////////////////////////////////////// //定义结点类 template class link { public: link* next; Elem element; int sign; link(const Elem& elementValue,link* nextValue = NULL) { element = elementValue; next = nextValue; sign = -1; } link(link* nextValue = NUll) { next = nextValue; sign = -1; } }; ///////////////////////////////////////////////// //定义堆栈类 template class stack { private: link *top; int size; public: stack(int sz = DefaultSize) { top = NULL; size = 0; } ~stack(){ clear(); } void clear() { while(top!=NULL) { link * temp = top; top = top->next; size = 0; delete temp; } } //入栈函数 bool push(const Elem& item) { top = new link (item,top); size++; return true; } //出栈函数 Elem pop() { Elem item; if (size == 0) return false; item = top->element; link * temp = top->next; delete top; top = temp; size--; return item; } //获取栈顶元素的值 Elem GetTop() const { Elem item; if(size == 0) return false; item = top->element; return item; } //获取堆栈的深度 int length() const { return size; } //判断栈是否为空 bool IsEmpty() const { return top == NULL; } //获取标志位 int GetSign() const { return top->sign; } //设置标志位 void SetSign(int s) { top->sign = s; } }; ////////////////////////////////// //定义产生式的数据结构 class Production { public: char From; char To[20]; }; ////////////////////////////////// //定义输入文法数据结构 class Grammar { private: char startState; Production pro[30]; int NumOfGra; public: Grammar() { NumOfGra = 0; } ~Grammar() { } //定义重载运算符 == bool operator == (Grammar g) { if (g.NumOfGra == NumOfGra) { bool flag=true; Production p; for (int i=0;i pos;i--) { pro[i] = pro[i-1]; } pro[pos].From = fr; strcpy(pro[pos].To,temp); NumOfGra++; return true; } //设置和获取开始状态 bool SetStartState(char ch) { startState = ch; return true; } //获取文法开始状态 char GetstartState() { return startState; } //获取开始的产生式 Production GetStartProduction() { for (int i=0;i pos;i--) { gr[i] = gr[i-1]; } gr[pos] = g; NumOfItems++; return true; } //删除一个项目集 bool Delete(Grammar g) { for (int i=0;i >NumOfGrammar; cout<<"\n 请输入你的文法\n (如S→DE|a|e 终结符用小写,非终结符用大写)"< >rPro; len = strlen(rPro); // 把文法分开保存在文法段中 k = 0; if (i == 0) { gra->SetStartState(lPro); } for (j=0;j Insert(lPro,temp); k = 0; strcpy(temp,"\0"); } else if (j == len-1) { temp[k++] = rPro[j]; temp[k] = '\0'; gra->Insert(lPro,temp); k = 0; strcpy(temp,"\0"); } else { temp[k++] = rPro[j]; temp[k] = '\0'; } } // 获取终结符的数目 for (j=0;j GetstartState(); rstr[1] = '\0'; gra->Insert(0,'G',rstr); gra->SetStartState('G'); NonTeminalSymbol[NumOfNonTeminal] = '\0'; cout<<"\n 你输入的文法是:"; Production pro; for (i=0;i GetNumOfGra()-1;i++) { pro = gra->GetProduction(i); for (j=i+1;j GetNumOfGra();j++) { Production prod= gra->GetProduction(j); if ((pro.From == prod.From)&&(strcmp(pro.To,prod.To)==0)) { gra->Delete(j); break; } } } for (i=0;i GetNumOfGra();i++) { pro = gra->GetProduction(i); cout<<"\n "<GetNumOfGra();i++) { pro = g->GetProduction(i); if (IsInString(tempNon,'Q')) { ch = (char)('Q'+1); } if (pro.From == pro.To[0]) { p = g->GetProduction(g->GetProDuctionOF(pro.From)); strcpy(temp,p.To); tempNon[NumOfNonTeminal] = ch; tempNon[NumOfNonTeminal+1] = '\0'; temp[strlen(pro.To)] = ch; temp[strlen(pro.To)+1] = '\0'; gr->Delete(i); gr->Insert(i,ch,temp); gr->Insert(ch,"e"); for (int i=1;i<(int)strlen(pro.To);i++) { temp[i-1] = pro.To[i]; } temp[i-1] = ch; gr->Insert(ch,temp); } } return gr; } // 把.插入到第a个位置 char * LRParse::InsertIndexOf(char *str, int a) { int i=0; char *temp = new char[20]; for (i=0;iInsert(pro.From,InsertIndexOf(pro.To,i)); } } // 扩展文法 void LRParse::ExGrammar() { int i=0,j=0; Production pro; egra->SetStartState(gra->GetstartState()); for (i=0;i GetNumOfGra();i++) { pro = gra->GetProduction(i); AddDot(pro); } cout<<"\n 扩展后的文法如下:"; for (i=0;i GetNumOfGra();i++) { pro = egra->GetProduction(i); cout<<"\n "<<(i+1<10?" ":"")<GetNumOfGra();j++) { p2 = egra->GetProduction(j); if (p2.From == GetNextOfDot(p1.To)&&(GetPos(p2.To,'.') == 0)) { if (!gr.IsIn(p2)) gr.Insert(p2.From,p2.To); } } } return gr; } // 移动函数 Production LRParse::Shift(Production pro) { Production p; p.From = pro.From; strcpy(p.To,pro.To); int i = GetPos(pro.To,'.'); p.To[i] = pro.To[i+1]; p.To[i+1] = pro.To[i];//即'.' return p; } // goto函数处理 Grammar LRParse::Goto(Grammar g, char ch) { Grammar gr; Production p,temp; for (int i=0;i GetStartProduction(); temp.Insert(p.From,p.To); temp = E_cloure(temp); item->Insert(temp); for (i=0;i GetNumOfItems();i++) { temp = item->GetItem(i); for (j=0;j<(int)strlen(Symbol);j++) { gtemp = Goto(temp,Symbol[j]); if ((!gtemp.IsEmpty())&&(!item->IsIn(gtemp))) { item->Insert(gtemp); } } } } // 项目集的输出 void LRParse::OutputItems() { int i,j; Grammar temp; Production p; cout<<"\n 构造的项目集如下:"; for (i=0;i GetNumOfItems();i++) { temp = item->GetItem(i); cout<<"\n I"<< i <<":"; for (j=0;j GetNumOfGra());j++) { pro = gra->GetProduction(j); if (ch[0] == pro.From) { if (strcmp(pro.To,"e")==0) { temp[len++] = 'e'; temp[len] = '\0'; break; } else { count = strlen(pro.To); for (k=0;k GetstartState()) { temp[len++] = '$'; temp[len] = '\0'; } for (j=0;j<(gra->GetNumOfGra());j++) { pro = gra->GetProduction(j); if (IsInString(pro.To,ch)) { flag = false; for (j=0;pro.To[j]!='\0';j++) { if (ch == pro.To[j]) { flag = true; } if (flag) { count = 0; for (k=j+1;k<(int)strlen(pro.To);k++) { protemp[count++] = pro.To[k]; } protemp[count] = '\0'; if (strlen(protemp)==0) { temp[len++] = 'e'; temp[len] = '\0'; } strcat(temp,First(protemp)); len = strlen(temp); for (k=0;k GetNumOfItems(); pt = new ParseTable(InputSymbol,NonTeminalSymbol,NumOfItems); for (i=0;i GetNumOfItems();i++) { gr = item->GetItem(i); for (j=0;j Add(i,ch,flag,item->GetPos(temp))) { cout<<"\n 语法有冲突,你输入的文法不是SLR文法!"; Error(); } } // 归约动作 else { if (pro.From == item->GetStartProduction().From&&(strcmp(pro.To,Shift(item->GetStartProduction()).To) == 0)) { if (!pt->Add(i,'$','A',0)) { cout<<"\n 语法有冲突,你输入的文法不是SLR文法!"; Error(); } } else { // 用于测试 follow = Follow(pro.From); Production p; p.From = pro.From; for (int d=0;d<(int)strlen(pro.To)-1;d++) { p.To[d] = pro.To[d]; } p.To[d] = '\0'; for (k=0;k<(int)strlen(follow);k++) { if (!pt->Add(i,follow[k],'r',gra->GetPos(p))) { cout<<"\n 语法有冲突,你输入的文法不是SLR文法!"; Error(); } } } } } } // 还原文法 gra = g; } // 字符转化为数字(数字小于10) int LRParse::GetCharDigit(char a) { switch(a) { case '0': return 0; break; case '1': return 1; break; case '2': return 2; break; case '3': return 3; break; case '4': return 4; break; case '5': return 5; break; case '6': return 6; break; case '7': return 7; break; case '8': return 8; break; case '9': return 9; break; default: return -1; break; } } //字符转化为数字 int LRParse::ToDigit(char * a) { int temp=-1; if (strlen(a)<=1) { temp = GetCharDigit(a[0]); } else if (strlen(a)==2) { temp = 10*GetCharDigit(a[0]) + GetDigitChar(a[1]); } else { temp = 100*GetCharDigit(a[0]) + 10*GetDigitChar(a[1])+ GetDigitChar(a[2]); } return temp; } // 数字转化为字符(数字小于10) char LRParse::GetDigitChar(int a) { switch(a) { case 0: return '0'; break; case 1: return '1'; break; case 2: return '2'; break; case 3: return '3'; break; case 4: return '4'; break; case 5: return '5'; break; case 6: return '6'; break; case 7: return '7'; break; case 8: return '8'; break; case 9: return '9'; break; default: return '0'; break; } } // 数字转化为字符 char *LRParse::ToChar(int a) { char *temp = new char[4]; if (a<10) { temp[0] = GetDigitChar(a); temp[1] = '\0'; } else if (a<100) { temp[0] = GetDigitChar((int)(a/10)); temp[1] = GetDigitChar(a%10); temp[2] = '\0'; } else { temp[0] = GetDigitChar((int)(a/100)); temp[1] = GetDigitChar((int)((a%100)/10)); temp[2] = GetDigitChar(a%10); temp[3] = '\0'; } return temp; } // 出错处理函数 void LRParse::Error() { cout<<"\n ━━━━━━━━━┷━━━━━━━━━┷━━━━━━━━━"; cout<<"\n 检测出现错误! 你输入的字符串不是SLR文法。"; cout<<"\n 请按任意键继续......"< * stch = new stack (0); stack * ststate = new stack (0); cout< push(0); stackTemp[len1++] = '0'; stackTemp[len1] = '\0'; flag = false; step=0; i=0; itemCount = 0; while(true) { cout< GetTop(); act = pt->GetAction(itemCount,ip); if (act.ch != '\0') { if (act.ch == 's') { stch->push(ip); ststate->push(act.state); stackTemp[len1++] = ip; stackTemp[len1] = '\0'; if (act.state >= 10) { strcat(stackTemp,ToChar(act.state)); len1 = strlen(stackTemp); } else { stackTemp[len1++] = GetDigitChar(act.state); } stackTemp[len1] = '\0'; itemCount = act.state; i++; cout<<"Shift "; } else if (act.ch == 'r') { pro = gra->GetProduction(act.state); for (j=0;j<(int)strlen(pro.To);j++) { if (ststate->pop()<10) { stackTemp[--len1] = '\0'; } else if (ststate->pop()<100) { stackTemp[--len1] = '\0'; stackTemp[--len1] = '\0'; } else { stackTemp[--len1] = '\0'; stackTemp[--len1] = '\0'; stackTemp[--len1] = '\0'; } stch->pop(); stackTemp[--len1] = '\0'; } int s = ststate->GetTop(); stch->push(pro.From); stackTemp[len1++] = pro.From; stackTemp[len1] = '\0'; int gotos = pt->GetGoto(s,pro.From); if (gotos != -1) { itemCount = gotos; ststate->push(gotos); } else { Error(); break; } strcat(stackTemp,ToChar(gotos)); len1 = strlen(stackTemp); cout<<"Reduce by "< clear(); ststate->clear(); } // 输出分析表 void LRParse::OutputParseTable() { pt->OutPut(); } // 执行主流程序 void LRParse::Run() { char ch; char Sentence[20]; // 输入文法 GetGrammar(); // 输出FIRST 和 Follow集合 OutPutFirstFollow(); // 构造扩展文法 ExGrammar(); // 构造项目集族 FormItems(egra); // 输出项目集族 OutputItems(); // 构造分析表 FormParseTable(); // 输出分析表 OutputParseTable(); // 作出一个表达式在分析表下的动作do do { //输入表达式 cout<<"\n\n 请你输入你要验证的字符串:"; cin >>Sentence; MadeMoves(Sentence); cout<<"\n 是否继续?(Y/N): "<