【编译原理】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

原文地址:https://www.cnblogs.com/acm-icpcer/p/8964342.html