递归下降语法分析
一、功能描述:
构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,进一步掌握递归下降的语法分析方法。
构造文法的语法分析程序,要求采用递归下降语法分析方法对输入的字符串进行语法分析,进一步掌握递归下降的语法分析方法。
二、初始步骤:
先将文法:
先将文法:
E-->E+T|T
T-->T*F|F
F-->(E)|i
T-->T*F|F
F-->(E)|i
转换成LL(1)文法:
E-->TS
S-->+TS|ε
T-->FN
N-->*FN|ε
F-->(E)|i
S-->+TS|ε
T-->FN
N-->*FN|ε
F-->(E)|i
得到
First(S) = { + } Follow(S) = { }, # }
First(N) = { * } Follow(N) = { +, }, # }
Fisrt(F) = { ( }
First(N) = { * } Follow(N) = { +, }, # }
Fisrt(F) = { ( }
三、程序结构描述:
全局变量:
全局变量:
set<char> firstS, firstN, firstF; ——非终结符S、N、F的First集合
set<char> followS, followN; ——非终结符S、N的Follow集合
string s; ——输入的字符串
int i; ——当前读到的位置
set<char> followS, followN; ——非终结符S、N的Follow集合
string s; ——输入的字符串
int i; ——当前读到的位置
程序分成如下几个函数:
void init() ——初始化函数:初始化各个非终结符的First集合和Follow集合。
void printSuccess(); ——打印正确信息
void printError() ; ——打印错误信息
void printError() ; ——打印错误信息
bool getNext(); ——获得串中的下一个字符,如果已结束则返回false
bool checkE(); ——匹配E文法,不匹配则返回false
bool checkS(); ——匹配S文法,不匹配则返回false
bool checkT(); ——匹配T文法,不匹配则返回false
bool checkN(); ——匹配N文法,不匹配则返回false
bool checkF(); ——匹配F文法,不匹配则返回false
bool checkS(); ——匹配S文法,不匹配则返回false
bool checkT(); ——匹配T文法,不匹配则返回false
bool checkN(); ——匹配N文法,不匹配则返回false
bool checkF(); ——匹配F文法,不匹配则返回false
main ——主函数
处理输入串的部分,若输入为“.”则退出循环,否则对指定文件进行语法分析。
处理输入串的部分,若输入为“.”则退出循环,否则对指定文件进行语法分析。
程序总体执行流程详见代码。
四、实验总结:
完成总使用四课时:
其中纸上时间一课时,编程两课时,调试一课时。
完成总使用四课时:
其中纸上时间一课时,编程两课时,调试一课时。
问题:
程序只适合固定的语法:代码重用性差。
程序只适合固定的语法:代码重用性差。
收获:
了解到一些语法分析的知识。
了解到一些语法分析的知识。
五、程式源码:
-
#include<iostream>
-
#include<string>
-
#include<set>
-
using namespace std;
-
-
set<char> firstS, firstN, firstF;
-
set<char> followS, followN;
-
-
bool checkE();
-
bool checkS();
-
bool checkT();
-
bool checkN();
-
bool checkF();
-
void printError();
-
void printSuccess();
-
-
string s;
-
int i;
-
-
bool getNext(){
-
if(++i==s.size()){
-
//cout<<"Finish!"<<endl;
-
return false;
-
}
-
return true;
-
}
-
-
void init(){
-
firstS.insert('+');
-
firstN.insert('*');
-
firstF.insert('(');
-
-
followS.insert(')');
-
followS.insert('#');
-
-
followN.insert('+');
-
followN.insert(')');
-
followN.insert('#');
-
}
-
-
bool checkE(){
-
return(checkT()&&checkS());
-
}
-
-
bool checkS(){
-
if(firstS.find(s[i])!=firstS.end()){ // 如果token属于FIRST(S):+
-
return(getNext()&&checkT()&&checkS());
-
}else{
-
if(followS.find(s[i])==followS.end()){ // 如果token不属于FOLLOW(S)则报错
-
printError();
-
return false;
-
}
-
}
-
return true;
-
}
-
-
bool checkT(){
-
return(checkF()&&checkN());
-
}
-
-
bool checkN(){
-
if(firstN.find(s[i])!=firstN.end()){ // 如果token属于FIRST(N):*
-
return(getNext()&&checkF()&&checkN());
-
}else{
-
if(followN.find(s[i])==followN.end()){ // 如果token不属于FOLLOW(N)则报错
-
printError();
-
return false;
-
}
-
}
-
return true;
-
}
-
-
bool checkF(){
-
if(firstF.find(s[i])!=firstF.end()){ // 如果token属于FIRST(F):(
-
if(!getNext())return false;
-
if(!checkE())return false;
-
if(s[i]==')'){
-
return(getNext());
-
}else{
-
printError();
-
return false;
-
}
-
}else{
-
if(s[i]=='i'){ // 如果token=='i'
-
return(getNext());
-
}else{
-
printError();
-
return false;
-
}
-
}
-
}
-
-
void printSuccess(){
-
cout<<"Success!"<<endl;
-
}
-
-
void printError(){
-
cout<<"Error in Location["<<(i+1)<<"]: "<<s[i]<<endl;
-
}
-
-
int main(){
-
char token;
-
init();
-
-
cout<<"input string(end of '#', if u want to exit, just press '.'):"<<endl;
-
-
while(cin>>s){
-
if(s==".")break;
-
i = -1;
-
-
if(getNext()&&checkE()){
-
printSuccess();
-
}
-
-
cout<<endl;
-
}
-
-
return 0;
-
}