LR (1) Grammar analyzer//c++ implementation

Source: Internet
Author: User
Tags closure

1, first read into the Terminator, non-Terminator, and all production type.




2, pre-processing: initialization; GETPP () obtains the number of each non-terminator on the left of the production type,
Recorded in string getp[] (can be multiple).


3. Get the first set of all the symbols: DFS, starting from S DFS, encountering Terminator is a recursive exit, back-to-back time to save records on the entire path of VN first, (encountered with left recursion, continue, left recursive production without affecting the fisrt set)


4: Get Project Set family: an LR (1) project with a structure record, get_close (Project T): BFS to complete the closure of T. Getxmjizu (): BFS, with a chain-forward star record chart.


5. Get the Analysis table table[][]: Traverse for all sides of the graph, the state i->j has the right to the side of W, the Action (i,w) =j;go, the essence is the same. Next scan all items, for the attribution of the project, the imputation


6 Master Control Program: Two stacks: the status stack and the symbol stack, nothing more than move in, return to, accept save.

Test:

A b
H S B
H->s
B->ab
S->bb
B->b
End


I * () +
E T F
E->e+t
E->t
T->t*f
T->f
F-> (E)
F->i
End


A B c D
S A B
S->a
A->b|cad
B->abb|ab
End


#include <iostream> #include <string> #include <map> #include <vector> #include <stack># include<set> #include <cstring> #include <queue>using namespace Std;map<char,int>getnum;char          GETCHAR[100];        Get the corresponding character vector<string>proce;         generated int table[30][30];        Pre-measured analysis table -1int tb_s_r[30][30];   is to move the input or the statute item, -1,-2.int Num=0;int numvt=0; NUMVT is the Terminator collection, 0 is ' # ', numvt empty word void readin ()//read into VT,VN, number 1-num, read in all production {memset (table,-1,sizeof (tabl    e));    getnum[' # ']=0;    getchar[0]= ' # ';    cout<< "Please enter Terminator set:" <<endl;    char x;      do {cin>>x;      Getnum[x]=++num;    Getchar[num]=x;     }while (Cin.peek ()! = ' \ n ');     Numvt=++num;        getnum[' @ ']=numvt;    Kong Zi getchar[num]= (' @ ');    cout<< "Please enter non-terminator set:" <<endl;      do {cin>>x;      Getnum[x]=++num;    Getchar[num]=x;    }while (Cin.peek ()! = ' \ n ');    cout<< "Input all production (empty word with ' @ '), end With ' End ':" <<endl; STring Pro;         while (cin>>pro&&pro!= "end") {string ss;         SS+=PRO[0];             for (int i=3;i<pro.size (); i++) {if (pro[i]== ' | ')                  {Proce.push_back (ss);             Ss.clear (); ss+=pro[0];             } else {ss+=pro[i];    }} proce.push_back (ss);       }}struct XIANGMU//a project {int nump;        The resulting type number int id;   . The position of string fst;   Set};string getp[100];        Get a terminator on the left of the production set void Getpp () {for (int i=0;i<proce.size (); i++) {int temp=getnum[proce[i][0]];    Getp[temp]+=char (' 0 ' +i);   }}string first[100]; First set of each symbol bool GOTFIRST[100];  has finished first collection void Dfsgetfirst (int nv,int nump)//current symbol, and corresponding production number {int temp=getnum[proce[nump][1]];               The first character of the production comes out gotfirst[nump]=1;  Mark if (TEMP&LT;=NUMVT) First[nv]+=char (' 0 ' +temp); is terminator else {for (int i=0;i<getp[temp].size (); i++)//All temp can be introduced to the symbol corresponding to the production {if (proce[nump][0]==proce[nump][1]) continue;//The production of left recursion does not affect the fisrt set          Dfsgetfirst (temp,getp[temp][i]-' 0 ');                  } First[nv]+=first[temp];    The}}void Get_first () {for (int i=1;i<=numvt;i++)//Terminator first collection is its own when backtracking.    {First[i]=char (' 0 ' +i); } for (int i=0;i<proce.size (); i++) {if (proce[i][0]==proce[i][1]) continue;///left recursive production without affecting the fisrt set if              (Gotfirst[i]) continue; has been generated.

