LR(1)语法分析表生成

花了一天写的语法分析器的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)
    {
     int num=0;
     for(set<char>::iterator it_zhong=zhongjiefu.begin();it_zhong!=zhongjiefu.end();++it_zhong)
     
      if(*set_it==*it_zhong) break;
      ++num;
     }
     if(str[0]==wenfa[0][0]) line_action[num]=999;
     else line_action[num]=-num_shi;
    }
   }
  }
  actions.push_back(line_action);
 }
}
void output_fenxibiao()
{
 ofstream out_action("action.txt"),out_goto("goto.txt");
 cout<<endl;
 cout<<"LR(1)分析表:"<<endl;
 cout<<endl<<'\t';
 set<char>::iterator zhong_it=zhongjiefu.begin();
 while(zhong_it!=zhongjiefu.end())
 {
  cout<<*zhong_it++<<'\t';
 }
 set<char>::iterator feizhong_it=feizhongjiefu.begin();
 while(feizhong_it!=feizhongjiefu.end())
 {
  cout<<*feizhong_it++<<'\t';
 }
 cout<<endl;
 int line=0;
 for(vector<vector<int> >::iterator i_1=actions.begin(),i_3=gotos.begin();i_1!=actions.end();++i_1,++i_3,++line)
 {
  cout<<line<<'\t';
  for(vector<int>::iterator i_2=i_1->begin();i_2!=i_1->end();++i_2)
  {
   cout<<*i_2<<'\t';
   out_action<<*i_2<<',';
  }
  for(vector<int>::iterator i_4=i_3->begin();i_4!=i_3->end();++i_4)
  {
   cout<<*i_4<<'\t';
   out_goto<<*i_4<<',';
  }
  cout<<endl;
  out_action<<endl;
  out_goto<<endl;
 }

}
void output_zhuangtaitu()
{
 cout<<"有"<<gototu.size()<<"个状态"<<endl<<endl;
 for(deque<xiangji>::size_type itp=0;itp!=gototu.size();++itp)
 {
  cout<<"状态:"<<itp<<endl;
  gototu[itp].output();
  for(set<pair<char,int> >::iterator iiip=gototu[itp].get_action().begin();iiip!=gototu[itp].get_action().end();++iiip)
  {
   cout<<"输入:"<<iiip->first<<"\t"<<"跳转到:"<<iiip->second<<endl;
  }
  cout<<endl;
 }
}
void output_zhongjiefu()
{
 cout<<"终结符:"<<zhongjiefu.size()<<"个"<<endl;
 set<char>::iterator zhong_it=zhongjiefu.begin();
 while(zhong_it!=zhongjiefu.end())
 {
  cout<<*zhong_it++<<' ';
 }
 cout<<endl;
 
}
void output_feizhongjiefu()
{
 cout<<"非终结符:"<<feizhongjiefu.size()<<"个"<<endl;
 set<char>::iterator feizhong_it=feizhongjiefu.begin();
 while(feizhong_it!=feizhongjiefu.end())
 {
  cout<<*feizhong_it++<<' ';
 }
 cout<<endl;
}
void output_chanshengshi_num()
{
 cout<<"规约时的产生式编号:"<<endl;
 int num=1;
 vector<string>::iterator it=wenfa.begin();
 ++it;
 for(;it!=wenfa.end();++it,++num)
 {
  cout<<num<<'\t'<<*it<<endl;
 }
}
int main()
{
 inputwenfa("wenfa.txt");
 inputfirst("first.txt");
 findzhongjiefu();
 items();
 creat_goto();
 creat_action();
 
 output_zhuangtaitu();
 output_zhongjiefu();
 output_feizhongjiefu();
 output_chanshengshi_num();
 output_fenxibiao();
 


 system("pause");
 return 0;
}

 

 

 

例:给定文法

          <program> ::= <block>

 

          <block> ::= <const-decl> <var-decl> <proc-decl> <statement>

 

          <const-decl> ::= const <const-assignment-list> ; | ε

 

          <const-assignment-list> ::= <ident> = <number>

            | <const-assignment-list> , <ident> = <number>

 

          <var-decl> ::= var <ident-list> ; |ε

 

          <ident-list> ::= <ident> | <ident-list> , <ident>

 

          <proc-decl> ::= <proc-decl> procedure <ident> ; <block> ; |ε

 

          <statement> ::= <ident> := <expression>

            | call <ident>

            | begin <statement-list> end

            | if <condition> then <statement>

            | while <condition> do <statement>

            

 

          <statement-list> ::= <statement> | <statement-list> ; <statement>

 

          <condition> ::= odd <expression> | <expression> <relation> <expression>

 

          <relation> ::= = | <> | < | > | <= | >=

 

          <expression> ::= <term> | <adding-operator> <term>

            | <expression> <adding-operator> <term>

 

          <adding-operator> ::= + | -

 

          <term> ::= <factor> | <term> <multiplying-operator> <factor>

 

          <multiplying-operator> ::= * | /

 

          <factor> ::= <ident> | <number> | ( <expression> )

 

wenfa.txt

S#A
A#B
B#CDEF
C#aG;
C#
G#m=n
G#G,m=n
D#bJ;
D#
J#m
J#J,m
E#Ecm;B;
E#
F#m:=K
F#dm
F#eLf
F#hMiF
F#jMlF
F#
L#F
L#L;F
M#kK
M#KNK
N#=
N#<>
N#<
N#>
N#<=
N#>=
K#O
K#PO
K#KPO
P#+
P#-
O#Q
O#ORQ
R#*
R#/
Q#m
Q#n
Q#(K)

 

first.txt

A abcmdehj%
B abcmdehj%
C a%
D b%
E c%
F mdehj%
G m
J m
K +-
L mdehj;%
M +-k
N =<>
O mn(
P +-
Q mn(
R */

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值