目的:熟练掌握自上而下的语法分析方法,并能用程序实现。
要求:
1. 使用的文法如下:
- E->TE'
- E' -> _TE'|#
- T->FT'
- T'->*FT'|#
- F-> (E)|id
2. 对于任意给定的输入串(词法记号流)进行语法分析,非递归预测分析方法可以任选其一来实现。
3. 要有一定的错误处理功能。即对错误能提示,并且能在一定程度上忽略尽量少的记号来进行接下来的分析。可以参考书上介绍的同步记号集合来处理。
可能的出错情况:idid*id, id**id, (id+id, +id*+id ……
4. 输入串以#结尾,输出推导过程中使用到的产生式。例如:
输入:id+id*id#
- E ® TE ¢
输出:E -> TE'
T -> FT'
F -> id
E' -> +TE'
T -> FT'
……
如果输入串有错误,则在输出中要体现是跳过输入串的某些记号了,还是弹栈,弹出某个非终结符或者是终结符了,同时给出相应的出错提示信息。比如:
idid*id对应的出错信息是:“输入串跳过记号id,用户多输入了一个id”;
id**id对应的出错信息是:“弹栈,弹出非终结符F,用户少输入了一个id”
(id+id对应的出错信息是:“弹栈,弹出终结符 ) ,用户少输入了一个右括号(或者说,括号不匹配)”
cpp实现如下:
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
static string input;
static string ahead;
void E();
void Ee();
void T();
void Te();
void F();
bool whether_in(string target,vector<string> v){
for(int i=0;i<v.size();i++)
if(target==v[i])
return true;
return false;
}
void nextToken(){
ahead.clear();
if(input[0]=='*'||input[0]=='+'||input[0]=='('||input[0]==')'||input[0]=='$'){
ahead += input[0];
input = input.substr(1);
}
else if(input[0]=='i'){ //要取完整呀!
ahead = "id";
input = input.substr(2);
}
else if(input[0]==' '){ //如果开头是空格的话就跳过
nextToken();
}
}
void E(){
vector<string> synch;
synch.push_back(")");
synch.push_back("$");
if(ahead == "id"||ahead == "("){
cout << "E->TE'" << endl;
T();
Ee();
}
else if(whether_in(ahead,synch)){
cout << "弹栈,弹出非终结符E,用户少输入了一个id"<<endl;
}
else{
cout << "输入串跳过记号" << ahead << ",用户多输入了一个" << ahead << endl;
nextToken();
E();
}
}
void Ee(){
if(ahead=="+"){
cout << "E'->TE'" << endl;
nextToken();
T();
Ee();
}
else if(ahead=="$"||ahead==")"){
cout << "E'->#" << endl;
//return ;
}
else{
cout << "输入串跳过记号" << ahead << ",用户多输入了一个" << ahead << endl;
nextToken();
Ee();
}
}
void T(){
vector<string> synch;
synch.push_back("+");
synch.push_back(")");
synch.push_back("$");
if(ahead == "("||ahead=="id"){
cout << "T->FT'" << endl;
F();
Te();
}
else if(whether_in(ahead,synch)){
cout << "弹栈,弹出非终结符T,用户少输入了一个id"<<endl;
}
else{
cout << "输入串跳过记号" << ahead << ",用户多输入了一个" << ahead << endl;
nextToken();
T();
}
}
void Te(){
if(ahead == "*"){
cout << "T'->*FT'" << endl;
nextToken();
F();
Te();
}
else if(ahead=="$"||ahead=="+"||ahead==")"){
cout << "T'->#" << endl;
//return ;
}
else{
cout << "输入串跳过记号" << ahead << ",用户多输入了一个" << ahead << endl;
nextToken();
Te();
}
}
void F(){
vector<string> synch;
synch.push_back("+");
synch.push_back("*");
synch.push_back(")");
synch.push_back("$");
if(ahead=="id"){
cout << "F->id" << endl;
nextToken();
}
else if(ahead=="("){
cout << "F->(E)" << endl;
nextToken();
E();
if(ahead!=")")
cout << "弹栈,弹出终结符),用户少输入了一个)" << endl;
}
else if(whether_in(ahead,synch)){
cout << "弹栈,弹出非终结符F,用户少输入了一个id"<< endl;
}
else{
cout << "输入串跳过记号" << ahead << ",用户多输入了一个" << ahead << endl;
nextToken();
F();
}
}
int main(){
char in[100];
cin.getline(in,100);
input = in;
input+="$";
nextToken();
E();
return 0;
}