#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
char grammer[200][200];
char terSymbol[200];
char nterSymbol[200];
int firstSET[100][100];
int followSET[100][100];
int vtnum, vnnum, pronum;
int M[200][200];
int local_terminal( char ch )
{
for( int i = 0; i < vtnum; i++ )
if( ch == terSymbol[i] )
return i;
return -1;
}
int local_nterminal( char ch )
{
for( int i = 0; i < vnnum; i++ )
if( ch == nterSymbol[i] )
return i;
return -1;
}
bool canbe_empty( char ch )
{
if( local_terminal(ch) != -1 )
return false;
else
{
if(firstSET[local_nterminal(ch)][vtnum-1] == 1)
return true;
else
return false;
}
}
bool have_first( int k )
{
for( int i = 0; i < vtnum; i++ )
if( firstSET[k][i] == 1 )
return true;
return false;
}
void addfirstSet( char ch, char X )
{
int X_num = local_nterminal(X);
if( local_terminal(ch) != -1 )
firstSET[X_num][local_terminal(ch)] = 1;
else
{
int ch_num = local_nterminal(ch);
for( int i = 0; i < vtnum; i++ )
if( firstSET[ch_num][i] == 1 )
firstSET[X_num][i] = 1;
}
}
void first( char X )
{
int p;
for( int i = 0; i < pronum; i++ )
{
if( grammer[i][0] == X )
{
p = 3;
while( grammer[i][p] != '\0' )
{
if( local_terminal(grammer[i][p]) != -1 )
{
addfirstSet( grammer[i][p], X );
break;
}
else
{
if(!have_first(local_nterminal(grammer[i][p])))
first( grammer[i][p] );
addfirstSet( grammer[i][p], X );
if( canbe_empty(grammer[i][p]) )
p++;
else
break;
}
}
}
}
}
bool have_follow( char ch )
{
int j = local_nterminal(ch);
for( int i = 0; i < vtnum; i++ )
if( followSET[j][i] == 1 )
return true;
return false;
}
void addfollowSet( char ch, char X, int kind )
{
int j, k;
int X_num = local_nterminal(X);
if( kind == 1 ) // add firstSET
{
if( (j = local_terminal(ch)) != -1 )
followSET[X_num][j] = 1;
else
{
k = local_nterminal(ch);
for( int i = 0; i < vtnum; i++ )
if( firstSET[k][i] == 1 )
followSET[X_num][i] = 1;
}
}
else if( kind == 0 ) // add followSET
{
j = local_nterminal(ch);
for( int i = 0; i <= vtnum; i++ )
if( followSET[j][i] == 1 )
followSET[X_num][i] = 1;
}
else
printf( "wrong" );
}
void follow( char X )
{
int p;
// add # to S
followSET[0][vtnum-1] = 1;
for( int i = 0; i < pronum; i++ )
{
p = 3;
while( grammer[i][p] !='\0' && grammer[i][p] != X )
p++;
if( grammer[i][p] == X )
{
p++;
if( grammer[i][p] == '\0' )
{
if( !have_follow(grammer[i][0]) )
follow( grammer[i][0] );
addfollowSet( grammer[i][0], X, 0);
}
else
{
while(canbe_empty(grammer[i][p]) && grammer[i][p]!='\0')
{
addfollowSet( grammer[i][p], X, 1 );//add first set but first can_empty
if(!have_follow(grammer[i][0])&&grammer[i][0]!=X)
follow( grammer[i][0] );
addfollowSet( grammer[i][0], X, 0 ); //add follow set
p++;
}
if( !canbe_empty(grammer[i][p]) )//first no-empty
addfollowSet( grammer[i][p], X, 1 ); // add first set
}
}
}
}
void create_table()
{
for( int i = 0; i < vnnum; i++ )
for( int j = 0; j < vtnum; j++ )
M[i][j] = -1;
for( int i = 0; i < pronum; i++ )
{
int S = local_nterminal( grammer[i][0] );
int t = local_terminal( grammer[i][3] );
if( grammer[i][3] != '$' )
{
for( int j = 0; j < vtnum; j++ )
{
if( t != -1 )
{
if(M[S][j] == -1 && grammer[i][3] == terSymbol[j])
M[S][j] = i;
}
else
{
int B = local_nterminal(grammer[i][3]);
if( M[S][j] == -1 && firstSET[B][j] == 1)
M[S][j] = i;
}
}
}
if( canbe_empty(grammer[i][0]) )
{
for( int t = 0; t < vtnum; t++ )
if( followSET[S][t] == 1 )
M[S][t] = i;
}
}
for( int i = 0; i < vnnum; i++ )
{
for( int j = 0; j < vtnum; j++ )
{
if( M[i][j] == -1 )
printf( " ");
else
printf( " %s", grammer[M[i][j]] );
}
printf( "\n" );
}
}
int is_terminal( char X )
{
for( int i = 0; i < vtnum; i++ )
{
if( X == terSymbol[i] )
return 1;
}
return 0;
}
int control()
{
char stack[1000];
int top = 0;
char input[200];
printf( "input the secentences:\n" );
scanf( "%s", input );
stack[top++] = '$';
stack[top++] = grammer[0][0];
char *p = input;
while( 1 )
{
char X = stack[top-1]; top--;
if( is_terminal(X) && X != '$' )
{
if( X == *p )
{
p++;continue;
}
else
{
printf( "wrong 1\n" );
return 0;
}
}
else
{
if( X == '$' )
{
if( X == *p )
{
printf( "end\n" );
return 1;
}
else
{
printf( "wrong!\n" );
return 0;
}
}
else
{
int t;
if( (t=M[local_nterminal(X)][local_terminal(*p)]) == -1 )
{
printf( "wrong 3!\n" );
return 0;
}
else
{
if ( grammer[t][3] == '$' )
continue;
else
{
for( int i = strlen(grammer[t])-1; i > 2; i-- )
stack[top++] = grammer[t][i];
}
}
}
}
}
};
int main()
{
pronum = 0;
char temp[100];
freopen( "1.txt", "r", stdin );
printf( "please input terminal-Symbol\n" );
scanf( "%s", terSymbol );
printf( "plaese input no-terminal-Symbol\n" );
scanf( "%s", nterSymbol );
vtnum = strlen(terSymbol);
vnnum = strlen(nterSymbol);
printf( "please input the grammarElement\n" );
while( scanf( "%s", temp) && temp[0] != '#' )
strcpy(grammer[pronum++], temp );
for( int i = 0; i < 100; i++ )
for( int j = 0; j < 100; j++ )
{
firstSET[i][j] = 0;
followSET[i][j] = 0;
}
for( int i = 0; i < vnnum; i++ )
first( nterSymbol[i] );
//print the firset set
for( int i = 0; i < vnnum; i++ )
{
for( int j = 0; j < vtnum; j++ )
printf( "%d ", firstSET[i][j] );
printf( "\n" );
}
for( int i = 0; i < vnnum; i++ )
follow( nterSymbol[i] );
//print the follow set
printf( "\n\n\n" );
for( int i = 0; i < vnnum; i++ )
{
for( int j = 0; j < vtnum; j++ )
printf( "%d ", followSET[i][j] );
printf( "\n" );
}
create_table();
if( control() )
printf( "success, this wenfa is true!!!\n\n" );
else
printf( "this wenfa is false!!\n\n" );
return 0;
}
輸入檔案
a^(),$
STB
S->a
S->^
S->(T)
T->SB
B->,SB
B->$
#
(a,a)$