컴파일링 원리 탑승 작업 2 - LL (1) 문법 분석

#include 
#include 
#include 
#include 

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( "
" ); } } 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:
" ); 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
" ); return 0; } } else { if( X == '$' ) { if( X == *p ) { printf( "end
" ); return 1; } else { printf( "wrong!
" ); return 0; } } else { int t; if( (t=M[local_nterminal(X)][local_terminal(*p)]) == -1 ) { printf( "wrong 3!
" ); 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
" ); scanf( "%s", terSymbol ); printf( "plaese input no-terminal-Symbol
" ); scanf( "%s", nterSymbol ); vtnum = strlen(terSymbol); vnnum = strlen(nterSymbol); printf( "please input the grammarElement
" ); 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( "
" ); } for( int i = 0; i < vnnum; i++ ) follow( nterSymbol[i] ); //print the follow set printf( "


" ); for( int i = 0; i < vnnum; i++ ) { for( int j = 0; j < vtnum; j++ ) printf( "%d ", followSET[i][j] ); printf( "
" ); } create_table(); if( control() ) printf( "success, this wenfa is true!!!

" ); else printf( "this wenfa is false!!

" ); return 0; }
    
a^(),$
STB
S->a
S->^
S->(T)
T->SB
B->,SB
B->$
#
(a,a)$

좋은 웹페이지 즐겨찾기