写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.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,'\0');
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
来源:oschina
链接:https://my.oschina.net/u/4383058/blog/3992349