zoukankan      html  css  js  c++  java
  • 作业12 实验二 递归下降语法分析

    一、实验目的:

    利用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 pg[80],token[80]; //pg用于存放输入数组,token用于存放输出数组 
    char ch;
    int r,syn,sum,m,i,p;
    char *rwtab[6]={"begin","if","then","while","do","end"};
    int z=0;
    
    
    void E();
    void T();
    void E1();
    void T1();
    void F();
    
    
    void getsyn(){
        for(i=0;i<8;i++)
            token[i]=NULL; //初始化 
        ch=pg[p++]; 
        while(ch==' '){ //如果为空格,则不进行操作,下标下移 
            ch=pg[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')){
                    token[m++]=ch;
                    ch=pg[p++];
            }
            token[m++]='';
            p--;
            syn=10;
            for(i=0;i<6;i++){
                if(strcmp(rwtab[i],token)==0){ //判断关键字是否一样 
                        syn=i+1;
                        break;
                }
            }
        }else if(ch>='0'&&ch<='9'){ //判断是否为数字 
                   sum=0;
                while(ch>='0'&&ch<='9'){
                        sum=sum*10+(ch-'0');
                        ch=pg[p++];
                }
                p--;
                syn=11;
        }else switch(ch){ //判断是否为其他字符 
                case '+':
                    token[0]=ch;syn=13;
                    break;
                case '-':
                    token[0]=ch;syn=14;
                    break;
                case '*':
                    token[0]=ch;syn=15;
                    break;
                case '/':
                    token[0]=ch;syn=16;
                    break;
                case ':':
                    i=0;
                    token[i++]=ch;
                    ch=pg[p++];
                    if(ch=='='){
                        token[i++]=ch;
                        syn=18;
                    }else{
                        syn=17;
                        p--;
                    }
                    break;
                case '<':
                    i=0; 
                    token[i++]=ch;
                    ch=pg[p++];
                    if(ch=='='){
                        token[i++]=ch;
                        syn=21;
                    }else if(ch=='>'){
                        token[i++]=ch;
                        syn=22;
                    }else{
                        syn=20;
                        p--;
                    }
                    break;
                case '>':
                    i=0;
                    token[i++]=ch;
                    ch=pg[p++];
                    if(ch=='='){
                        token[i++]=ch;
                        syn=24;
                    }else{
                        syn=23;
                        p--;
                    }
                    break;
                case '=':
                    token[0]=ch;syn=25;
                    break;
                case ';':
                    token[0]=ch;syn=26;
                    break;
                case '(':
                    token[0]=ch;syn=27;
                    break;
                case ')':
                    token[0]=ch;syn=28;
                    break;
                case '#':
                    token[0]=ch;syn=0;
                    break;
                case '
    ':
                    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 && z==0){
                    printf("success!
    ");
                }        
            }
            else{
                printf("语法错误,缺少end!
    ");
            }
        }else{
            printf("语法错误,缺少begin!
    ");
            z=1;
        }
        return ; 
        
    }
    
    void T(){
        if(syn==10){
            getsyn();
            if(syn==18){
                getsyn();
                E1();
            }else{
                printf("表达式语法有误!错误为:%s
    ",token);
                z=1;
            }
        }else{
            if(z!=1&&syn!=6){
                printf("表达式语法有误,错误为:%s
    ",token);
                z=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("没有')',语法有误!
    ");
                z=1;
            }
        }
        else{
            printf("表达式语法有误!错误为:%s
    ",token);
            z=1;
        }
        return ;
    }
    
    int main(){
        p=0;    
        printf("请输入程序段:"); 
        do{
            ch=getchar();
            pg[p++]=ch; 
        }while(ch!='#');
        p=0;
        getsyn();
        E();
        printf("分析结束!"); 
        getchar();
    }

    运行结果:

  • 相关阅读:
    PAT 甲级 1132 Cut Integer (20 分)
    AcWing 7.混合背包问题
    AcWing 9. 分组背包问题
    AcWing 5. 多重背包问题 II
    AcWing 3. 完全背包问题
    AcWing 4. 多重背包问题
    AcWing 2. 01背包问题
    AcWing 875. 快速幂
    AcWing 874. 筛法求欧拉函数
    AcWing 873. 欧拉函数
  • 原文地址:https://www.cnblogs.com/zhengjieting/p/11958571.html
Copyright © 2011-2022 走看看