编译原理上机作业2——LL(1)语法分析

来源:互联网 发布:2018年 人工智能大会 编辑:程序博客网 时间:2024/05/17 08:07
#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;elsereturn 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++;elsebreak;}}}}}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;}elseprintf( "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 setp++;}if( !canbe_empty(grammer[i][p]) )//first no-emptyaddfollowSet( 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( "     ");elseprintf( " %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 setfor( 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 setprintf( "\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" );elseprintf( "this wenfa is false!!\n\n" );return 0;}
输入文件
a^(),$STBS->aS->^S->(T)T->SBB->,SBB->$#(a,a)$
原创粉丝点击