作业十二

一、实验目的:

利用C语言编制递归下降分析程序,并对简单语言进行语法分析。

编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。

 

二、实验原理

每个非终结符都对应一个子程序。

该子程序根据下一个输入符号(SELECT集)来确定按照哪一个产生式进行处理,再根据该产生式的右端:

  • 每遇到一个终结符,则判断当前读入的单词是否与该终结符相匹配,若匹配,再读取下一个单词继续分析;不匹配,则进行出错处理
  • 每遇到一个非终结符,则调用相应的子程序

 

三、实验要求说明

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”,并指出语法错误的类型及位置。

例如:

输入begin a:=9;x:=2*3;b:=a+x end #

输出success

输入x:=a+b*c  end #

输出‘end' error

 

四、实验步骤

1.待分析的语言的语法(参考P90)

2.将其改为文法表示,至少包含

–语句

–条件

–表达式

3. 消除其左递归

4. 提取公共左因子

5. SELECT集计算

6. LL(1)文法判断

7. 递归下降分析程序

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

 

char wsym[80],ssym[80];

char ch;

int row,syn,sum,m,i,p;

char *word[6]={"begin","if","then","while","do","end"};

int flag=0;

 

void E();

void T();

void E1();

void T1();

void F();

 

void getsyn(){

    for(i=0;i<8;i++)

        ssym[i]=NULL;

    ch=wsym[p++];

    while(ch==' '){

        ch=wsym[p];

        p++;

    }

    if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){

        m=0;

        while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z')){

            ssym[m++]=ch;

            ch=wsym[p++];

        }

        ssym[m++]='\0';

        p--;

        syn=10;

        for(i=0;i<6;i++){

            if(strcmp(word[i],ssym)==0){

                syn=i+1;

                break;

            }

        }

    }else if(ch>='0'&&ch<='9'){

        sum=0;

        while(ch>='0'&&ch<='9'){

            sum=sum*10+(ch-'0');

            ch=wsym[p++];

        }

        p--;

        syn=11;

    }else switch(ch){

        case '+':

            ssym[0]=ch;syn=13;

            break;

        case '-':

            ssym[0]=ch;syn=14;

            break;

        case '*':

            ssym[0]=ch;syn=15;

            break;

        case '/':

            ssym[0]=ch;syn=16;

            break;

        case ':':

            i=0;

            ssym[i++]=ch;

            ch=wsym[p++];

            if(ch=='='){

                ssym[i++]=ch;

                syn=18;

            }else{

                syn=17;

                p--;

            }

            break;

        case '<':

            i=0;

            ssym[i++]=ch;

            ch=wsym[p++];

            if(ch=='='){

                ssym[i++]=ch;

                syn=21;

            }else if(ch=='>'){

                ssym[i++]=ch;

                syn=22;

            }else{

                syn=20;

                p--;

            }

            break;

        case '>':

            i=0;

            ssym[i++]=ch;

            ch=wsym[p++];

            if(ch=='='){

                ssym[i++]=ch;

                syn=24;

            }else{

                syn=23;

                p--;

            }

            break;

        case '=':

            ssym[0]=ch;syn=25;

            break;

        case ';':

            ssym[0]=ch;syn=26;

            break;

        case '(':

            ssym[0]=ch;syn=27;

            break;

        case ')':

            ssym[0]=ch;syn=28;

            break;

        case '#':

            ssym[0]=ch;syn=0;

            break;

        case '\n':

            syn=100;

            break;

        default:

            syn=-1;

            break;

    }

}

 

void E(){

    if(syn==1){

        getsyn();

        T();

        while(syn==26){

            getsyn();

            T();

        }

        if(syn==6){

            getsyn();

            if(syn==0 && flag==0){

                printf("success!\n");

            }       

        }

        else{

            printf("语法错误,缺少end!\n");

        }

    }else{

        printf("语法错误,缺少begin!\n");

        flag=1;

    }

    return ;

   

}

 

void T(){

    if(syn==10){

        getsyn();

        if(syn==18){

            getsyn();

            E1();

        }else{

            printf("表达式语法有误!错误为:%s\n",ssym);

            flag=1;

        }

    }else{

        if(flag!=1){

            printf("表达式语法有误,错误为:%s\n",ssym);

            flag=1;

        }

       

    }

}

 

void E1(){

    T1();

    while(syn==13||syn==14){

        getsyn();

        T1();

    }

    return ;

}

 

void T1(){

    F();

    while(syn==15||syn==16){

        getsyn();

        F();

    }

    return ;

}

void F(){

    if(syn==10||syn==11){

        getsyn();

    }else if(syn==27){

        getsyn();

        E1();

        if(syn==28)

            getsyn();

        else{

            printf("没有')',语法有误!\n");

            flag=1;

        }

    }

    else{

        printf("表达式语法有误!错误为:%s\n",ssym);

        flag=1;

    }

    return ;

}

 

 

int main(){

    p=0;

    printf("请输入语句段(以#号结束):");

    do{

        ch=getchar();

        wsym[p++]=ch;

    }while(ch!='#');

    p=0;

    getsyn();

    E();

    printf("分析结束!");

    getchar();   

}

 

 

 

 

 

 

 

posted @ 2019-11-29 14:54  董学沉啦  阅读(147)  评论(0编辑  收藏  举报