使用LL(1)分析法计算First集并给出c++代码
时间: 2023-11-27 10:55:25 浏览: 78
LL(1)文法的First集是指对于每个非终结符,其可以推导出的终结符的集合。计算First集的过程可以使用递归算法,以下是c++代码实现:
```c++
#include <iostream>
#include <vector>
#include <unordered_set>
#include <map>
using namespace std;
// 终结符
unordered_set<char> Vt = {'a', 'b', 'c', '#'};
// 非终结符
unordered_set<char> Vn = {'S', 'A', 'B'};
// 产生式
map<char, vector<string>> P = {
{'S', {"ABc"}},
{'A', {"a|epsilon"}},
{'B', {"b|epsilon"}}
};
// First集
map<char, unordered_set<char>> First;
// 计算非终结符X的First集
void calcFirst(char X) {
if (Vt.find(X) != Vt.end()) { // 如果X是终结符
First[X].insert(X); // 将X加入到First(X)中
} else { // 如果X是非终结符
for (auto &p : P[X]) { // 遍历X的每个产生式
char Y = p[0]; // 取得产生式的第一个字符
if (Vt.find(Y) != Vt.end()) { // 如果Y是终结符
First[X].insert(Y); // 将Y加入到First(X)中
} else { // 如果Y是非终结符
calcFirst(Y); // 递归计算First(Y)
First[X].insert(First[Y].begin(), First[Y].end()); // 将First(Y)加入到First(X)中
}
}
}
}
int main() {
for (char X : Vn) {
calcFirst(X); // 计算每个非终结符的First集
}
// 输出每个非终结符的First集
for (char X : Vn) {
cout << "First(" << X << ")={";
for (char c : First[X]) {
cout << c << ",";
}
cout << "}" << endl;
}
return 0;
}
```
上述代码中,使用了STL中的unordered_set和map容器,分别用来存储终结符、非终结符、产生式和First集。在计算First集时,对于每个非终结符X,遍历其所有产生式,处理每个产生式的第一个字符Y,如果Y是终结符,则将其加入到First(X)中;如果Y是非终结符,则递归计算First(Y),然后将其加入到First(X)中。最后输出每个非终结符的First集。
阅读全文