给定文法(PASCAL语言标识符定义文法)
type→simple|↑id|array[simple] of type
Simple→integer|char|num dotdot num
其中:dotdot表示..
编写递归下降子程序,判定一个句子结构是否正确:array [3..5]of integer
输入:其输入数据应该为词法分析器输出的单词序列:array [ num dotdot num ] of integer
输出:分析结果
1. 输入的时候需要把每个字符串分割出来,因为用Java的时候的split比较方便,查了下C++里面也有类似的,但是用着不太方便,所以利用C++里面的find函数和substr写了一个split,舒服多了
2. 这个和上面那个类似,只不过把字符换成了字符串,当时写第一个的时候觉得match()这个函数有点多余,因为写的比较快也没深入思考,写这个的时候才意识到,其实match()也承担了判错的责任,还是有很大作用的
3. 这个有个左递归把simple()代入到第一行的文法里思路就很清晰了
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
vector<string> vc;
int localhead = 0;
void match(string local);
void type();
void simple();
vector<string> split(string str, char delim);
void error();
int main() {
string str;
cout << "请输入:" << endl;
getline(cin, str);
vc = split(str, ' ');
type();
return 0;
}
vector<string> split(string str, char delim) {
vector<string> vector;
str.append(1, delim);
while (1) {
//找到分隔符第一次出现的位置
int length = str.find(delim);
if (length == str.size() - 1) {
vector.push_back(str.substr(0, length));
break;
}
//拿到第一个分隔符前的字符串
string temp = str.substr(0, length);
//把分割出的字符串放入到容器中
vector.push_back(temp);
//将剩余的字符串替换成新串继续分割
str = str.substr(length + 1, str.size());
}
return vector;
}
void match(string local) {
if (!vc[localhead].compare(local)) {
localhead++;
} else {
//error();
}
}
void type() {
if (!vc[localhead].compare("integer") || !vc[localhead].compare("char") || !vc[localhead].compare("num")) {
simple();
} else if (!vc[localhead].compare("↑")) {
match("↑");
match("id");
} else if (!vc[localhead].compare("array")) {
match("array");
match("[");
simple();
match("]");
match("of");
type();
} else error();
}
void simple() {
if (!vc[localhead].compare("integer")) {
match("integer");
} else if (!vc[localhead].compare("char")) {
match("char");
} else if (!vc[localhead].compare("num")) {
match("num");
match("dotdot");
match("num");
} else error();
}
void error() {
cout << "产生错误" << endl;
}