C++给定预测分析表,构造出相关预测分析程序,并返回一个符号串的分析结果,如果是一个合法的符号串则输出正确标志并返回True,否则输出错误标志并返回False。并写出实验体会
时间: 2023-08-04 22:05:48 浏览: 107
首先,预测分析表是一个二维数组,其中行表示非终结符,列表示终结符,每个单元格中的值表示使用该非终结符进行推导时所需要的产生式。我们可以使用一个栈来模拟分析过程。
根据输入的符号串,我们将其放入一个队列中,然后将起始非终结符(通常是文法的开始符号)放入栈顶。接下来,从队列中取出一个终结符,如果与栈顶的终结符相同,则弹出栈顶并继续取下一个终结符;如果栈顶是一个非终结符,则在预测分析表中查找该非终结符和当前终结符对应的产生式,并将该产生式中的符号逆序入栈(注意,如果该非终结符和当前终结符没有对应的产生式,则说明输入符号串不合法);如果队列已经为空但栈中还有符号,则说明输入符号串不合法。
下面是C++实现代码:
```c++
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
using namespace std;
const int MAXN = 100; // 文法符号个数的上限
const int MAXM = 100; // 终结符个数的上限
int n, m; // 文法符号数和终结符数
char nonterminal[MAXN]; // 非终结符
char terminal[MAXM]; // 终结符
int table[MAXN][MAXM]; // 预测分析表
bool analyze(string s) {
stack<char> stk;
queue<char> q;
for (char c : s) {
q.push(c);
}
stk.push(nonterminal[0]); // 将起始非终结符入栈
while (!stk.empty()) {
char top = stk.top();
stk.pop();
if (top == q.front()) {
q.pop();
} else if (top >= 'A' && top <= 'Z') {
int i = top - 'A';
int j = 0;
for (; j < m; j++) {
if (terminal[j] == q.front()) {
break;
}
}
if (j == m) { // 没有对应的产生式
return false;
}
int k = table[i][j];
if (k == -1) { // 没有对应的产生式
return false;
}
for (int l = nonterminal[k + 1] == '\'' ? k + 2 : k + 1; l < strlen(nonterminal); l++) {
stk.push(nonterminal[l]);
}
} else {
return false;
}
}
return q.empty();
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> nonterminal[i];
}
for (int i = 0; i < m; i++) {
cin >> terminal[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> table[i][j];
}
}
string s;
cin >> s;
if (analyze(s)) {
cout << "Correct!" << endl;
return true;
} else {
cout << "Error!" << endl;
return false;
}
}
```
我的实验体会是,预测分析表虽然可以用来构造分析程序,但是需要手动构造预测分析表,而且对于复杂的文法,预测分析表可能会非常大,难以维护。因此,预测分析法适用于文法比较简单的情况,对于复杂的文法,还是推荐使用LR分析法等自动构造分析程序的方法。
阅读全文