int temp=getnum[proce[i][0]]; Dfsgetfirst (Temp,i); }}vector<vector<xiangmu> >v; Project set family int e[100][3]; int Head[100];int nume=0; Chain forward star project set family diagram void Addegde (int from,int to,int W)//join Edge {e[nume][0]=to;e[nume][1]=head[from];head[from]=nume; E[nume++][2]=w;} void clear ()//initialization function {for (int i=0;i<100;i++) head[i]=-1; for (int i=0;i<30;i++) for (int j=0;j<30;j++) tb_s_r[i][j]=table[i][j]=-1; nume=0;} inline bool Xmeq (XIANGMU A,xiangmu b) {if (a.fst==b.fst&&a.id==b.id&&a.nump==b.nump) return 1; return 0;} BOOL Isin (XIANGMU a,vector<xiangmu> b)//xm A is in Xmji b{for (int i=0;i<b.size (); i++) {if (XM EQ (A,b[i])) return 1; } return 0;} Vector<xiangmu> hebing (Vector<xiangmu>a, vector<xiangmu>b)//merge project set, B to a{for (int i=0;i<b.siz E (); i++) {if (Isin (b[i],a)) continue; else A.push_back (B[i]); } return A; BOOL Xmjieq (vector<xiangmu> a,vector<xiangmu> B)//Two set of items are equal {if (A.size ()!=b.size ()) return 0; for (int i=0;i<a.size (); i++) {if (!isin (a[i],b)) return 0; } return 1;} int Xmji_isin_xmjizu (vector<xiangmu>a,vector<vector<xiangmu> >b)//Find item set, if any, then return number, one at a stroke {for (int i =0;i<b.size (); i++) {if (Xmjieq (A,b[i])) return i; } return-1;} Vector<xiangmu> get_close (Xiangmu t)//to project T as closure {vector<xiangmu> temp; Temp.push_back (t); Queue<xiangmu> Q; BFS Complete closure Q.push (t); while (!q.empty ()) {Xiangmu cur=q.front (); Q.pop (); if (Cur.id==proce[cur.nump].size ())//return to the continue; int tt=getnum[proce[cur.nump][cur.id]]; TT is tHM num of '. ' Zhihoudefuhao if (TT&LT;=NUMVT) continue; If Terminator, you do not need to find the for (int i=0;i<getp[tt].size (); i++)//The corresponding production of the number {XIANGMU C; c.id=1; c.nump=getp[tt][i]-' 0 '; if (Proce[cur.nump].size ()-cur.id==1)//The LAST:A-&GT;BC. D,a/b c.fst+=cur.fst; Else//not the last:a->b.cfb,a/b {int tttnum=getnum[proce[cur.nump][cur.id +1]]; C.fst+=first[tttnum]; } if (!isin (c,temp))//row weight, the new project is added. {Q.push (c); Temp.push_back (c); }}} return temp;} void Get_xiangmujizu ()//Get project set family {vector<xiangmu>temp; Xiangmu T; t.nump=0;t.id=1;t.fst+= ' 0 '; Initial set of items: 0 temp=get_close (t); Queue<vector<xiangmu> >q; BFs method obtained Q.push (temp); V.push_back (temp); First in while (!q.empty ()) {vector<xiangmu> cur=q.front (); Q.pop (); for (int i=1;i<=num;i++)//All symbols {if (I==NUMVT) continue; ‘#‘ Vector<xiangmu> temp; for (int j=0;j<cur.size (); j + +)//All items in the project set {if (Cur[j].id==proce[cur[j].nump].size ()) C Ontinue; is the statute item. Can no longer read into int tt=getnum[proce[cur[j].nump][cur[j].id]]; if (tt==i)//can read in sign I {XIANGMU tempt; TEMPT.FST=CUR[J].FST; tempt.id=cur[j].id+1; Tempt.nump=cur[j].nump; Temp=hebing (Temp,get_close (tempt)); }} if (Temp.size () ==0) continue; The symbol cannot be read in. int Numcur=xmji_isin_xmjizu (CUR,V); Current node designator int Tttnum=xmji_isin_xmjizu (TEMP,V); New Target label if (TTTNUM==-1)//New project set {V.push_back (TEM p); Q.push (temp); Addegde (Numcur,v.size () -1,i); Join Edge, the right is read into the characterID} else//old project set {add Egde (Numcur,tttnum,i); }}}}void Print_xmjizu ()//print project set family {for (int i=0;i<v.size (); i++) {cout<< "project set "<<i<<": "<<endl; for (int j=0;j<v[i].size (); j + +) {cout<<proce[v[i][j].nump]<< "" <<v[i][j].id<< " "<<v[i][j].fst<<endl; } cout<<endl; } for (int i=0;i<v.size (), i++) {for (int j=head[i];j!=-1;j=e[j][1]) {cout<< "" &lt ;<getchar[e[j][2]]<<endl; cout<<i<< "--->" <<e[j][0]<<endl; }}}bool get_table ()//Get Analysis table table[i][j]=w: status I-->j, read in symbol W.

