typedef struct grammer
{
char *expr;
}GrammarType;
GrammarType grammarTable[10];
int iog=0;
char lexemes[1024];
int pos=0;
int getToken()
{
int c=getchar();
while(c==' '||c=='/t')
{
c=getchar();
}
return c;
}
int getGrammar()
{
char local[16];
int p=0;
int c=getToken();
if(c=='#') return -1;
if(c>='A'&&c<='Z')local[p++]=c;
else {printf("the left of grammar must be UpperCase");exit(1);}
c=getToken();
if(c!='-'){printf("there must be - symbol");exit(1);}
local[p++]=c;
c=getToken();
if(c!='>'){printf("there must be > symbol");exit(1);}
local[p++]=c;
c=getToken();
if(c!='/n')local[p++]=c;
else {printf("the right of grammar is null");exit(1);}
c=getToken();
while(c!='/n')
{if(c=='|')
{
local[p++]='/0';
grammarTable[iog].expr=&lexemes[pos];
strcpy(&lexemes[pos],local);
pos+=strlen(local)+1;
iog++;
p=3;
}
else local[p++]=c;
c=getToken();
}
local[p]='/0';
grammarTable[iog].expr=&lexemes[pos];
strcpy(&lexemes[pos],local);
pos+=strlen(local)+1;
iog++;
return iog;
}
void lex()
{
while(getGrammar()!=-1);
}
typedef struct item
{
char *production;
int pos;
char *end;
}ItemType;
ItemType I[32][8];
int set=0,term=0;
int final[32];
char buffer[1024];
int index=0;
int copy(char *dest,char *from)
{
int j=0;
while(from[j]!='/0')
{
dest[j]=from[j++];
}
dest[j]='/0';
return j;
}
int len(char *s)
{
int j=0;
while(s[j++]!='/0');
return j-1;
}
char x[32];
void first(char *right,char *key)
{
static int point=0;
int i;
if(right[0]>='A'&&right[0]<='Z')
{
for(i=0;i<iog;i++)
{
if(right[0]==grammarTable[i].expr[0])
{ int n=copy(x,&grammarTable[i].expr[3]);
copy(&x[n],&right[1]);
first(x,key);}
}
}
else {
for(i=0;i<point;i++)
if(key[i]==right[0])return;
key[point++]=right[0];return;
}
key[point]='/0';
}
void closure(char *right,int pos,char *end)
{
char f[16];
char key[16];
int i;
int m,n,k;
ItemType temp;
temp.production=right;
temp.pos=pos;
temp.end=end;
//printf("%s,%d,%s,%d/n",right,pos,end,set);
term=0;
I[set][term]=temp;
while(I[set][term].production[pos]>='A'&&I[set][term].production[pos]<='Z')
{
int i,j,n;
j=term;
for(i=0;i<4;i++)
{
if(I[set][j].production[pos]==grammarTable[i].expr[0])
{
temp.production=grammarTable[i].expr;
temp.pos=3;
if(I[set][j].production[pos+1]=='/0')
temp.end=end;
else { n=copy(f,&(I[set][j].production[pos+1]));
copy(&f[n],end);
first(f,key);
copy(&buffer[index],key);
temp.end=&buffer[index];
index+=len(temp.end)+1;
}
I[set][++term]=temp;
}
}
}
final[set]=term+1;
i=0;
for(i=0;i<set;i++)
{
k=0;
if(final[set]==final[i])
{ for(m=0;m<final[set];m++)
{int z=0;
for(n=0;n<final[i];n++)
{
if((strcmp(I[set][m].production,I[i][n].production)==0)&&
(strcmp(I[set][m].end,I[i][n].end)==0)&&(I[set][m].pos==I[i][n].pos)){z=1;break;}
}
k+=z;
}
if(k==final[set])
{
while(k--){
I[set][k].production=0;
}
return;}
}
}
//if(k==final[set])return;
set++;
}
void items()
{
int i=index;
int j;
buffer[index++]='$';
buffer[index++]='/0';
closure(grammarTable[0].expr,3,&buffer[i]);
i=0;
j=0;
while(I[j][i].production!=0)
{while(I[j][i].production!=0)
{
if(I[j][i].production[I[j][i].pos]=='/0')
break;
//else if(I[j][i].production[I[j][i].pos+1]!='/0')
//printf("I[%d] eat %c->",j,I[j][i].production[I[j][i].pos]);
closure(I[j][i].production,I[j][i].pos+1,I[j][i].end);
//printf("%s/n",I[set][i++].production);
i++;
}
i=0;
j++;
}
}
int main()
{
int i,j;
lex();
items();
for(j=0;j<set;j++)
{i=0;
printf("I[%d]: %d/n",j,final[j]);
while(I[j][i].production!=0)
{
printf("%s,%d,%s/n",I[j][i].production,I[j][i].pos,I[j][i++].end);
}
printf("%/n");
}
return 0;
}
{
char *expr;
}GrammarType;
GrammarType grammarTable[10];
int iog=0;
char lexemes[1024];
int pos=0;
int getToken()
{
int c=getchar();
while(c==' '||c=='/t')
{
c=getchar();
}
return c;
}
int getGrammar()
{
char local[16];
int p=0;
int c=getToken();
if(c=='#') return -1;
if(c>='A'&&c<='Z')local[p++]=c;
else {printf("the left of grammar must be UpperCase");exit(1);}
c=getToken();
if(c!='-'){printf("there must be - symbol");exit(1);}
local[p++]=c;
c=getToken();
if(c!='>'){printf("there must be > symbol");exit(1);}
local[p++]=c;
c=getToken();
if(c!='/n')local[p++]=c;
else {printf("the right of grammar is null");exit(1);}
c=getToken();
while(c!='/n')
{if(c=='|')
{
local[p++]='/0';
grammarTable[iog].expr=&lexemes[pos];
strcpy(&lexemes[pos],local);
pos+=strlen(local)+1;
iog++;
p=3;
}
else local[p++]=c;
c=getToken();
}
local[p]='/0';
grammarTable[iog].expr=&lexemes[pos];
strcpy(&lexemes[pos],local);
pos+=strlen(local)+1;
iog++;
return iog;
}
void lex()
{
while(getGrammar()!=-1);
}
typedef struct item
{
char *production;
int pos;
char *end;
}ItemType;
ItemType I[32][8];
int set=0,term=0;
int final[32];
char buffer[1024];
int index=0;
int copy(char *dest,char *from)
{
int j=0;
while(from[j]!='/0')
{
dest[j]=from[j++];
}
dest[j]='/0';
return j;
}
int len(char *s)
{
int j=0;
while(s[j++]!='/0');
return j-1;
}
char x[32];
void first(char *right,char *key)
{
static int point=0;
int i;
if(right[0]>='A'&&right[0]<='Z')
{
for(i=0;i<iog;i++)
{
if(right[0]==grammarTable[i].expr[0])
{ int n=copy(x,&grammarTable[i].expr[3]);
copy(&x[n],&right[1]);
first(x,key);}
}
}
else {
for(i=0;i<point;i++)
if(key[i]==right[0])return;
key[point++]=right[0];return;
}
key[point]='/0';
}
void closure(char *right,int pos,char *end)
{
char f[16];
char key[16];
int i;
int m,n,k;
ItemType temp;
temp.production=right;
temp.pos=pos;
temp.end=end;
//printf("%s,%d,%s,%d/n",right,pos,end,set);
term=0;
I[set][term]=temp;
while(I[set][term].production[pos]>='A'&&I[set][term].production[pos]<='Z')
{
int i,j,n;
j=term;
for(i=0;i<4;i++)
{
if(I[set][j].production[pos]==grammarTable[i].expr[0])
{
temp.production=grammarTable[i].expr;
temp.pos=3;
if(I[set][j].production[pos+1]=='/0')
temp.end=end;
else { n=copy(f,&(I[set][j].production[pos+1]));
copy(&f[n],end);
first(f,key);
copy(&buffer[index],key);
temp.end=&buffer[index];
index+=len(temp.end)+1;
}
I[set][++term]=temp;
}
}
}
final[set]=term+1;
i=0;
for(i=0;i<set;i++)
{
k=0;
if(final[set]==final[i])
{ for(m=0;m<final[set];m++)
{int z=0;
for(n=0;n<final[i];n++)
{
if((strcmp(I[set][m].production,I[i][n].production)==0)&&
(strcmp(I[set][m].end,I[i][n].end)==0)&&(I[set][m].pos==I[i][n].pos)){z=1;break;}
}
k+=z;
}
if(k==final[set])
{
while(k--){
I[set][k].production=0;
}
return;}
}
}
//if(k==final[set])return;
set++;
}
void items()
{
int i=index;
int j;
buffer[index++]='$';
buffer[index++]='/0';
closure(grammarTable[0].expr,3,&buffer[i]);
i=0;
j=0;
while(I[j][i].production!=0)
{while(I[j][i].production!=0)
{
if(I[j][i].production[I[j][i].pos]=='/0')
break;
//else if(I[j][i].production[I[j][i].pos+1]!='/0')
//printf("I[%d] eat %c->",j,I[j][i].production[I[j][i].pos]);
closure(I[j][i].production,I[j][i].pos+1,I[j][i].end);
//printf("%s/n",I[set][i++].production);
i++;
}
i=0;
j++;
}
}
int main()
{
int i,j;
lex();
items();
for(j=0;j<set;j++)
{i=0;
printf("I[%d]: %d/n",j,final[j]);
while(I[j][i].production!=0)
{
printf("%s,%d,%s/n",I[j][i].production,I[j][i].pos,I[j][i++].end);
}
printf("%/n");
}
return 0;
}