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 <iostream>
    #include <ext/hash_map>
    #include <string.h>
    #include<map>
    using std::map;
    using namespace __gnu_cxx;
    using namespace std;
    map<string, string> m;
    string str="begin if a>9 then a:=4 end #";
    vector<string> str_list;
    vector<string> strnum;
    int select=0;
    int kk=0;
    
    void test();
    void E();
    void E1();
    void T();
    void T1();
    void F();
    void lrparser();
    void yucu();
    void statement();
    void condition();
    void expression();
    void term();
    void factor();
    
    void test(){
        select++;
        cout<<select<<"   "<<strnum[select]<<endl;
    }
    
    void init(){
         m["begin"]="1";
         m["if"]="2";
         m["then"]="3";
         m["while"]="4";
         m["do"]="5";
         m["end"]="6";
         m["+"]="13";
         m["-"]="14";
         m["*"]="15";
         m["/"]="16";
         m[":"]="17";
         m[":="]="18";
         m["<"]="20";
         m["<="]="21";
         m["<>"]="22";
         m[">"]="23";
         m[">="]="24";
         m["="]="25";
         m[";"]="26";
         m["("]="27";
         m[")"]="28";
         m["#"]="0";
    } 
    
    //字符串切割函数 
    vector<string> split(const string& str, const string& delim) {  
        vector<string> res;  
        if("" == str) return res;  
        //先将要切割的字符串从string类型转换为char*类型  
        char * strs = new char[str.length() + 1] ; 
        strcpy(strs, str.c_str());   
     
        char * d = new char[delim.length() + 1];  
        strcpy(d, delim.c_str());  
     
        char *p = strtok(strs, d);  
        while(p) {  
            string s = p; //分割得到的字符串转换为string类型  
            res.push_back(s); //存入结果数组  
            p = strtok(NULL, d);  
        }  
     
        return res;  
    }
    
    //辨别字符串是否为纯数字 
    bool AllisNum(string str)  
     {  
         for (int i = 0; i < str.size(); i++)
         {
             int tmp = (int)str[i];
             if (tmp >= 48 && tmp <= 57)
             {
                 continue;
             }
             else
             {
                 return false;
             }
         } 
         return true;
    }
    
    
    
    void scanner() {
        int chock=0;
        int row=1;
        init();
         //string str="begin a/*:=bc/:()d>=eas;dasd";
         
    //     string str;
    //     string s;
    //     cout<<"请输入字符串:"<<endl; 
    //     do{
    //         getline(cin,s);
    //         str+=s;
    //         if(str[str.size()-1]=='#'){
    //             break;
    //         }
    //        str+="
    ";
    //     }while(1);
         
         //插入空格 
         for(int i=0;i<str.size();i++){
            switch(str[i]){
                case '+':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                   
                   case '-':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                   
                   case '*':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                   /**/
                   case '/':
                       
                       if(str[i+1]=='*'){
                           
                           for(int k=i;k<str.size();k++){
                               if(str[k]=='/' && str[k-1]=='*'){
                                   cout<<"成功进入"<<endl; 
                                   str.erase(i,k-i+1);
                                   str.insert(i," ");
                                   chock=1;
                                break;    
                            }
                        }
                        
                        if(chock==0){
                            chock=0;
                            cout<<"注释方式错误不完整,错误位置第"<<row<<""<<endl ;
                            exit(0); 
                        }
                    }
                    else{
                           str.insert(i," ");
                        i++;
                        str.insert(i+1," ");
                    }
                       break;
                   
                   case ':':
                       str.insert(i," ");
                    if(str[i+2]=='=')i=i+2;else i++;
                    str.insert(i+1," ");
                       break;
                       
                   case '<':
                       str.insert(i," ");
                    if(str[i+2]=='=' || str[i+2]=='>')i=i+2;else i++;
                    str.insert(i+1," ");
                       break;
                       
                   case '>':
                       str.insert(i," ");
                    if(str[i+2]=='=')i=i+2;else i++;
                    str.insert(i+1," ");
                       break;
                   
                   case '=':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                   
                   case ';':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                       
                   case '(':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                   
                   case ')':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                       
                   case '#':
                       str.insert(i," ");
                    i++;
                    str.insert(i+1," ");
                       break;
                       
                   case '
    ':
                       str.insert(i," ");
                    i++;
                    row++;
                    str.insert(i+1," ");
                       break;
           }         
         }
         
         for(int i=0;i<str.size();i++){
             cout<<str[i];
         }
         cout<<endl;
        
        //切割空格 
         
        str_list=split(str," ");
        
        //输出对应序列 
        for(int i = 0; i < str_list.size(); i++)
        {
    
            if (m.find(str_list[i]) != m.end()){
                cout<<"	< "<<str_list[i] <<","<<m[str_list[i]]<<" >"<<endl;
                strnum.push_back(m[str_list[i]]);
            }    
            else if(AllisNum(str_list[i])){        
                cout<<"	< "<<str_list[i] <<","<<11<<" >"<<endl;
                strnum.push_back("11");
            }
            else {
                cout<<"	< "<<str_list[i] <<","<<10<<" >"<<endl; 
                strnum.push_back("10");
            }
    
        }
        
        for(int i = 0; i < strnum.size(); i++){
            cout<<strnum[i]<<"  ";
        }
    
    }
    
    //void E(){
    //    if(select==strnum.size())return;
    //    T();
    //    E1();                                                               
    //}
    //
    //void E1(){
    //    if(select==strnum.size())return;
    //    if(strnum[select]=="13"){
    //        select++;
    //        T();
    //        E1();
    //    }
    //    else if(strnum[select]=="0" || strnum[select]=="28"){
    //
    //    }
    //    else cout<<"error : "<<select;     
    //     
    //}
    //
    //void T(){
    //    if(select==strnum.size())return;
    //    F();
    //    T1();
    //}
    //
    //void T1(){
    //    if(select==strnum.size())return;
    //    if(strnum[select]=="15"){
    //        select++;
    //        F();
    //        T1();
    //    }
    //    else if(strnum[select]=="0" || strnum[select]=="13" || strnum[select]=="28"){
    //
    //    }
    //    else cout<<"error : "<<select;     
    //
    //}
    //
    //void F(){
    //    if(select==strnum.size())return;
    //    if(strnum[select]=="27"){
    //        select++;
    //        E();
    //        if(strnum[select]=="28"){}
    //        else cout<<"error : "<<select;     
    //    }
    //    else if(strnum[select]=="10"){ 
    //        select++;
    //    }
    //    else cout<<"error : "<<select;         
    //}
    
    //程序,判断是否以begin开始,end #结束 
    void lrparser(){
        if (strnum[select]=="1") { //begin
            test();
            yucu();
            if (strnum[select]=="6") { //end
                test();
                if (strnum[select]=="0" && kk==0){
                    printf("success 
    ");
                } 
            } 
            else {
                printf("error,lose 'end' ! 
    ");
                kk=1;
                exit(0);
            }
        } 
        else {
            printf("error,lose 'begin' ! 
    ");
            kk=1;
            exit(0);
        }
        return;
    }
    
    //语句串 
    void yucu() {
        statement();
        while(strnum[select]=="26") { 
            test();
            statement();
        }
        return;
    }
    
    //语句 
    void statement(){
        if (strnum[select]=="10") { //为标识符
            test();
            if (strnum[select]=="18") { //为 :=
                test();
                expression();
            } 
            else {
                printf("error!");
                kk=1;
                exit(0);
            }
        }
        else if(strnum[select]=="2"){  //为if 
            test();
            condition();
            if(strnum[select]=="3"){
                test();
                statement(); 
            }
            else{
                printf("error,lose 'then' ! 
    ");
                kk=1;
                exit(0);
            }
        }
        else {
            printf("error!");
            kk=1;
            exit(0);
        }
        
        return;
    }
    //条件
    void condition(){
        expression();
        if(strnum[select]=="25"||strnum[select]=="0"||strnum[select]=="20"||strnum[select]=="21"||strnum[select]=="23"||strnum[select]=="24"){
            
            test(); 
        }
        else{
            printf("error! 
    ");
            kk=1;
            exit(0);
        }
        expression();
        return;
    } 
    //表达式 
    void expression(){
        term();
        while(strnum[select]=="13" || strnum[select]=="14") {
            test();
            term();
        }
        return;
    }
    //
    void term(){
        factor();
        while(strnum[select]=="15" || strnum[select]=="16") {
            test();
            factor();
        }
        return;
    }
    //因子 
    void factor(){
        if(strnum[select]=="10" || strnum[select]=="11"){
            test(); //为标识符或整常数时,读下一个单词符号
        }
        else if(strnum[select]=="27") {
            test();
            expression();
            if(strnum[select]=="28"){
                test();
            }
            else {
                printf(" ')' 错误
    ");
                kk=1;
                exit(0);
            }
        } else {
            cout<<select<<"  asdsada"<<endl;
            printf("表达式错误
    ");
            kk=1;
            exit(0);
        }
        return;
    }
    int main(){
        scanner();
        cout<<endl;
        lrparser();
        
    }

    测试

     

  • 相关阅读:
    [C#]MagicLibrary.dll控件的使用(一)(下拉菜单)
    [SQL server]查询用户表及表结构
    [ASP.net]ASP.net的RUL重写
    [C#]简单XP菜单的实现(一)
    [Javascript]IFRAME运用(1)
    [ASP.net]未解的疑惑!
    [乱七八糟]Google搜索使用详细
    [Javascript]IFRAME运用(2)
    [随文杂记]残局
    [CSS]RevealTrans 滤镜
  • 原文地址:https://www.cnblogs.com/renshenbenzuig/p/11958725.html
Copyright © 2011-2022 走看看