zoukankan      html  css  js  c++  java
  • 【编译原理】c++实现自上而下语法分析器

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文!

    本博客全网唯一合法URL:http://www.cnblogs.com/acm-icpcer/p/8964342.html

      使用递归下降子程序实现的PL/0语言的算术表达式的自上而下语法分析。该语言的其他语法实现思想与此一致,故不赘述。

      运行此程序前,必须先将代码通过:【编译原理】c++实现词法分析器的词法分析,生成词法表(词法表是txt文件,为了语法分析成功,务必删除文件中最后空着的一行,即文件末尾不可以留空白行)。生成的该词法表为此程序的必要输入。

    /*
    this code was first initiated by TZ,COI,HZAU
    contact email:xmb028@163.com
    personal website:wnm1503303791.github.io
    personal blogs:www.cnblogs.com/acm-icpcer/
    this code has been posted on my personal blog,checking url:www.cnblogs.com/acm-icpcer/p/8964342.html
    Copyright 2018/4/27 TZ.
    All Rights Reserved.
    */
    
    #include<cstdio>  
    #include<cstring>  
    #include<algorithm>  
    #include<iostream>  
    #include<string>  
    #include<vector>  
    #include<stack>  
    #include<bitset>  
    #include<cstdlib>  
    #include<cmath>  
    #include<set>  
    #include<list>  
    #include<deque>  
    #include<map>  
    #include<queue>  
    #include<fstream>
    using namespace std;
    
    /*
    S->X(AX)*|AX(AX)*
    X->Y(MY)*
    Y->I|N|(S)
    A->+|-
    M->*|/
    C->=|#|<|<=|>|>= 
    */
    char buffer[1024];
    bool x(fstream &f);
    bool s(fstream &f);
    
    bool preproccess(char *a,char *b)
    {
        int i1=0,i2=1;
        memset(b,1024,'');
        while(a[i2]!=',')
        {
            b[i1]=a[i2];
               ++i1,++i2;
        }
        return true;
    }
    
    bool a(fstream &f)
    {
        f.getline(buffer,1024);
        char t[1024];//存放字符标志 
        preproccess(buffer,t);
        cout<<buffer<<","<<t<<endl;
        
        if((!strcmp(t,"plus"))||(!strcmp(t,"minus")))
        {
            return true;
        }
        else 
        {
            cout<<"add operator ERROR"<<endl;
            return false;
        }
    }
    
    bool m(fstream &f)
    {
        f.getline(buffer,1024);
        char t[1024];//存放字符标志 
        preproccess(buffer,t);
        cout<<buffer<<","<<t<<endl;
        
        if((!strcmp(t,"times"))||(!strcmp(t,"slash")))
        {
            return true;
        }
        else 
        {
            cout<<"times operator ERROR"<<endl;
            return false;
        }
    }
    
    bool c(fstream &f)
    {
        f.getline(buffer,1024);
        char t[1024];//存放字符标志 
        preproccess(buffer,t);
        cout<<buffer<<","<<t<<endl;
        
        if    (    (!strcmp(t,"eql"))
                ||(!strcmp(t,"lss"))
                ||(!strcmp(t,"leq"))
                ||(!strcmp(t,"gtr"))
                ||(!strcmp(t,"geq"))
              )
        {
            return true;
        }
        else 
        {
            cout<<"compare operator ERROR"<<endl;
            return false;
        }
    }
    
    bool y(fstream &f)
    {
        f.getline(buffer,1024);
        char t[1024];//存放字符标志 
        preproccess(buffer,t);
        cout<<buffer<<","<<t<<endl;
        
        if(!strcmp(t,"ident"))
        {
            return true;
        }
        else if(!strcmp(t,"number"))
        {
            return true;
        }
        else if(!strcmp(t,"lparen"))
        {
            s(f);
            
            f.getline(buffer,1024);
                preproccess(buffer,t);
            cout<<buffer<<","<<t<<endl;
            
            if(!strcmp(t,"rparen"))
            {
                return true;
            }
            else
                return false;
        }
        else 
        {
            cout<<"yingzi operator ERROR"<<endl;
            return false;
        }
    }
    
    bool x(fstream &f)
    {
        bool /*a1=y(f),*/a2=false,a3=false;
        while(!f.eof())
        {
            a2=m(f);
            a3=y(f);    
        }
        return (a2)&a3;
    }
    
    bool s(fstream &f)
    {
        bool a1=false,a2=false;
        while(!f.eof())
        {
            a1=y(f);
            a2=x(f);
        }
        return a1&a2;
    }
    
    int main()
    {
        fstream f1,f2;
        f1.open("lexical.txt", ios::in);//打开文件,供读
        f2.open("lexical.txt", ios::in);
        
           bool result1=s(f1);//start the grammar detection
           /*
           cout<<"break:"<<endl;
           bool result2=x(f2);
           */
           if(result1/*||result2*/)
               cout<<"ACCEPTED!"<<endl;
        else
            cout<<"ERROR!"<<endl;
        
        f1.close();
        f2.close();
        return 0;
    }

    运行示例:

    1、在词法分析器中输入待分析代码:

    2、检查词法分析表,删除文件最后的空行:

     

    3、运行本次的语法分析程序:

     

    附产生式推导过程:

    tz

    first posted@COI HZAU,2018/4/27

    last updated@COI HZAU,2018/4/28

  • 相关阅读:
    Docker03-镜像
    Docker02:Centos7.6安装Docker
    Docker01-重要概念
    WEB开发新人指南
    Lpad()和Rpad()函数
    Unable to find the requested .Net Framework Data Provider. It may not be installed
    redis自动过期
    redis简单的读写
    redis的安装
    Ajax缓存,减少后台服务器压力
  • 原文地址:https://www.cnblogs.com/acm-icpcer/p/8964342.html
Copyright © 2011-2022 走看看