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

    一、实验目的:

    利用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 prog[]="a+b*c end#",token[20]; //输入程序段,单词符号
    char ch;
    int syn,p,m,n,sum;//单词符号类型syn,整数sum
    char *rwtab[6] = {"begin","if","then","while","do","end"};
     
    void E();
    void T();
    void E1();
    void T1();
    void F();
    void error();
     
    void scaner(){
        for (n=0;n<20;n++)
            token[n]=NULL;
        m=0;
        sum=0;
        ch=prog[p++];
        while(ch==' '){ //跳过空格
            ch=prog[p++];
        }
        if(ch>='a'&&ch<='z'){ //判断单词
            while(ch>='a'&&ch<='z'){
                token[m++]=ch;
                ch=prog[p++];
            }
            syn=10;
            p--;
            for(n=0;n<6;n++){
                if(strcmp(token,rwtab[n])==0){
                    syn=n+1;
                    break;
                }
            }
        }
        else{  
            if(ch>='0'&&ch<='9'){ //判断数字
                while(ch>='0'&&ch<='9'){
                    sum=sum*10+(ch-'0');
                    ch=prog[p++];
                }
                syn=11;
                p--;
            }
            else{
                switch(ch){
                    case '<':
                        token[m++]=ch;
                        ch=prog[p++];
                        if(ch=='>'){ //<>
                            syn=22;
                            token[m++]=ch;
                        }
                        else if(ch=='='){   //<=
                            syn=21;
                            token[m++]=ch;
                        }
                        else{   //<
                            syn=20;
                            p--;
                        }
                        break;
                     
                    case '>':
                        m=0;
                        token[m++]=ch;
                        ch=prog[p++];
                        if(ch=='='){    //>=
                            syn=24;
                            token[m++]=ch;
                        }
                        else{   //>
                            syn=23;
                            p--;
                        }
                        break;
                         
                    case ':':
                        m=0;
                        token[m++]=ch;
                        ch=prog[p++];
                        if(ch=='='){    //:=
                            syn=18;
                            token[m++]=ch;
                        }
                        else{   //:
                            syn=17;
                            p--;
                        }
                        break;
                         
                    case '+':syn=13;token[0]=ch;break;
                    case '-':syn=14;token[0]=ch;break;
                    case '*':syn=15;token[0]=ch;break;
                    case '/':syn=16;token[0]=ch;break;
                    case '=':syn=25;token[0]=ch;break;
                    case ';':syn=26;token[0]=ch;break;
                    case '(':syn=27;token[0]=ch;break;
                    case ')':syn=28;token[0]=ch;break;
                    case '#':syn=0;token[0]=ch;break;
                    default:syn=-1;token[0]=ch;break;
                }
            }
        }
    }
     
    void E(){
        T();
        E1();
    }
     
     
     
    void E1(){
        if (syn == 13){
            scaner();
            T();
            E1();
        }
        else if(syn ==0 || syn == 28){
             
        }
        else
            error();
    }
     
    void T(){
        F();
        T1();
    }
     
    void T1(){
        if(syn == 15){
            scaner();
            F();
            T1();
        }
        else if (syn == 0 || syn == 28 || syn ==13){
             
        }
        else
            error();
    }
     
    void F(){
        if(syn == 27){
            scaner();
            E();
            if(syn == 28){
                scaner();
                printf("success
    ");
            }
            else
                error();
        }
        else if(syn == 11 || syn == 10){
            scaner();
            printf("success
    ");
        }  
        else
            error();
    }
     
    void error(){
        printf("error
    ");
        printf("
    (%s,出错!)",token);
    }
     
    main(){
        scaner();
        E();
    }
    

      

     测试结果:

     

  • 相关阅读:
    pycharm中以pytest的方式运行测试用例
    jmeter 固定吞吐量控制器 Constant Throughput Timer
    jmeter 循环控制器使用
    jmeter 24个常用函数
    jmeter 参数化取唯一值
    jmeter之json提取器
    【转】Jmeter如何把响应数据的结果保存到本地的一个文件
    jmeter测试并发
    jmeter参数为Excel表格
    jmeter接口调用
  • 原文地址:https://www.cnblogs.com/zzj420133722/p/11944001.html
Copyright © 2011-2022 走看看