/*本程序从文件读入文法,可以根据文法自动生成规范LR(0)项目族,并根据DFA自动构造ACTION和GOTO表,希望各位大虾批评指正*/
/*所用文法
SA
SB
AaAb
Ac
BaBb
Bd
*/
#include<iostream>
#include<stdio.h>
#include<fstream>
#include<malloc.h>
using namespace std;
#define OK 1
#define ERROR 0
#define N 50
#define Y 20
int vtnum,vnnum,pronum;//依次是终结符个数,非终结符个数,产生式个数
char vt[N];
char vn[N];//终结符和非终结符集
char old[N][N]={'/0'};//用于存储文法
char oldz[N][N]={'/0'};//用于存储增广文法
int ACTION[N][N]={0};
int GOTO[N][N]={0};
typedef struct SqE{
int t;//状态编号
char c1;
}SqE;//堆栈元素
typedef struct item{
int f;//项目前部,表示产生式编号
int l;//项目后部,表示停顿点在产生式的位置
}item;//定义项目
typedef struct link{
int f;//连接前部,表示所用符号的编号,非终结符编号=在vn[]中的下标+100
int l;//连接后部,即状态编号
}link;//定义状态之间的连接
typedef struct cd{
int item_num;//状态中的项目数
int link_num;//状态的连接数
item w[N];//项目集
link u[N];//连接集
}cd;//定义状态
typedef struct DFA{
int cd_num;//状态个数
cd s[N+1];//状态集
}DFA;//定义规范LR(0)项目族,D.s[N]用作状态转换函数go_switch()的存储空间
DFA D;
void dfa();
void closure(int);
void go_switch(int,int);
int test_go_switch();
void add_go_switch();
void del_go_switch();
void action();
void go_answer();
int control();
int length(int);
int test(char);
void printf_ag();
bool test_link(int i,int num);
void main()
{
int i,j;
ifstream in("input1.txt",ios_base::in);//读文件,从文件中读入pronum,vtnum,vnnum以及产生式
in>>pronum>>vnnum>>vtnum;
in>>vn;
in>>vt;
for(i=1;i<=pronum;i++)
in>>old[i];//将产生式存入old[][],old[1]为第一个产生式
for(i=1;i<=pronum;i++)
for(j=0;old[i][j]!='/0';j++)
oldz[i][j]=old[i][j];//将产生式从old[][]录入oldz[][]
oldz[0][0]='P';
oldz[0][1]=old[1][0];//加入P->S,将原文法扩充,使其变为增广文法
vt[vtnum]='$';//把结束符'$'加入终结符集
D.cd_num=0;
for(i=0;i<=N;i++)
{
D.s[i].item_num=0;
D.s[i].link_num=0;
}//初始化状态个数、连接个数、项目个数
dfa();
action();
go_answer();
printf_ag();
control();
}
//求一个状态的闭包
void closure(int i)
{
int j,k,m,x,flag;
do
{
j=D.s[i].item_num;//j是本轮循环开始前的项目数
for(k=0;k<D.s[i].item_num;k++)
{
for(m=0;m<=pronum;m++)
{
if(oldz[m][0]==oldz[D.s[i].w[k].f][D.s[i].w[k].l])//对当前状态i中的每个项目,查询每个产生式,例如:A->a.Ab应找到A->...
{
f