{for (int i=0;i<v.size (); i++)//Traverse graph {for (int j=head[i];j!=-1;j=e[j][1]) {i F (Table[i][e[j][2]]!=-1) return 0; Multiple entrances. Error. TABLE[I][E[J][2]]=E[J][0]; Tb_s_r[i][e[j][2]]=-1; Move closer-1.

}} for (int i=0;i<v.size (); i++)//Traverse all items {for (int j=0;j<v[i].size (); j + +) { if (V[i][j].id==proce[v[i][j].nump].size ())//attribution {for (int k=0;k<v[i][j].fst.siz E (); k++) {if (table[i][(V[I][J].FST) [k]-' 0 ']!=-1) return 0; Multiple entrances, error. if ((V[I][J].FST) [k]== ' 0 ' &&v[i][j].nump==0) table[i][(V[I][J].FST) [k]-' 0 ']=-3; Acceptable state. else {table[i][(v[i][j].fst) [k]-' 0 ']=v[i][j].nump; tb_s_r[i][(V[I][J].FST) [k]-' 0 ']=-2; Return to the State}}}}} 1; void Print_table () {cout<< "LR (1) Analysis table:" <<endl; cout<< "status" << "Actoin" <<endl; for (int j=0;j<=num;j++) {if (J==NUMVT) continue; Cout<< "" <<getchar[j]; } cout<<endl; for (int i=0;i<v.size (); i++) {cout<<i<< ""; for (int j=0;j<=num;j++) {if (J==NUMVT) continue; if (table[i][j]==-3) cout<< "ACC" << ""; Accept else if (table[i][j]==-1) cout<< ""; Empty else if (tb_s_r[i][j]==-1) cout<< "s" <<table[i][j]<< ""; Move near else if (tb_s_r[i][j]==-2) cout<< "R" <<table[i][j]<< ""; Attribution} cout<<endl; }}string word;void print_now_state (int count,stack<int>state,stack<int>wd,int i) {cout<<count< < ' t ' << ' t '; stack<int>temp; while (!state.empty ()) {Temp.push (State.top ()); State.pop (); } while (!temp.empty ()) {cout<<temp.top (); Temp.pop (); } cout<< ' \ t ' << ' \ t '; while (!wd.empty ()) {Temp.push (Wd.top ()); Wd.pop (); } while (!temp.empty ()) {cout<<getchar[temp.top ()]; Temp.pop (); } cout<< ' \ t ' << ' \ t '; for (int j=i;j<word.size (); j + +) cout<<word[j]; cout<< ' \ t ' << ' t ';} Parsing process for bool analyze () {cout<< "<<word<<": "<<endl; cout<< "Step \t\t" << "status Stack \t\t" << "symbol stack \t\t" << "input string \t\t" << "Action description" <<endl; stack<int>state; Two stacks: state stack and symbol stack stack<int>wd; int count=0; State.push (0); Initialize Wd.push (0); ' # ' for (int i=0;;) I, {int cur=state.top () reading into the text; if (table[cur][getnum[word[i]]]==-1)//blank, report error return 0; if (table[cur][getnum[word[i]]]==-3)//Accept State {print_now_state (count++,state,wd,i); cout<< "Congratulations. acc! " <<endl; return 1; } if (Tb_s_r[cur][getnum[word[i]]]==-1)//Move Input { Print_now_state (Count++,state,wd,i); int Newstate=table[cur][getnum[word[i]]; cout<< "action[" <<cur<< "," <<getnum[word[i]]<< "]=" <<newstate; cout<< ", status" <<newstate<< "into the stack" <<endl; Wd.push (Getnum[word[i]); State.push (newstate); i++; } else if (tb_s_r[cur][getnum[word[i]]]==-2)//Attribution {print_now_state (count++,state,wd,i); int Numpro=table[cur][getnum[word[i]]; The resulting formula is normalized to about int len=proce[numpro].size ()-1; for (int ii=0;ii<len;ii++)//Stack {wd.pop (); State.pop (); } wd.push (Getnum[proce[numpro][0]]); New into int cur=state.top (); cout<< "with" <<proce[numpro][0]<< ","; for (int ii=1;ii<=len;ii++) cout<<proce[numpro][ii]; Cout<< "for Attribution," << "goto[" <<cur<< "," <<getnum[word[i]]<< "]=" <<table[cur][ Getnum[proce[numpro][0]]; cout<< "into the stack" <<endl; State.push (Table[cur][getnum[proce[numpro][0]]); }} return 1;} int main () {clear (); Readin (); GETPP (); Get_first (); Get_xiangmujizu (); if (!get_table ()) {cout<< "This grammar has multiple entries when generating an analytic table, non-LR (1) Grammar!

"<<endl; return 0; }//Print_xmjizu (); Print_table (); cout<< "Please input word:" <<endl; cin>>word; word+= ' # '; if (!analyze ()) cout<< "error!" <<endl; Else return 0;}




LR (1) Grammar analyzer//c++ implementation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.