花了一天写的语法分析器的LR(1)分析表
LR(1)分析表生成器(FIRST需手动求...)
文法放在“wenfa.txt”文件中,FIRST集放“first.txt”中
文法须为增广文法,每行一个产生式,“->”用“#”代替,非终结符用单个大写字母,终结符用单个小写字母
FIRST集格式为“非终结符 终结符集合字符串”每行一条 如“T ni(” 空用“%”代替
生成ACTION表在action.txt中,GOTO表在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)//读入文法文件
{
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)//读入FIRST文件
{
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)
{