• 第十二次作业——实验二-递归下降语法分析


    一、实验目的:

    利用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>
    
    #define gjword 13         //关键字个数
    
    #define max 10           //标识符的最长长度
    
    #define getchdo         if(-1==getch()) return -1;
    
    char ch;                //读取的字符
    char ch1[10];                //存放字符 
    char id[max+1];          //传递标识符单词 
    int num;                //传递数值 
    int js, js2;             
    char find[100];
    char a[max+1];           //暂时存储符号
    char word[gjword][max];    //保留字
    int sym;                 //符号类型 
    
    FILE* input;
    void E();
    void E1();
    void T();
    void T1();
    void F();
    void error();
     
    int getch()
    {
        if(js == js2)
        {
            if(feof(input))
            {
                printf("
    词法分析完毕!
    ");
                return -1;
            }
            js2 = 0;
            js = 0;
            ch = ' ';
            while(ch != '
    ')
            {
                if(fscanf(input, "%c", &ch) == EOF)
                {
                    find[js2] = 0;
                    break;
                }
    //            printf("%c", ch);
                find[js2] = ch;
                js2++;
            }
            printf("
    ");
        }
        ch = find[js];
        js++;
        return 0;
    }
     
    int getsym()
    {
        int i, j, k;
        while(ch == ' ' || ch == '
    ' )
        {
            getchdo;
        }
        if(ch >= 'a' && ch <= 'z')
        {
            k = 0;
            do
            {
                if(k < max)
                {
                    a[k] = ch;
                    k++;
                }
                getchdo;
            }while(ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9');
            a[k] = '';
            strcpy(id, a);
            i = 0;
            j = gjword-1;
            do
            {
                k = (i+j)/2;
                if(strcmp(id, word[k]) <= 0)
                    j = k-1;
                if(strcmp(id, word[k]) >= 0)
                    i = k+1;
            }while(i <= j);
     
            if(i-1 > j)
            {
    //            printf("保留字 ('%s')
    ", id);
                sym=i;
                strcpy(ch1, id); 
            }
            else
            {
    //            printf("标识符 ('%s')
    ", id);
                sym=10;
                strcpy(ch1, id); 
                k--; 
            }
        }
        else{
            if(ch >= '0' && ch <= '9')
            {
                k = 0;
                num = 0;
                do
                {
                    num = num * 10 + ch - '0';
                    k++;
                    getchdo;
                }while(ch >= '0' && ch <= '9');
                k--;         
    //            printf("整 数 ('%d')
    ",num);
                sym=11; 
            }
            else
            {
                switch(ch){
                    case ':':getchdo;
                            k++;
                            if(ch == '=')
                            {
                                sym=18; 
    //                            printf("运算符 (':=')
    ");
                                strcpy(ch1, ":="); 
                                getchdo;
                                break;
                            }
                            else
                            {
    //                             printf("符号(':')
    ");
                                 sym=17;
                                 ch1[0]=ch;
                                 k--;
                                 break; 
                            }
                    case '<':getchdo;
                            k++;
                            if(ch == '=')
                            {
    //                            printf("运算符 ('<=')
    ");
                                sym=21;
                                strcpy(ch1, "<=");
                                getchdo;
                                break;
                            }
                            else if(ch == '>'){
                                sym=22;
                                strcpy(ch1, "<>");
                                break;
                            }
                            else
                            {
    //                            printf("运算符 ('<')
    ");
                                sym=20;
                                ch1[0]=ch;
                                k--;
                                break;
                            }
                    case '>':getchdo;
                            k++;
                            if(ch == '=')
                            {
    //                            printf("运算符 ('>=')
    ");
                                sym=24;
                                strcpy(ch1, ">=");
                                getchdo;
                                break;
                            }
                            else
                            {
    //                            printf("运算符 ('>')
    ");
                                sym=23;
                                ch1[0]=ch;
                                k--;
                                break;
                            }
                    case '+':
    //                        printf("运算符 ('+')
    ");
                                sym=13;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case '-':
    //                        printf("运算符 ('-')
    ");
                                sym=14;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case '*':
    //                        printf("运算符 ('*')
    ");
                                sym=15;
                                ch1[0]=ch;
                                getchdo;                            
                                break;
                    case '/':
    //                        printf("运算符 ('/')
    ");
                                sym=16;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case '=':
    //                        printf("运算符 ('=')
    ");
                                sym=25;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case ';':
    //                        printf("分界符 (';')
    ");
                                sym=26;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case '(': 
    //                        printf("分界符 ('(')
    ");
                                sym=27;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case ')':
    //                        printf("分界符 (')')
    ");
                                sym=28;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    case '#':
    //                        printf("分界符 ('#')
    ");
                                sym=0;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    default:
    //                        printf("其他字符('%c')
    ",ch);
                                sym=-1;
                                ch1[0]=ch;
                                getchdo;
                                break;
                    }
                }
            }
        return 0;
    }
    void init()
    {
    
        strcpy(&(word[0][0]), "begin");
        strcpy(&(word[1][0]), "if");
        strcpy(&(word[2][0]), "then");
        strcpy(&(word[3][0]), "while");
        strcpy(&(word[4][0]), "do");
        strcpy(&(word[5][0]), "end");
        strcpy(&(word[6][0]), "void");
        strcpy(&(word[7][0]), "struct");
    
    }
    
    void E(){
        T();
        E1();
    }
     
    void E1(){
        if(sym == 13){
            getsym();
            T();
            E1();
        }
        else if(sym == 0 || sym == 28){
            
        }
        else{
            error();
        }
    }
    
    void T(){
        F();
        T1();
    }
    
    void T1(){
        if(sym == 15){
            getsym();
            F();
            T1();
        }
        else if(sym==0 || sym==28 ||sym==13){
            
        }
        else{
            error();
        }    
    }
    void F(){
        if(sym == 27){
            getsym();
            E();
            if(sym == 28){
                getsym();
            }
            else{
                error();
            }
        }
        else if(sym == 11 || sym == 10){
            getsym();
        }
        else{
            error();    
        }    
    }
    
    void error(){
        printf("
    (%s,文法出错!)
    ",ch1);
    }
    
    
    int main()
    {
    
        input = fopen("test.txt", "r");
        if(input)
        {
            init();
            js = js2 = 0;
            ch = ' ';
    //        while(getsym() != -1)
    //        {
              getsym();
              E();
    //        }        
        }
        else
        {
            printf("找不到文件
    ");
        }
        printf("
    ");
        return 0;
    }

    运行结果:

     

  • 相关阅读:
    Android深度探索--HAL与驱动开发----第十章读书笔记
    Android深度探索--HAL与驱动开发----第九章读书笔记
    Android深度探索--HAL与驱动开发----第八章读书笔记
    Android深度探索--HAL与驱动开发----第七章读书笔记
    Android深度探索--HAL与驱动开发----第六章读书笔记
    Android深度探索--HAL与驱动开发----第五章读书笔记
    Android深度探索--HAL与驱动开发----第四章读书笔记
    Android深度探索--HAL与驱动开发----第三章读书笔记
    Android深度探索--HAL与驱动开发----第二章读书笔记
    Android深度探索--HAL与驱动开发----第一章读书笔记
  • 原文地址:https://www.cnblogs.com/a1120139442/p/11946646.html
Copyright © 2020-2023  润新知