7-5 LL(1)分析-最左推导输入一个上下文无关文法,先输入文法产生式条数,再输入各个产生式,字符“ε”用“@”表示。 输入一个待分析的字符串,以"#"结束。 输出格式: 输出待分析字符串的最左推导。给我C++代码
时间: 2024-02-24 22:58:32 浏览: 303
ll(1)文法分析以及消除左递归
好的,以下是一个简单的C++代码实现LL(1)分析器并输出最左推导的例子。请注意,这里的代码实现只是一个简单的示例,如果您想要更加完整和高效的实现,可能需要更多的工作和优化。
```
#include <iostream>
#include <map>
#include <vector>
#include <stack>
using namespace std;
// 定义产生式结构体
struct Production {
char left; // 左部字符
string right; // 右部字符串
};
// 定义LL(1)分析器类
class LL1 {
public:
LL1(int n) : n(n) {
productions.resize(n);
isFirst.resize(256, vector<bool>(false));
isFollow.resize(256, vector<bool>(false));
predictTable.resize(256, vector<int>(256, -1));
}
// 添加产生式
void addProduction(int i, char left, string right) {
productions[i].left = left;
productions[i].right = right;
}
// 计算FIRST集
void calcFirst() {
for (int i = 0; i < n; i++) {
char left = productions[i].left;
string right = productions[i].right;
for (int j = 0; j < right.length(); j++) {
char c = right[j];
if (isupper(c)) { // 非终结符
isFirst[left][c] = true; // FIRST(A) 包含 FIRST(B)
for (int k = 0; k < n; k++) {
if (productions[k].left == c) {
// 如果 B -> ε,则 FIRST(A) 包含 FIRST(B) - {ε}
if (k == i && right.length() == 1) {
isFirst[left][c] = false;
}
for (int l = 0; l < productions[k].right.length(); l++) {
char r = productions[k].right[l];
isFirst[left][r] = true; // FIRST(A) 包含 FIRST(B)
if (!isFirst[c][r]) {
break;
}
}
}
}
} else { // 终结符
isFirst[left][c] = true;
break;
}
}
}
}
// 计算FOLLOW集
void calcFollow() {
isFollow[productions[0].left]['#'] = true;
for (int i = 0; i < n; i++) {
char left = productions[i].left;
string right = productions[i].right;
for (int j = 0; j < right.length(); j++) {
char c = right[j];
if (isupper(c)) { // 非终结符
if (j == right.length() - 1) { // A -> αB
for (int k = 0; k < n; k++) {
if (productions[k].left == left) {
isFollow[c] = isFollow[c] || isFollow[productions[k].right[productions[k].right.length() - 1]];
}
}
} else { // A -> αBβ
char next = right[j + 1];
if (isupper(next)) { // FIRST(β) - {ε} 属于 FOLLOW(B)
for (int k = 0; k < n; k++) {
if (productions[k].left == next) {
for (int l = 0; l < productions[k].right.length(); l++) {
char r = productions[k].right[l];
if (r != '@') {
isFollow[c][r] = true;
}
}
}
}
} else { // β 是终结符,直接加入 FOLLOW(B)
isFollow[c][next] = true;
}
}
}
}
}
}
// 构造预测分析表
void buildPredictTable() {
for (int i = 0; i < n; i++) {
char left = productions[i].left;
string right = productions[i].right;
vector<bool> first = isFirst[left];
for (int j = 0; j < right.length(); j++) {
char c = right[j];
if (isupper(c)) { // 非终结符
for (int k = 0; k < n; k++) {
if (productions[k].left == c) {
for (int l = 0; l < 256; l++) {
if (first[l]) {
predictTable[left][l] = k;
}
}
if (isFirst[c]['@']) { // 如果 B -> ε,则 FOLLOW(B) 属于 FOLLOW(A)
for (int l = 0; l < 256; l++) {
if (isFollow[left][l]) {
predictTable[left][l] = k;
}
}
}
break;
}
}
if (!isFirst[c]['@']) {
break;
}
} else { // 终结符
predictTable[left][c] = i;
break;
}
}
}
}
// LL(1)分析
void analyze(string input) {
stack<char> stk;
stk.push('#');
stk.push(productions[0].left);
int i = 0;
cout << "最左推导: ";
while (!stk.empty()) {
char c = stk.top();
stk.pop();
if (c == input[i]) {
if (c != '#') {
i++;
}
} else if (isupper(c)) {
int prod = predictTable[c][input[i]];
Production p = productions[prod];
cout << p.left << "->" << p.right << " ";
for (int j = p.right.length() - 1; j >= 0; j--) {
if (p.right[j] != '@') {
stk.push(p.right[j]);
}
}
} else {
break;
}
}
cout << endl;
}
private:
int n; // 产生式条数
vector<Production> productions; // 产生式
vector<vector<bool>> isFirst; // FIRST集
vector<vector<bool>> isFollow; // FOLLOW集
vector<vector<int>> predictTable; // 预测分析表
};
int main() {
int n;
cout << "请输入产生式条数: ";
cin >> n;
LL1 ll1(n);
cout << "请输入各个产生式: " << endl;
for (int i = 0; i < n; i++) {
char left;
string right;
cin >> left >> right;
ll1.addProduction(i, left, right);
}
ll1.calcFirst();
ll1.calcFollow();
ll1.buildPredictTable();
string input;
cout << "请输入待分析的字符串: ";
cin >> input;
input += '#';
ll1.analyze(input);
return 0;
}
```
希望这个例子对你有所帮助!
阅读全文