写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.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