你修改过后的代码仍存在报错:112 41 E:\.c\ll1test.cpp [Error] 'grammar' was not declared in this scope
时间: 2024-11-04 09:10:29 浏览: 34
在 `LLTable` 类中的 `isFirst` 方法和 `print` 方法中,`grammar` 变量未被声明。你需要将 `grammar` 作为成员变量添加到 `LLTable` 类中,并在构造函数或相关方法中进行初始化。
以下是修改后的代码:
```cpp
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_map>
#include <stack>
#include <algorithm>
using namespace std;
// 定义文法符号
struct Symbol {
string name;
bool isTerminal; // 是否为终结符
};
// 定义产生式
struct Production {
Symbol left;
vector<Symbol> right;
};
// 定义文法
class Grammar {
public:
vector<Symbol> nonTerminals;
vector<Symbol> terminals;
vector<Production> productions;
Symbol startSymbol;
void readFromFile(const string& filename) {
ifstream file(filename);
if (!file.is_open()) {
cerr << "无法打开文件: " << filename << endl;
return;
}
int n, m;
file >> n;
for (int i = 0; i < n; ++i) {
string s;
file >> s;
nonTerminals.push_back({s, false});
}
file >> m;
for (int i = 0; i < m; ++i) {
string s;
file >> s;
terminals.push_back({s, true});
}
string start;
file >> start;
startSymbol = {start, false};
while (file >> start) {
vector<Symbol> right;
string symbol;
while (file >> symbol && symbol != "->") {
right.push_back({symbol, find(terminals.begin(), terminals.end(), Symbol{symbol, true}) != terminals.end()});
}
productions.push_back({{start, false}, right});
}
}
void print() const {
cout << "非终结符: ";
for (const auto& nt : nonTerminals) {
cout << nt.name << " ";
}
cout << "\n终结符: ";
for (const auto& t : terminals) {
cout << t.name << " ";
}
cout << "\n开始符号: " << startSymbol.name << endl;
cout << "产生式:\n";
for (const auto& p : productions) {
cout << p.left.name << " -> ";
for (const auto& s : p.right) {
cout << s.name << " ";
}
cout << endl;
}
}
};
// 构造LL预测分析表
class LLTable {
private:
unordered_map<string, unordered_map<string, vector<Symbol>>> table;
Grammar grammar; // 添加语法对象
public:
void build(Grammar& g) {
grammar = g; // 初始化语法对象
for (const auto& production : grammar.productions) {
for (const auto& terminal : grammar.terminals) {
if (isFirst(production.right, terminal)) {
table[production.left.name][terminal.name] = production.right;
}
}
}
}
bool isFirst(const vector<Symbol>& symbols, const Symbol& terminal) {
for (const auto& symbol : symbols) {
if (symbol.isTerminal) {
return symbol.name == terminal.name;
} else {
for (const auto& prod : grammar.productions) {
if (prod.left.name == symbol.name) {
if (isFirst(prod.right, terminal)) {
return true;
}
}
}
}
}
return false;
}
void print() const {
cout << "预测分析表:\n";
cout << " ";
for (const auto& terminal : grammar.terminals) {
cout << terminal.name << " ";
}
cout << "#\n";
for (const auto& nonTerminal : grammar.nonTerminals) {
cout << nonTerminal.name << " ";
for (const auto& terminal : grammar.terminals) {
if (table.find(nonTerminal.name) != table.end() && table[nonTerminal.name].find(terminal.name) != table[nonTerminal.name].end()) {
cout << table[nonTerminal.name][terminal.name][0].name << " ";
} else {
cout << "- ";
}
}
cout << "-\n";
}
}
bool analyze(const string& input) const {
stack<Symbol> stack;
stack.push({"#", false});
stack.push(grammar.startSymbol);
string inputWithHash = input + " #";
int pos = 0;
cout << "分析过程:\n";
while (!stack.empty()) {
Symbol top = stack.top();
stack.pop();
if (top.isTerminal) {
if (top.name == inputWithHash[pos]) {
cout << "匹配: " << top.name << endl;
pos++;
} else {
cout << "错误: 不匹配" << endl;
return false;
}
} else {
if (table.find(top.name) != table.end() && table[top.name].find(inputWithHash[pos]) != table[top.name].end()) {
const vector<Symbol>& productionRight = table[top.name][inputWithHash[pos]];
for (auto it = productionRight.rbegin(); it != productionRight.rend(); ++it) {
stack.push(*it);
}
cout << "应用产生式: " << top.name << " -> ";
for (const auto& symbol : productionRight) {
cout << symbol.name << " ";
}
cout << endl;
} else {
cout << "错误: 无适用产生式" << endl;
return false;
}
}
}
if (pos == inputWithHash.length() - 1) {
cout << "成功" << endl;
return true;
} else {
cout << "失败" << endl;
return false;
}
}
};
int main(int argc, char* argv[]) {
if (argc != 3) {
cerr << "Usage: " << argv[0] << " <grammar_file> <input_string_file>" << endl;
return 1;
}
string grammarFile = argv[1];
string inputStringFile = argv[2];
Grammar grammar;
grammar.readFromFile(grammarFile);
grammar.print();
LLTable llTable;
llTable.build(grammar);
llTable.print();
ifstream inputFile(inputStringFile);
if (!inputFile.is_open()) {
cerr << "无法打开文件: " << inputStringFile << endl;
return 1;
}
string inputString;
inputFile >> inputString;
llTable.analyze(inputString);
return 0;
}
```
在这个修改后的代码中,`LLTable` 类中添加了一个 `Grammar` 成员变量 `grammar`,并在 `build` 方法中进行了初始化。这样可以确保 `isFirst` 和 `print` 方法能够访问到 `grammar` 对象。
阅读全文