某个编译原理的实验代码存档
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
compile-work/parser/grammar/AnalysisTableBuilder.cpp

58 lines
1.4 KiB

//
// Created by lenfrex on 2023/5/8.
//
#include "Grammar.h"
using namespace std;
// 求是否有交集
bool hasUnion(const set<char> &a, const set<char> &b) {
for (const auto &selectChars: b) {
if (a.contains(selectChars)) {
return true;
}
}
return false;
}
// 检查是否为LL1文法
bool Grammar::isLL1Grammar() {
// 逐个非终止符检查
for (const auto &nonTerminal: nonTerminals) {
SelectSet select = selectSet[nonTerminal];
// 取一行
for (auto current = select.begin(); current != select.end();) {
const auto &productionSelectSet = current->second;
// 取剩下的行进行比较,注意这里已经++current了,外层for就不要++了
for (auto innerCurrent = ++current; innerCurrent != select.end(); innerCurrent++) {
if (hasUnion(productionSelectSet, innerCurrent->second)) {
return false;
}
}
}
}
return true;
}
void Grammar::buildAnalysisTable() {
if (!isLL1Grammar()) {
throw NotSupportedGrammarException("文法定义不符合LL1文法");
}
for (const auto &nonTerminal: nonTerminals) {
SelectSet select = selectSet[nonTerminal];
for (const auto &selectPair: select) {
const auto &prod = selectPair.first;
const auto &selectChars = selectPair.second;
// 填充预测分析表
for (const auto &selectableTerminal: selectChars) {
analysisTable[nonTerminal][selectableTerminal] = prod;
}
}
}
}