Write a program to Implement Shift Reduce parsing for a String.
#include <iostream>
#include <stack>
#include <vector>
#include <unordered_map>
using namespace std;
vector<string> productions = {"E->E+T", "E->T", "T->T*F", "T->F", "F->(E)", "F->id"};
unordered_map<string, unordered_map<string, string>> parsingTable = {
{"E", {{"(", "shift T"}, {"id", "shift T"}}},
{"T", {{"(", "shift F"}, {"id", "shift F"}}},
{"F", {{"(", "shift (E)"}, {"id", "shift id"}}}
};
void shift(stack<string> &parseStack, vector<string> &input) {
parseStack.push(input[0]);
input.erase(input.begin());
}
void reduce(stack<string> &parseStack, const string &nonTerminal) {
if (parsingTable.find(nonTerminal) != parsingTable.end()) {
string production = parsingTable[nonTerminal]["$"];
size_t arrowPos = production.find("->");
string rhs = production.substr(arrowPos + 2);
for (size_t i = 0; i < rhs.size(); ++i) {
parseStack.pop();
}
parseStack.push(production.substr(0, arrowPos));
} else {
cout << "Error: No production rule for non-terminal " << nonTerminal << endl;
}
}
void parse(stack<string> &parseStack, vector<string> &input) {
while (!input.empty()) {
string stackTop = parseStack.top();
string nextInput = input[0];
if (parsingTable[stackTop].find(nextInput) != parsingTable[stackTop].end()) {
string action = parsingTable[stackTop][nextInput];
if (action.substr(0, 5) == "shift") {
shift(parseStack, input);
} else if (action.substr(0, 5) == "reduce") {
reduce(parseStack, stackTop);
}
} else {
cout << "Error: Invalid pair (" << stackTop << ", " << nextInput << ")" << endl;
break;
}
cout << "Stack: ";
stack<string> tempStack = parseStack;
while (!tempStack.empty()) {
cout << tempStack.top() << " ";
tempStack.pop();
}
cout << "\tInput: ";
for (const auto &symbol : input) {
cout << symbol << " ";
}
cout << endl;
}
}
int main() {
vector<string> input = {"id", "+", "id", "*", "id", "$"};
stack<string> parseStack;
parseStack.push("E");
parse(parseStack, input);
return 0;
}
Comments
Post a Comment