// // Created by lenfrex on 2023/5/8. // #include "Grammar.h" using namespace std; #define isEmptyStr(c) (c == '~') void Grammar::generateSelectSet() { // 处理每一个非终止符,以取得产生式 for (const auto &leftNonTerminal: nonTerminals) { if (!productionsMap.contains(leftNonTerminal)) { continue; } const set &productions = productionsMap.at(leftNonTerminal); // 解析非终止符的每个产生式 for (const auto &production: productions) { ExpressSelectSet productionSelectSet = ExpressSelectSet(); productionSelectSet.first = production; productionSelectSet.second = set(); // 解析产生式,一个一个字符处理 for (auto currPos = production.begin(); currPos != production.end(); currPos++) { char currChar = *currPos; // 如果当前字符是终止符 // - 是空串,把产生式左部非终止符(即A->a...中的A, 此处即为leftNonTerminal)的follow加到当前产生式的select中(productionSelectSet); // - 不是空串,就直接把这个符号加入到当前产生式的select // // 如果是非终结符把,则把当前字符的first删去空串之后加入当前产生式的select中 // - 当前非终止符可以推出空串,就继续往后解析处理当前非终止符为空时的情况; // - 如果是最后一个字符,把产生式左部follow加当前产生式的select中; // - 如果不是最后一个字符,则继续看下一个字符(continue) // - 不能推出空串,说明该条产生式select集合的计算结束(break) if (terminals.contains(currChar)) { if (isEmptyStr(currChar)) { productionSelectSet.second.insert(followSet[leftNonTerminal].begin(), followSet[leftNonTerminal].end()); } else { productionSelectSet.second.insert(currChar); } break; } else { // 前字符的first删去空串之后加入到产生式的select中 set currFirst = firstSet[currChar]; currFirst.erase('~'); productionSelectSet.second.insert(currFirst.begin(), currFirst.end()); // 如果当前字符能推出空串,就看看下一个字符怎么样 // 不能推出空串就break退出 if (canDeducedEmpty(productionsMap.at(currChar))) { // 如果现在的这个字符已经是产生式末尾了,就把产生式左部follow加进去 // 否则转到下一个字符 auto next = currPos + 1; if (next == production.end()) { productionSelectSet.second.insert(followSet[leftNonTerminal].begin(), followSet[leftNonTerminal].end()); } else { continue; } } else { break; } } } selectSet[leftNonTerminal].insert(productionSelectSet); } } }