10 63 D:\dev c++\cifa2.cpp [Error] in C++98 'TERMINALS' must be initialized by constructor, not by '{...}'
时间: 2023-12-10 14:39:39 浏览: 177
这个错误是因为在 C++98 标准下,数组的初始化必须通过构造函数进行,不能使用花括号列表初始化。要解决这个错误,你可以在定义数组时使用构造函数进行初始化,或者将编译器的标准设置为 C++11 或更高版本,这样就可以使用花括号列表初始化了。如果你希望使用构造函数进行初始化,可以将数组定义为类的成员变量,并在类的构造函数中进行初始化。例如:
```c++
class MyClass {
public:
MyClass() : TERMINALS({ '+', '-', '*', '/' }) {}
private:
char TERMINALS[4];
};
```
这样就可以通过构造函数进行数组的初始化了。如果你希望使用花括号列表初始化,可以将编译器的标准设置为 C++11 或更高版本。在大部分现代编译器中,可以通过命令行参数 `-std=c++11` 来设置编译器的标准。
相关问题
9 79 D:\dev c++\cifa2.cpp [Error] in C++98 'grammar' must be initialized by constructor, not by '{...}'
这个错误提示是因为在 C++98 标准中,类的成员变量不能使用花括号来初始化,而必须使用构造函数。比如下面的代码就会导致这个错误:
```cpp
class Grammar {
public:
std::vector<std::string> nonterminals {"S", "A", "B", "C"};
std::vector<std::string> terminals {"a", "b", "c", "d", "e", "f"};
std::unordered_map<std::string, std::vector<std::vector<std::string>>> rules {
{"S", {{"A", "B", "C"}}},
{"A", {{"a", "A"}, {"b"}}},
{"B", {{"c", "B"}, {"d"}}},
{"C", {{"e", "C"}, {"f"}}}
};
};
```
解决这个问题的方法是,使用构造函数来初始化成员变量,例如:
```cpp
class Grammar {
public:
Grammar()
: nonterminals{"S", "A", "B", "C"},
terminals{"a", "b", "c", "d", "e", "f"},
rules{
{"S", {{"A", "B", "C"}}},
{"A", {{"a", "A"}, {"b"}}},
{"B", {{"c", "B"}, {"d"}}},
{"C", {{"e", "C"}, {"f"}}}
}
{}
std::vector<std::string> nonterminals;
std::vector<std::string> terminals;
std::unordered_map<std::string, std::vector<std::vector<std::string>>> rules;
};
```
这样就可以在 C++98 标准下正常编译了。当然,在 C++11 之后,使用花括号初始化成员变量是被允许的,所以如果你使用的是较新的编译器,也可以直接使用花括号初始化成员变量。
你修改过后的代码仍存在报错:112 41 E:\.c\ll1test.cpp [Error] 'grammar' was not declared in this scope
在 `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` 对象。
阅读全文