文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>编译原理的课程设计

编译原理的课程设计

时间:2007-01-15  来源:tthacker

假设文件的内容为 i a
* nul
i b
+ nul
i c
# nul
是一个单词二元式,对它进行不带回溯的自上而下的语法分析.    

/*
    用预测分析法(即LL(1)分析法)构造文法G[E]:
    E->E + T / T
    T->T * F / F
    F->(E) / i / x / y
    的预测分析程序(即语法分析器)。

    by wzt <[email protected]>
    
    date : 2007.1.14
*/

#include <stdio.h>
#include <string.h>

#define MAXSIZE 200
#define MAX 20
//#define DEBUG


char c[MAX]; /* 要判断的符号串 */

char *str[]={"TD","+TD","","FS","*FS","","(E)","i","x","y"}; /* 所有产生式 */

char Symbol_VT[MAX] = "+*()ixy#"; /* 所有终结符号 */
char Symbol_VN[MAX] = "EDTSF"; /* 所有非终结符号 */

char stack[MAX] = {'#','E'}; /* 分析栈 */
int top = 1;

char temp[MAX];

FILE *s_fp,*t_fp;

int M[][8] = { /* 存放str的下标,-1表示不存在 */
            {-1,-1,0,-1,0,0,0,-1},
            {1,-1,-1,2,-1,-1,-1,2},
            {-1,-1,3,-1,3,3,3,-1},
            {5,4,-1,5,-1,-1,-1,5},
            {-1,-1,6,-1,7,8,9,-1}
             };

void usage(char *pro); /* 程序帮助信息 */
void do_analyses(); /* 分析符号串 */
int VN_to_lin(char X); /* 判断非终结符所在的下标 */
int VT_to_col(char X); /* 判断终结符所在的下标 */
int is_VN(char X); /* 判断字符是否是非终结符 */
int is_VT(char X); /* 判断字符是否是终结符 */
void print_symbols(int i); /* 打印余留符号串 */
void print_stack(); /* 打印分析栈 */

int main(int argc,char **argv)
{
    char temp_str[MAXSIZE];
    char temp_code,temp_val[MAX];
    int j = 0;

    if( argc < 3 )
        usage(argv[0]);

    if( (s_fp = fopen(argv[1],"r")) == NULL ){
        printf("Can not open %s.\n",argv[1]);
        exit(1);
    }

    if( (t_fp = fopen(argv[2],"w+")) == NULL ){
        printf("Can not open %s.\n",argv[1]);
        exit(1);
    }

    while( fgets(temp_str,MAXSIZE,s_fp) != NULL ){ /* 从文件读取单词二元式 */
        sscanf(temp_str,"%c %s",&temp_code,temp_val);
        c[j++] = temp_code;
#ifdef DEBUG
        printf("%c %s\n",temp_code,temp_val);
#endif
    }

    c[j] = '\0';
#ifdef DEBUG
    printf("%s\n",c);
#endif

    do_analyses();

    fclose(s_fp);
    fclose(t_fp);

    return 0;
}

void usage(char *pro) /* 程序帮助信息 */
{
    printf("usage : %s <file_int> <file_out>\n",pro);
    exit(0);
}

void do_analyses() /* 分析符号串 */
{
    char temp_str[MAXSIZE];
    char temp_str1[MAXSIZE];
    char X;
    int i,j = 0,m,n,k;

    printf("Step Stack Symbols Syntax\n");

    for( i = 0 ; i < strlen(c) ; i++ ){
        X = stack[top--]; /*弹出栈顶元素 */
        print_symbols(i);
        stack[top + 2 ] = '\0';
        sprintf(temp_str,"%2d %-8s %-13s",j++,stack,temp);
        printf("%s",temp_str);
        fputs(temp_str,t_fp);
        if( X == '#' ){ /* 符号串匹配成功 */
            if( X == c[i] ){
                printf("Acc.\n");
            }
            else{
                printf("Symbols Error.\n");
            }
            exit(0);
        }

        if( is_VT(X) ){ /* X是终结符号且与要判断的字符相等,就继续循环 */
            printf("\n");
            fputs("\n",t_fp);
            if( X == c[i] )
                continue;
            else{
                printf("Error at %d.\n",i);
            }
        }

        if( is_VN(X) ){ /* X是非终结符号 */
            m = VN_to_lin(X); /* 求X在M数组中的纵坐标 */
            n = VT_to_col(c[i]); /* 求要判断的字符在M数组中的横坐标 */
            for( k = strlen(str[M[m][n]]) - 1 ; k >= 0 ; k-- )
                stack[++top] = *(str[M[m][n]] + k ); /* 取得产生式并反向压栈 */
            i --; /* !!! i减1,符号串要重新开始判断 */
            sprintf(temp_str1,"%c->%s\n",X,str[M[m][n]]);
            printf("%s",temp_str1);
            fputs(temp_str1,t_fp);
        }
    }
}

int VN_to_lin(char X) /* 求X在M数组中的纵坐标 */
{
    int i;

    for( i = 0 ; i < strlen(Symbol_VN) ; i++ ){
        if( X == Symbol_VN[i] )
            return i;
    }

    printf("Error. X is not in Symbol_VN \n");
    exit(0);
}

int VT_to_col(char X) /* 求要判断的字符在M数组中的横坐标 */
{
    int i;

    for( i = 0 ; i < strlen(Symbol_VT) ; i++ ){
        if( X == Symbol_VT[i] )
            return i;
    }

    printf("Error. %c is not in Symbol_VT \n",X);
    exit(0);
}

int is_VN(char X) /* X是非终结符号 */
{
    int i;

    for( i = 0 ; i < strlen(Symbol_VN) ; i++ ){
        if( X == Symbol_VN[i] )
            return 1;
    }

    return 0;
}

int is_VT(char X) /* X是终结符号 */
{
    int i;

    for( i = 0 ; i < strlen(Symbol_VT) ; i++ ){
        if( X == Symbol_VT[i] )
            return 1;
    }

    return 0;
}

void print_symbols(int i) /* 打印余留符号串 */
{
    int j,k=0;

    for( j = i ; j < strlen(c) ; j++ )
        temp[k++] = c[j];
    temp[k] = '\0';

}

void print_stack() /* 打印分析栈 */
{
    int i;

    printf(" ");
    for( i = 0 ; i <= top ; i++ )
        printf("%c",stack[i]);
}

相关阅读 更多 +
排行榜 更多 +
山雾搜剧 1.0.0

山雾搜剧 1.0.0

系统软件 下载
布鲁伊一起玩吧2025年

布鲁伊一起玩吧2025年

休闲益智 下载
最后的试炼

最后的试炼

策略塔防 下载