LR1文法全智能分析
// by hfut yzk
#include "stdafx.h"
#include<fstream>
#include<string>
#include<map>
#include<vector>
#include<stack>
#include<set>
#include<cstring>
#include<queue>
using namespace std;
#pragma region vars
struct xiangmu //一个项目
{
int nump; //产生式编号
int id; //.的位置
string fst; //集合
};
map<char,int>getnum;
char getchars[100]; //获得对应字符
vector<string>proce; //产生式
int table[30][30]; //预测分析表 -1
int tb_s_r[30][30]; //是移进项还是规约项,-1,-2.
int num=0;int numvt=0; //numvt是终结符集合,0是‘#’,numvt表空字
string first[100]; //每个符号的first集
bool gotfirst[100]; //是否已经完成FIRST集合
string getp[100]; //获得某终结符在左边的产生式集合
vector<vector<xiangmu> >v; //项目集族
int e[100][3];
int head[100];
int nume=0; //链式前向星项目集族图
fstream cin ("H:/课程设计/编译原理2015/lr(1)/in.txt");
fstream cout ("H:/课程设计/编译原理2015/lr(1)/out.txt");
fstream cout2 ("H:/课程设计/编译原理2015/lr(1)/out2.txt");
#pragma endregion
#pragma region functions
void readin();
void getpp();
void dfsgetfirst(int nv,int nump);
void get_first();
void clear() ;
void addegde(int from,int to,int w) ;
inline bool xmeq(xiangmu a,xiangmu b);
bool isin(xiangmu a,vector<xiangmu> b) ; //xm a is in xmji b
bool xmjieq(vector<xiangmu> a,vector<xiangmu> b) ; //两个项目集是否相等
vector<xiangmu> hebing(vector<xiangmu>a ,vector<xiangmu>b) ; //合并项目集 a,b 复给 a
int xmji_isin_xmjizu(vector<xiangmu>a,vector<vector<xiangmu> >b) ; //查找项目集,若有,则返回编号,一举俩得
vector<xiangmu> get_close(xiangmu t) ; //对项目 T作闭包
void get_xiangmujizu() ; //获得项目集族
void print_xmjizu() ; //打印项目集族
bool get_table();
void print_table();
void print_now_state(int count,stack<int>state,stack<int>wd,int i);
bool analyze();
#pragma endregion
/*******************************************读入vt,vn,编号1-num,读入所有产生式*********************************************/
void readin()
{
memset(table,-1,sizeof(table));
getnum['#']=0;
getchars[0]='#';
//cout<<"请输入所有终结符:"<<endl;
char x;
do
{
cin>>x;
getnum[x]=++num;
getchars[num]=x;
}while(cin.peek()!='\n');
numvt=++num;
getnum['@']=numvt; //kong zi
getchars[num]=('@');
// cout<<"请输入非终结符集:"<<endl;
do
{
cin>>x;
getnum[x]=++num;
getchars[num]=x;
}while(cin.peek()!='\n');
// cout<<"输入所有产生式(空字用‘@’表示),以‘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);
}
}
void getpp()
{
for(int i=0;i<proce.size();i++)
{
int temp=getnum[proce[i][0]];
getp[temp]+=char('0'+i);
}
}
/****************************************************获得first集************************************************************/
void dfsgetfirst(int nv,int nump) //当前的符号,和对应产生式编号
{
int temp=getnum[proce[nump][1]]; //产生式推出来的首符
gotfirst[nump]=1; //标记
if(temp<=numvt)first[nv]+=char('0'+temp); //是终结符
else
{
for(int i=0;i<getp[temp].size();i++) //所有temp可以推出来的符号对应的产生式
{
if(proce[nump][0]==proce[nump][1])continue; //左递归的产生式不用不影响求fisrt集
dfsgetfirst(temp,getp[temp][i]-'0');
}
first[nv]+=first[temp]; //回溯时候沿途保存
}
}
void get_first()
{
for(int i=1;i<=numvt;i++) // 终结符first集合是它自己.
{
first[i]=char('0'+i);
}
for(int i=0;i<proce.size();i++)
{
if(proce[i][0]==proce[i][1])continue; //左递归的产生式不用不影响求fisrt集
if(gotfirst[i])continue; //已经生成。
int temp=getnum[proce[i][0]];
dfsgetfirst(temp,i);
}
}
/***************************************************添加边*****************************************************************/
void addegde(int from,int to,int w)
{
e[nume][0]=to;e[nume][1]=head[from];head[from]=nume;
e[nume++][2]=w;
}
/******************************************************初始化函数*********************************************************/
void clear()
{
for(int i=0;i<100;i++