编译原理上机作业3——算符优先算法

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char grammer[200][200];
char terSymbol[200];
char nterSymbol[200];
int firstVT[100][100];
int lastVT[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 )
{
    for( int i = 0; i < pronum; i++ )
    {
         if( grammer[i][0] == ch )
         {
             if( grammer[i][3] == '$' )
                 return true;
         }
    }
    return false;
}
bool have_first( int k )
{
	for( int i = 0; i < vtnum; i++ )
		if( firstVT[k][i] == 1 )
			return true;
	return false;
}
bool have_last( int k )
{
	for( int i = 0; i < vtnum; i++ )
		if( lastVT[k][i] == 1 )
			return true;
	return false;
}
void addfirstvtSet( char ch, char X )
{
	int X_num = local_nterminal(X);
	if( local_terminal(ch) != -1 )
		firstVT[X_num][local_terminal(ch)] = 1;
	else
	{
		int ch_num = local_nterminal(ch);
		for( int i = 0; i < vtnum; i++ )
			if( firstVT[ch_num][i] == 1 )
				firstVT[X_num][i] = 1;
	}
}
void addlastvtSet( char ch, char X )
{
	int X_num = local_nterminal(X);
	if( local_terminal(ch) != -1 )
		lastVT[X_num][local_terminal(ch)] = 1;
	else
	{
		int ch_num = local_nterminal(ch);
		for( int i = 0; i < vtnum; i++ )
			if( lastVT[ch_num][i] == 1 )
				lastVT[X_num][i] = 1;
	}
}
void firstvt( char X )
{
	int p, flag = 1;
	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 )
				{
					addfirstvtSet( grammer[i][p], X );
					break;
				}
				else
				{
					do
					{
					    if( grammer[i][p] != X )
						{
				            flag = 1;
				            if(!have_first(local_nterminal(grammer[i][p]))) 
				               firstvt( grammer[i][p] );
				            addfirstvtSet( grammer[i][p], X );
				            if( canbe_empty(grammer[i][p]) )
				            {
				                flag = 0;
							       p++;
				            }
				        }
				        else
				            break;
					}while( canbe_empty(grammer[i][p]) && grammer[i][p] != '\0' );
				    if( local_terminal(grammer[i][p+1]) != -1 && grammer[i][p+1] != '\0' && flag )
                        addfirstvtSet( grammer[i][p+1], X );
					break;
				}
            }
		}
	}
}
void lastvt( char X )
{
	int p, flag = 1;
	for( int i = 0; i < pronum; i++ )
	{
		if( grammer[i][0] == X )
		{
			p = strlen(grammer[i])-1;
			while( p !=  2 )
			{
				if( local_terminal(grammer[i][p]) != -1 )
				{
					addlastvtSet( grammer[i][p], X );
					break;
				}
				else
				{
					do
					{
						if( grammer[i][p] != X )
						{
							flag = 1;
							if(!have_last(local_nterminal(grammer[i][p]))) 
								lastvt( grammer[i][p] );
							addlastvtSet( grammer[i][p], X );
							if( canbe_empty(grammer[i][p]) )
							{
								flag = 0;
								p--;
							}
						}
						else
							break;

					}while( canbe_empty(grammer[i][p]) && p != 2 );
 					if( local_terminal(grammer[i][p-1]) != -1 && p != 2 && flag )
                        	addlastvtSet( grammer[i][p-1], X );
					break;

				}
			}
		}
	}
}
void print_table()
{
	char x1 = '>';
	char x2 = '<';
	char x3 = '=';
	printf( "   " );
	for( int i = 0; i < vtnum; i++ )
		printf( "%c ", terSymbol[i] );
	printf( "\n" );
	for( int i = 0; i < vtnum; i++ )
	{
		printf( "%c ", terSymbol[i] );
		for( int j = 0; j < vtnum; j++ )
		{
			if( M[i][j] == 1 )
				printf( "%2c", x1 );
			if( M[i][j] == 2 )
				printf( "%2c", x2 );
			if( M[i][j] == 3 )
				printf( "%2c", x3 );
			if( M[i][j] == -1)
				printf( "  " );
		}
		printf( "\n" );
	}
	printf( "\n\n" );
}
void create_table()
{
	/* > means 1
	 * < means 2
	 * = means 3
	 */
	for( int i = 0; i < vtnum; i++ )
		for( int j = 0; j < vtnum; j++ )
			M[i][j] = -1;
	for( int i = 0; i < vtnum; i++ )
	{
		M[i][vtnum-1] = 1;
		M[vtnum-1][i] = 2;
	}
	M[vtnum-1][vtnum-1] = 3;
	for( int i = 0; i < pronum; i++ )
	{
		int len = strlen(grammer[i]);
		for( int j = 3; j < len-1; j++ )
		{
			int a1 = local_terminal(grammer[i][j]);
			int b1 = local_terminal(grammer[i][j+1]);
			int c1 = local_terminal(grammer[i][j+2]);
			int a2 = local_nterminal(grammer[i][j]);
			int b2 = local_nterminal(grammer[i][j+1]);
			int c2 = local_nterminal(grammer[i][j+2]);
			if( a1 != -1 && b1 != -1 )
			{
				M[a1][b1] = 3;
			//	print_table();
			}
			if( j <= len-2 && a1 != -1 && b1 == -1 && c1 != -1 )
			{
				M[a1][c1] = 3;
			//	print_table();
			}
			if( a1 != -1 && b1 == -1 )
			{
				for( int i = 0; i < vtnum; i++ )
				{
					if( firstVT[b2][i] )
						M[a1][i] = 2;
				}
			//	print_table();
			}
			if( a1 == -1 && b1 != -1 )
			{
				for( int i = 0; i < vtnum; i++ )
				{
					if( lastVT[a2][i] )
						M[i][b1] = 1;
				}
			//	print_table();
			}
		}
	}

}
char prime( char * p )
{
	char temp[100];
	int flag, i, j, begin, end, begin_flag, end_flag;
	begin = -1;
	end = -1;
	i = j = 0;
	while( i < strlen(p) && j < strlen(p)-1 )
	{
		i = j;
		while( local_terminal(*(p+i)) == -1 )
			i++;
		begin = local_terminal(*(p+i));	
		j = i+1;
		while( local_terminal(*(p+j)) == -1 )
			j++;
		end = local_terminal(*(p+j));
		if( M[begin][end] == 2 )
			begin_flag = i+1;
		if( M[begin][end] == 1 )
			end_flag = j-1;
	}
	for( int i = begin_flag, j= 0; i <= end_flag; i++ )
	{
		temp[j++] = *(p+i);
		temp[j] = '\0';
	}
	for( int i = 0; i < pronum; i++ )
	{
		char a[100];
		flag = 0;
		char *p = &grammer[i][3];
		char *s = a;
		while( (*s = *p) != '\0' )
		{
			s++;
			p++;
		}
		if( !strcmp(a,temp) )
			return grammer[i][0];
	}
	return -1;
}
void control()
{
	/* This function had a little bug, but i don't wanna correct it */
	char stack[200], input[100], save[100];
	int top = 0, temp, j, find, flag;
	stack[top++] = '$';
	scanf( "%s", input );
	for( int i = 0; i < strlen(input); i++ )
	{
		flag = 1;
		int a = local_terminal(input[i]);
		if( local_terminal(stack[top-1]) != -1 )  
			find = top-1;
		else
			find = top-2;
		while( !(top ==2 && input[i] == '$') )
		{
			j = local_terminal(stack[find]);
			if( M[j][a] == 1  )		// S[j] > a 
			{
				do
				{
					find--;
					if( local_terminal(stack[find]) == -1 )
						find--;
				}while( M[local_terminal(stack[find])][j] != 2 );  // S[j] < Q
				//  stack[find+1] ---- stack[top-1] guiyue   top = find +1   
				int in = 0;
				for( int t = find; t <= top-1; t++ )
					save[in++] = stack[t];
				save[in] = '$';
				save[in+1] = '\0';
	//			printf( "%s", save );
				top = find+1;
				stack[top++] = prime( save );
	//				printf( "wrong" );
			}
			else
			{
				flag = 0;
				if( M[j][a] == 2 || M[j][a] == 3 )
					stack[top++] = input[i];
				else
					printf( "error" );
				break;
			}
		}
		if( flag )
			printf( "success\n" );
	}
}
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++ )
		{
			firstVT[i][j] = 0;
			lastVT[i][j] = 0;
		}
	for( int i = 0; i < vnnum; i++ )
		firstvt( nterSymbol[i] );
	//print the firset set
	for( int i = 0; i < vnnum; i++ )
	{
		for( int j = 0; j < vtnum; j++ )
			printf( "%d ", firstVT[i][j] );
		printf( "\n" );
	}

	for( int i = 0; i < vnnum; i++ )
		lastvt( nterSymbol[i] );
	//print the last set
	printf( "\n\n\n" );
	for( int i = 0; i < vnnum; i++ )
	{
		for( int j = 0; j < vtnum; j++ )
			printf( "%d ", lastVT[i][j] );
		printf( "\n" );
	}
	create_table();
	print_table();
	control();
	return 0;
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
优先分析法 C++ 编译原理 运行环境:Visual Studio 2005 #include "SStack.h" #include <iostream> #include <string> using namespace std; class Functor { private : char ** table; string ** production; string prog;//待分析字串 int p;//字指针 int num;//终结个数 int num1;//产生式个数 SStack <char> stack; public: Functor(int m,int n,char ** T,string **prod,string pr) { num=m; num1=n; table=T; production=prod; prog=pr; p=0; stack.push('$'); } void traversal() { while(p<(prog.length())) { stack.display(); cout<<prog.substr(p)<<" "; char ch; if(Getnum(stack.gettop())) { ch=stack.gettop(); } else { ch=stack.getsecond(); } switch(compare(ch,prog[p])) { case 1: case 2:stack.push(prog[p]);p++;cout<<"移入"<<endl;break; case 3:reduct();cout<<"归约"<<endl;break; } } cout<<"分析成功!"<<endl; } int Getnum(char ch) { for(int i=1;i<num;i++) { if(ch==table[i][0]) { return i; } } return 0; } int compare(char col,char row) { int c=Getnum(col); int r=Getnum(row); switch( table[c][r]) { case '>': return 3;break; case '<': return 2;break; case '=': return 1;break; default:cout<<endl<<"输入串有误,程序将终止!"<<endl;system("pause");exit(0);break; } } void reduct() { //待定 string token=""; int temp; string str=""; if(!Getnum(stack.gettop())) { token+=stack.gettop(); stack.pop(); } char ch=stack.gettop(); str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); bool Nover=true; while(Nover) { if(Getnum(stack.gettop())) { if(compare(stack.gettop(),ch)==2) { Nover=false; } else { ch=stack.gettop(); str=""; str+=ch; temp=Haven(str); if(temp!=-1) { token+=production[temp][0]; } else { token+=ch; } stack.pop(); } } else { token+=stack.gettop(); stack.pop(); } } string token2=""; //cout<<token<<" "; for(int i=token.length()-1;i>=0;i--) { token2+=token[i]; } //cout<<token2<<endl; if(Haven(token2)!= -1) { stack.push(production[Haven(token2)][0][0]); } else { cout<<"输入串有误!分析终止!"<<endl; system("pause"); exit(0); } } int Haven(string temp) { for(int i=0;i<num1;i++) { int j=1; while(production[i][j]!="") { if(temp==production[i][j]) { return i; } j++; } } return -1; } public: ~Functor(void) { } };

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值