// cyk_greibach.cpp CYK reduce grammar to Greiback Normal Form // and output it to file greibach.pda // for use in a PDA // corrections 4/3/01 JSS #include "cykp.h" void cyk_greibach(var_type V, ter_type T, prod_type P, variable S) // parameters are input only, not modified { vector A; // the A[k] in pseudo code vector B; // the B[k] in pseudo code var_type::const_iterator iter; int m = V.size(); // loop limit in pseudo code int k; // loop variable in pseudo code int j; // loop variable in pseudo code int i; // misc loop variable prod_type P1; // swaping temporary for productions prod_type P2; // the other swap temporary // (can't remove in loop) prod_type::iterator p1_iter; // for loop through productions prod_type::iterator p2_iter; // for loop within loop through productions production tp(""); // temporary production alpha::iterator a_iter; // for loop through right side of production int kk; // additional loop variable if(verbose>=3) cout << "generating greiback.pda" << endl; // the variables are ordered, arbitrarily, yet fixed, A and B pairs // no requirement on ordering productions, sorted at end for checking if(verbose>=4) cout << "k A[k] B[k]" << endl; k = 0; for(iter=V.begin(); iter!=V.end(); iter++) { A.push_back(*iter); B.push_back("G_"+ *iter); if(verbose>=4) cout << k++ << " " << *iter << " " << "G_"+ *iter << endl; } P1 = P; for(kk=0; kk=5) cout << "kk=" << kk << ", k=" << k << endl; if(verbose>=5) cout << "A[k]=" << A[k] << endl; for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) p1_iter->color = 0; // later a 1 will mean delete for(j = 0; j < k; j++) { // pseudo code 2) if(verbose>=6) { cout << "kk=" << kk << ", k=" << k << ", j=" << j << endl; cout << "A[j]=" << A[j] << endl; } for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { //pseudo code 3) if(p1_iter->V==A[k] && p1_iter->w[0]==A[j] && p1_iter->color==0) { if(verbose>=4) cout << "found 3 " << A[k] << " -> " << A[j] << endl; for(p2_iter=P1.begin(); p2_iter!=P1.end(); p2_iter++) { // pscode 4) if(p2_iter->V==A[j] && p2_iter->color==0) { tp = *p2_iter; tp.V = A[k]; for(i=1; iw.size(); i++) tp.w.push_back(p1_iter->w[i]); // pseudo code 5) P2.push_back(tp); if(verbose>=4) { cout << "adding 5 " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } } } p1_iter->color = 1; // delete later pseudo code 6) if(verbose>=4) { cout << "deleting 6 " << p1_iter->V << " ->"; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } } } } // end for(j= // fix up P1 for next section for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) if(p1_iter->color==0) P2.push_back(*p1_iter); P1 = P2; P2.clear(); // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>2) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { // pseudo code 7) if(p1_iter->V==A[k] && p1_iter->w[0]==A[k] && p1_iter->color==0) { if(verbose>=4) cout << "found 7 " << A[k] << " -> " << A[k] << endl; tp = production(B[k]); for(i=1; iw.size(); i++) tp.w.push_back(p1_iter->w[i]); P2.push_back(tp); // pseudo code 8) if(verbose>=4) { cout << "adding 8 " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } tp.w.push_back(B[k]); P2.push_back(tp); // also pseudo code 8) if(verbose>=4) { cout << "adding 8 " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } p1_iter->color = 1; // delete later pseudo code 9) if(verbose>=4) { cout << "deleting 9 " << p1_iter->V << " ->"; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } for(p2_iter=P1.begin(); p2_iter!=P1.end(); p2_iter++) {// pscode 10) if(p2_iter->V==A[k] && p2_iter->w[0]!=A[k] && p2_iter->color==0) { if(verbose>=4) cout << "found 10 " << A[k] << " -> !=" << endl; tp = *p2_iter; tp.w.push_back(B[k]); P2.push_back(tp); // also pseudo code 11) if(verbose>=4) { cout << "adding 11 " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) cout << " " << *a_iter; cout << endl; } } } } } // fix up P1 for next section for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) if(p1_iter->color==0) P2.push_back(*p1_iter); P1 = P2; P2.clear(); // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>2) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); if(verbose>=6) cout << "fix up deletes in P1" << endl; // fix up P1 for next iteration for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(p1_iter->color==0) P2.push_back(*p1_iter); } P1 = P2; P2.clear(); // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>2) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); if(verbose>=6) // detailed printout { cout << "productions are now:" << endl; for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { cout << p1_iter->V << " ->" ; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) { cout << " " << *a_iter ; } cout << endl; } } } // end for(k= // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>2) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); } // end for(kk= if(verbose>=4) cout << "Greibach pass 1 complete" << endl; // Pass2 of Greibach A[k] -> A[kk] gamma gets all A[kk] replaced for(kk=m-1; kk>0; kk--) { for(k=kk-1; k>=0; k--) { if(verbose>=4) cout << "Greiback Pass2 kk=" << kk << ", k=" << k << endl; if(verbose>=4) cout << "A[kk]=" << A[kk] << ", A[k]=" << A[k] << endl; for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) // through productions { if(p1_iter->V==A[k] && p1_iter->w[0]==A[kk] && p1_iter->color==0) { if(verbose>=4) cout << "found sub " << A[k] << " -> " << A[kk] << " gamma" << endl; for(p2_iter=P1.begin(); p2_iter!=P1.end(); p2_iter++) // substitute { if(p2_iter->V==A[kk]) { tp = *p2_iter; tp.V = A[k]; for(i=1; iw.size(); i++) { tp.w.push_back(p1_iter->w[i]); // keep gamma } P2.push_back(tp); if(verbose>=4) { cout << "adding substitute " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) { cout << " " << *a_iter; } cout << endl; } } } p1_iter->color = 1; // delete later if(verbose>=4) { cout << "deleting in pass2 " << p1_iter->V << " ->"; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) { cout << " " << *a_iter; } cout << endl; } } } } if(verbose>=6) cout << "fix up deletes in P1" << endl; // fix up P1 for next iteration for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(p1_iter->color==0) P2.push_back(*p1_iter); } P1 = P2; P2.clear(); if(verbose>=6) // detailed printout { cout << "Pass2 productions are now:" << endl; for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { cout << p1_iter->V << " ->" ; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) { cout << " " << *a_iter ; } cout << endl; } } } if(verbose>=4) cout << "Greibach pass 2 complete, sort and delete duplicates" << endl; // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>2) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); if(verbose>=4) cout << "Greibach Pass3, G_* -> A* substitute" << endl; for(k=0; kw[0]==A[k] && p1_iter->color==0) { if(verbose>=4) cout << "found sub 3 " << p1_iter->V << " -> " << A[k] << " gamma" << endl; for(p2_iter=P1.begin(); p2_iter!=P1.end(); p2_iter++) // substitute { if(p2_iter->V==A[k]) { tp = *p2_iter; tp.V = p1_iter->V; for(i=1; iw.size(); i++) { tp.w.push_back(p1_iter->w[i]); // keep gamma } P2.push_back(tp); if(verbose>=4) { cout << "adding substitute 3 " << tp.V << " ->"; for(a_iter=tp.w.begin(); a_iter!=tp.w.end(); a_iter++) { cout << " " << *a_iter; } cout << endl; } } } p1_iter->color = 1; // delete later if(verbose>=4) { cout << "deleting in pass3 " << p1_iter->V << " ->"; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) { cout << " " << *a_iter; } cout << endl; } } } } if(verbose>=6) cout << "fix up deletes in P1" << endl; // fix up P1 for next iteration for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(p1_iter->color==0) P2.push_back(*p1_iter); } P1 = P2; P2.clear(); if(verbose>=4) cout << "Greibach pass 3 complete, sort and delete duplicates" << endl; // sort, delete duplicates and print productions tp = production(""); sort(P1.begin(), P1.end(), production::smaller ); for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) { if(tp == *p1_iter) continue; // delete if(verbose>0) cout << *p1_iter << endl; tp = *p1_iter; P2.push_back(tp); } P1 = P2; P2.clear(); // Clean out some redundant stuff that may have created cyk_eliminate(V, T, P1, S); // open output file and write ofstream file_out; file_out.open("greibach.pda"); if(!file_out) { cout << "can not open greibach.pda for writing. bye!" << endl; return; } file_out << "// greibach.pda from cykp" << endl; file_out << endl; file_out << "start " << S << endl; file_out << endl; for(iter=T.begin(); iter!=T.end(); iter++) // output terminals { file_out << "terminal " << *iter << " ;" << endl; } file_out << endl; for(iter=V.begin(); iter!=V.end(); iter++) // output variables { file_out << "variable " << *iter << " ;" << endl; } file_out << endl; for(p1_iter=P1.begin(); p1_iter!=P1.end(); p1_iter++) // output productions { file_out << p1_iter->V << " ->" ; for(a_iter=p1_iter->w.begin(); a_iter!=p1_iter->w.end(); a_iter++) { file_out << " " << *a_iter ; } file_out << " ;" << endl; } file_out << "enddef" << endl; file_out.close(); if(verbose>=4) cout << "greibach finished" << endl << endl; return; }