#include #include #include "iostream" #include "Checker.h" using namespace std; #define isEmptyStr(c) (c == '~') // 能否推导出空串 bool Checker::canDeducedEmpty(const set &productions) { for (const auto &production: productions) { for (const auto &c: production) { if (isEmptyStr(c)) { return true; } } } return false; } string Checker::getStackContent(stack source) { string str; while (!source.empty()) { str.push_back(source.top()); source.pop(); } std::reverse(str.begin(), str.end()); return str; } void printTableHeader() { cout << setw(16) << left << setfill(' ') << "步"; cout << setw(20) << left << setfill(' ') << "分析栈情况"; cout << setw(23) << left << setfill(' ') << "待分析字符串"; cout << setw(25) << left << setfill(' ') << "使用产生式与匹配情况" << endl; } bool Checker::identifyString(std::string input) { printTableHeader(); // 添加#到输入字符串尾部 input.push_back('#'); stack analysisStack = stack(); // #先入栈 analysisStack.push('#'); // 开始符号入栈, S analysisStack.push(grammar.getStartChar()); int step = 0; string remain = input; string status = "分析中"; cout << setw(16) << left << setfill(' ') << step; cout << setw(16) << left << setfill(' ') << getStackContent(analysisStack); cout << setw(16) << left << setfill(' ') << remain; const set &terminals = grammar.getTerminals(); const auto &productionsMap = grammar.getGrammarExpresses(); const auto &analysisTable = grammar.getAnalysisTable(); for (auto pos = input.begin(); pos != input.end();) { char currentChar = *pos; char stackTopChar = analysisStack.top(); // 如果当前栈顶是终结符,对比当前输入字符和栈顶终结符是否匹配 // 匹配则进行规约,否则判定不匹配 if (terminals.contains(stackTopChar)) { if (currentChar == stackTopChar) { analysisStack.pop(); for (const auto &c: remain) { if (c == currentChar) { remain = remain.substr(1); break; } } status.clear(); status.push_back('\''); status.push_back(currentChar); status += "': 匹配"; pos++; } else { cout << "匹配失败。期望输入:" << stackTopChar; cout << ",得到输入:" << currentChar << endl; return false; } } else if (stackTopChar == '#') { return currentChar == '#'; } else { /* 对非终结符的处理 */ // 预测分析表中找不到对应的规则,但是当前的非终止符能推出空串,就退栈,该非终止符作为空串推测处理 // 否则就判定不接受 bool foundInTable = analysisTable.at(stackTopChar).contains(currentChar); if (!foundInTable) { if (canDeducedEmpty(productionsMap.at(stackTopChar))) { cout << "找不到" << stackTopChar << "与" << currentChar << "相匹配的规则" << endl; return false; } else { analysisStack.pop(); status.clear(); status.push_back(stackTopChar); status += "->~"; } } else { analysisStack.pop(); status.clear(); status.push_back(stackTopChar); string production = analysisTable.at(stackTopChar).at(currentChar); status += "-> " + production; for (int i = (int) production.size() - 1; i >= 0; --i) { char c = production[i]; if (c != '~') { analysisStack.push(c); } } } } step++; cout << setw(16) << left << setfill(' ') << status << endl; cout << setw(16) << left << setfill(' ') << step; cout << setw(16) << left << setfill(' ') << getStackContent(analysisStack); cout << setw(16) << left << setfill(' ') << remain; } cout << endl; return true; } Checker::Checker(Grammar grammar) : grammar(std::move(grammar)){}