Spent the day writing the parser's LR (1) Analysis table
LR (1) Analysis Table generator (first requires manual ... )
The grammar is placed in the "Wenfa.txt" file, and the first set is put in "First.txt"
Grammar must be augmented grammar, one production per line, "-" instead of "#", non-terminator with a single capital letter, Terminator with a single lowercase letter
The first set is formatted as "non-terminator Terminator collection string", one per line such as "T ni (" empty "%" instead of "
Generate action table in Action.txt, goto table in Goto.txt
-----by decly
#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cctype>
#include <algorithm>
#include <set>
#include <map>
#include <deque>
using namespace Std;
Class A_xiang
{
Public
A_xiang::a_xiang () {}
A_xiang::a_xiang (const string& str,set<char>& forw): A_shizi (str), ForWord (FORW) {}
string& Geta_shizi () {return a_shizi;}
set<char>& Getforword () {return forword;}
void Push_forword (set<char>& sv) {Forword.insert (Sv.begin (), Sv.end ());}
friend bool operator== (const a_xiang& lhs,const a_xiang& RHS);
Private
String A_shizi;
Set<char> ForWord;
};
Class Xiangji
{
Public
void closure ();
void Push_a_xiang (const A_xiang orig) {xiang.push_back (orig);}
void output ();
vector<a_xiang>& Get_xiang () {return Xiang;}
Set<pair<char,int> >& get_action () {return action;}
friend bool operator== (const xiangji& lhs,const xiangji& RHS);
Private
Vector<a_xiang> Xiang;
Set<pair<char,int> > action;
};
map<char,set<char> > first;
Vector<string> Wenfa,wenfa_dian;
Deque<xiangji> Gototu;
Set<char> Zhongjiefu,feizhongjiefu;
Vector<vector<int> >actions,gotos;
BOOL operator== (const a_xiang& lhs,const a_xiang& RHS)
{
if (Lhs.a_shizi!=rhs.a_shizi) return false;
if (Lhs.forword.size ()!=rhs.forword.size ()) return false;
Set<char>::const_iterator Lhs_it=lhs.forword.begin (), Rhs_it=rhs.forword.begin ();
while (Lhs_it!=lhs.forword.end ())
{
if (*lhs_it!=*rhs_it) return false;
++lhs_it;
++rhs_it;
}
return true;
}
BOOL operator== (const xiangji& lhs,const xiangji& RHS)
{
if (Lhs.xiang.size () ==rhs.xiang.size ())
{
For (Vector<a_xiang>::const_iterator Lhs_it=lhs.xiang.begin (); Lhs_it!=lhs.xiang.end (); ++lhs_it)
{
Vector<a_xiang>::const_iterator Rhs_it=rhs.xiang.begin ();
for (; Rhs_it!=rhs.xiang.end (); ++rhs_it)
if (*lhs_it==*rhs_it) break;
if (Rhs_it==rhs.xiang.end ()) return false;
}
return true;
}
else return false;
}
void Changewenfa ()
{
Vector<string>::iterator It=wenfa.begin ();
while (It!=wenfa.end ())
{
String A_line (*it);
if (A_line.size () ==2) a_line.push_back ('! ');
Else
{
String::iterator P=a_line.begin ();
++p;++p;
A_line.insert (P, '! ');
}
Wenfa_dian.push_back (A_line);
++it;
}
}
void Inputwenfa (const string& wenfa_file)//Read into grammar file
{
Ifstream in;
In.open (Wenfa_file.c_str ());
String A_line;
while (Getline (In,a_line))
Wenfa.push_back (A_line);
In.close ();
Changewenfa ();
}
void Inputfirst (const string& first_file)//read into first file
{
Ifstream in;
In.open (First_file.c_str ());
String A_line;
while (Getline (In,a_line))
{
Char ch=a_line[0];
for (int i=2;i!=a_line.size (); ++i)
First[ch].insert (A_line[i]);
}
In.close ();
}
BOOL Isfeizhongjiefu (char c)
{
if (c>= ' A ' &&c<= ' Z ') return true;
else return false;
}
BOOL Iszhongjiefu (char c)
{
return!isfeizhongjiefu (c);
}
Vector<string> Chanshengshi (char c)
{
Vector<string> VEC;
For (Vector<string>::iterator It=wenfa_dian.begin (); It!=wenfa_dian.end (); ++it)
if ((*it) [0]==c] Vec.push_back (*it);
return VEC;
}
Set<char> FindFirst (const string& str,set<char>& ForWord)
{
if (str== "") return ForWord;
else if (Iszhongjiefu (str[0]))
{
Set<char> setc;
Setc.insert (Str[0]);
return setc;
}
else//if (Isfeizhongjiefu (str[0]))
{
Set<char> setc;
String::const_iterator P=str.begin ();
while (P!=str.end ())
{
Setc.insert ((First[*p]). Begin (), (First[*p]). end ());
if ((First[*p]). Find ('% ')!=first[*p].end ()) ++p;
else break;
}
if (P==str.end ()) Setc.insert (Forword.begin (), Forword.end ());
Setc.erase ('% ');
return setc;
}
}
void Xiangji::closure ()
{
For (Vector<a_xiang>::size_type it=0;it!=xiang.size (); ++it)
{
For (String::iterator P=xiang[it].geta_shizi (). Begin ();p!=xiang[it].geta_shizi (). end (); ++p)
{
if (*p== '! ')
{
if ((++p)!=xiang[it].geta_shizi (). End () &&isfeizhongjiefu (*p))
{
String Hou (++p,xiang[it].geta_shizi (). end ());
Set<char> forword_2 (FindFirst (Hou,xiang[it].getforword ()));
Vector<string> Shi (Chanshengshi (* (--p)));
For (Vector<string>::iterator Jp=shi.begin (); Jp!=shi.end (); ++jp)
{
Vector<a_xiang>::iterator Xiang_it=xiang.begin ();
while (Xiang_it!=xiang.end ())
{
if ((*JP) ==xiang_it->geta_shizi ())
{
Xiang_it->push_forword (forword_2);
Break
}
++xiang_it;
}
if (Xiang_it==xiang.end ())
Xiang.push_back (A_xiang (*JP), forword_2);
}
Break
}
--p;
}
}
}
}
void Xiangji::output ()
{
Vector<a_xiang>::iterator Ip=xiang.begin ();
while (Ip!=xiang.end ())
{
cout<< (*IP). Geta_shizi () << ' \ t ';
Set<char>::iterator Iit=ip->getforword (). Begin ();
while (Iit!=ip->getforword (). End ())
{
cout<<*iit<< "";
++IIT;
}
cout<<endl;
++ip;
}
}
Xiangji go_to (xiangji& Orig,char x)
{
Xiangji Xia_j;
For (Vector<a_xiang>::iterator It=orig.get_xiang (). Begin (); It!=orig.get_xiang (). end (); ++it)
{
String Shizi (It->geta_shizi ());
String::iterator P=find (Shizi.begin (), Shizi.end (), '! ');
if (++p!=shizi.end () && (*p) ==x)
{
P=shizi.erase (P);
--p;
Shizi.insert (P,X);
Xia_j.get_xiang (). Push_back (A_xiang (Shizi,it->getforword ()));
}
}
Xia_j.closure ();
return xia_j;
}
BOOL Isdifferent (xiangji& orig)
{
BOOL Flag=true;
For (Vector<xiangji>::size_type i=0;i!=gototu.size (); ++i)
{
if (Orig==gototu[i])
{
Flag=false;
Break
}
}
return flag;
}
void items ()
{
Xiangji start;
Set<char> Start_forword;
Start_forword.insert (' $ ');
Start.push_a_xiang (A_xiang (Wenfa_dian.front (), Start_forword));
Start.closure ();
Gototu.push_back (start);
For (Vector<xiangji>::size_type i=0;i!=gototu.size (); ++i)
{
For (Vector<a_xiang>::iterator P=gototu[i].get_xiang (). Begin ();p!=gototu[i].get_xiang (). end (); ++p)
{
String::iterator It=find (P->geta_shizi (). Begin (), P->geta_shizi (). End (), '! ');
++it;
if (It==p->geta_shizi (). End ()) continue;
Xiangji A_new_xiangji (go_to (gototu[i],*it));
if (Isdifferent (A_new_xiangji))
{
Gototu[i].get_action (). Insert (Make_pair (*it,gototu.size ()));
Gototu.push_back (A_new_xiangji);
}
Else
{
For (Vector<xiangji>::size_type ip=0;ip!=gototu.size (); ++ip)
{
if (A_new_xiangji==gototu[ip])
Gototu[i].get_action (). Insert (Make_pair (*IT,IP));
}
}
}
}
}
void Findzhongjiefu ()
{
For (Vector<string>::iterator It=wenfa.begin (); It!=wenfa.end (); ++it)
{
For (String::iterator p=it->begin ();p!=it->end (); ++p)
{
if (Isupper (*p)) Feizhongjiefu.insert (*p);
else if (*p!= ' # ') Zhongjiefu.insert (*p);
}
}
Zhongjiefu.insert (' $ ');
Feizhongjiefu.erase (Wenfa[0][0]);
}
void Creat_goto ()
{
For (Deque<xiangji>::iterator It=gototu.begin (); It!=gototu.end (); ++it)
{
Vector<int> Line_goto;
For (Set<char>::iterator Zhong_it=feizhongjiefu.begin (); Zhong_it!=feizhongjiefu.end (); ++zhong_it)
{
Set<pair<char,int> >::iterator p=it->get_action (). Begin ();
For (;p!=it->get_action (). end (); ++p)
{
if (*zhong_it==p->first)
{
Line_goto.push_back (P->second);
Break
}
}
if (P==it->get_action (). End ()) line_goto.push_back (0);
}
Gotos.push_back (Line_goto);
}
}
void Creat_action ()
{
For (Deque<xiangji>::iterator It=gototu.begin (); It!=gototu.end (); ++it)
{
Vector<int> line_action;
For (Set<char>::iterator Zhong_it=zhongjiefu.begin (); Zhong_it!=zhongjiefu.end (); ++zhong_it)
{
Set<pair<char,int> >::iterator p=it->get_action (). Begin ();
For (;p!=it->get_action (). end (); ++p)
{
if (*zhong_it==p->first)
{
Line_action.push_back (P->second);
Break
}
}
if (P==it->get_action (). End ()) line_action.push_back (0);
}
For (Vector<a_xiang>::iterator It_shi=it->get_xiang (). Begin (); It_shi!=it->get_xiang (). end (); ++it_shi )
{
String str (It_shi->geta_shizi ());
if (str[str.size () -1]== '! ')
{
String::iterator Ip_str=str.end ();
--IP_STR;
Str.erase (IP_STR);
int num_shi=0;
for (; Num_shi!=wenfa.size (); ++num_shi)
{
if (Str==wenfa[num_shi]) break;
}
For (Set<char>::iterator Set_it=it_shi->getforword (). Begin (); Set_it!=it_shi->getforword (). end (); + + SET_IT)
{
int num=0;