• 实验二 递归下降语法分析


    一、实验目的:

    利用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 <iostream>
    #include<string.h>
    using namespace std;
    
    char *reserved[6] = {"begin","if","then","while","do","end"};
    char input[80],output[8]; 
    char ch;
    int syn,p,i;//syn
    int m = 0,n,row,sum = 0,count=0; 
    int flag = 0;//
    void ParseS();//解析语句 
    void ParseS1();
    void ParseS2();
    void ParseS3();
    void ParseS4();
    void ParseC();//解析条件 
    void ParseE();//解析表达式 
    void ParseE1();
    void ParseT();//解析项 
    void ParseT1();
    void ParseF();//解析因子 
    void scanner(){
        for( i = 0 ; i < 8 ; i++ ){
            output[i] = NULL;
        }//
        ch = input[p++];
        
        while( ch == ' ' ){
            ch = input[p] ;
            p ++ ;
        }
        //持续读入 
        if( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) ){
            m = 0 ;
            while( ( ch >= 'a' && ch <= 'z' ) || ( ch >= 'A' && ch <= 'Z' ) || ( ch >= '0' && ch <= '9' ) ){
                output[m++]  = ch ;
                ch = input[p++];
            }
            output[m++] = '';
            p -- ;
            syn = 10 ;
            for( n = 0 ; n < 6 ; n ++ ){
                if( strcmp(output,reserved[n]) == 0 ){
                    syn = n + 1;
                    break;
                }
            }
        
        }else if( ( ch >= '0' && ch <= '9' ) ){
            sum = 0 ;
            while( ch >= '0' && ch <= '9' ){
                sum=sum*10+ch-'0' ;
                ch = input[p++] ;
            }
            p -- ;
            syn = 11;
        }
        else if(ch == '/'){
            ch = input[p++] ;
            if(ch == '/'){
                while(ch != '
    '){
                    ch = input[p++] ;
                }
                scanner();    
                
            }
            else if(ch == '*'){
                ch = input[p++];
                int flag=0;
            //    printf("%c %c",ch,input[p]);
                while((ch == '*' && input[p] != '/')||(ch != '*' && input[p] == '/') || (ch != '*' && input[p] != '/')){
                    ch = input[p++] ;
                    if(p==count-2 && (ch != '*' && input[p] != '/')){
                        flag =1;
                        syn = 100;
                        break;
                    }
                }
                p++;
                if(flag==0){
                    scanner();    
                }
                
            }else{
                p = p - 2 ;
                ch = input[p++] ; 
                output[0] = ch ;
                syn = 16 ;
            } 
            
        }else switch(ch){
            case '+':
                output[0] = ch ; 
                syn = 13;
                break;
            case '-':
                output[0] = ch ; 
                syn = 14;
                break;
            case '*':
                output[0] = ch ;
                syn = 15 ;
                break;
            case '/':
                output[0] = ch ;
                syn = 16 ;
                break;
            case ':':
                i = 0;
                output[i++] = ch ;
                ch = input[p++];
                if( ch == '=' ){
                    output[i++] = ch;
                    syn = 18 ;
                }else{
                    syn = 17;
                    p-- ;
                }
                break;
            case '<':
                i = 0 ;
                output[i++] = ch ;
                ch = input[p++] ;
                if( ch == '=' ){
                    output[i++] = ch ;
                    syn = 21 ;
                }else if( ch == '>' ){
                    output[i++] = ch ;
                    syn = 22 ;
                }else{
                    syn = 20 ;
                    p-- ;
                }
                break;
            case '>':
                i = 0;
                output[i++] = ch ;
                ch = input[p++] ;
                if( ch == '=' ){
                    output[i++] = ch;
                    syn=24;
                }else{
                    syn=23;
                    p--;
                }
                break;
            case '=':
                output[0] = ch ;
                syn = 25 ;
            break;
            case ';':
                output[0] = ch ;
                syn = 26 ;
                break;
            case '(':
                output[0] = ch ;
                syn = 27 ;
                break;
            case ')':
                output[0] = ch ;
                syn = 28 ;
                break;
            case '#':
                output[0] = ch ;
                syn = 0;
                break;
            case '
    ':
                syn = 99 ;
                break;
            default:
                syn = -1 ;
                break;    
        }
        
    }
    
    void ParseS(){
        if(flag != 0){
            if(syn == 10){ //<id>:=<表达式> 
                scanner();
                ParseS1();
            }
            else if(syn == 2){ //if
                scanner();
                ParseS2();
            }
            else if(syn == 4){//while
                scanner();
                ParseS3();
            }
            else if(syn == 0){
            } 
            else{
                printf("statement syntx error S
    ");
                exit(0);
            }
        }
        else{
            if(syn == 1){//begin
            scanner();
            flag = 1;
            ParseS4();
            }else{
                printf("error,缺少begin!
    ");
                exit(0);
            }
        }
    }
    
    void ParseS1(){
        if(syn==18){
            scanner();
            ParseE();
        }
        else{
            printf("statement syntx error S1
    ");
            exit(0);
        }
    }
    void ParseS2(){//if
        ParseC(); 
        if(syn== 3 ){
            scanner();
            ParseS();
        }
        else{
            printf("statement syntx error S2
    ");
            exit(0);
        }
    }
    void ParseS3(){//while
        ParseC(); 
        if(syn== 5 ){
            scanner();
            ParseS();
        }
        else{
            printf("statement syntx error S3 
    ");
            exit(0);
        }
    }
    
    void ParseS4(){//begin
        ParseS();
        while(syn == 26){
            scanner();
            ParseS();
        }
        if(syn == 6){
            scanner();
            if(syn == 0){
                printf("success!");
            }
            else{
                printf("statement syntx error S4
    ");
            }
        }
        else{
            printf("error,缺少end
    ");
            exit(0);
        }
    }
    void ParseC(){
        ParseE();
        if(syn==25||syn==0||syn==20||syn==21||syn==23||syn==24){
            scanner();
            scanner();
        }
        else{
            printf("condition syntx error C
    ");
            exit(0);
            }
        ParseE();
     
    } 
    void ParseE(){
        ParseT();
        ParseE1();
    
    }
     
     
    
    void ParseE1(){
        if(syn == 13 || syn == 14){
            scanner();
            ParseT();
            ParseE1();
        }
        else if(syn == 28 || syn == 0){
        }    
    }
    
     
    
    void ParseT(){
        ParseF();
        ParseT1();
    }
    
     
    
    void ParseT1(){
        if(syn == 15 || syn == 16){
            scanner();
            ParseF();
            ParseT1();
        } 
        else if(syn == 13 ||syn == 14 || syn == 28 || syn == 0){    
        }
    
    }
    
    void ParseF(){
        if(syn == 27){
            scanner();
            ParseE();
            if(syn == 28){
                scanner();
            }
            else{
                printf("factor syntx error F
    ");
                exit(0);
            }
        }
        else if(syn == 10 || syn == 11){
                scanner();    
                    
        }
        else{
            printf("factor syntx error F
    ");
            exit(0);
        }
    }
    int main() {
        p = 0;
        printf("请输入源程序:");
        do{
            ch = getchar();
            input[p++] = ch;
        }while(ch != '#');
        count = p;
        p = 0;
        scanner();
        ParseS();
        return 0;
    }

  • 相关阅读:
    Ubuntu下手动安装vscode
    VMware Tools安装后设置自动挂载解决共享文件夹无法显示的问题
    VMware Tools安装方法及共享文件夹设置方法
    JavaScript原始类型转换和进制转换
    Javascript的数据类型(原始类型和引用类型)
    设计模式(六)观察者模式
    设计模式(五)之适配器模式
    设计模式(四)注册模式 解决:解决全局共享和交换对象
    设计模式(三)单例模式
    设计模式(二)之策略模式
  • 原文地址:https://www.cnblogs.com/hzxx/p/11960077.html
Copyright © 2020-2023  润新知