#include <bits/stdc++.h>
using namespace std;
// LL(1) Parsing Table: {Non-terminal, Terminal} -> {Production Symbols}
// Ekhane map use kore table-er value gulo set kora hoyeche
map<pair<string, string>, vector<string>> table = {
{{"E", "id"}, {"T", "E'"}}, {{"E", "("}, {"T", "E'"}},
{{"E'", "+"}, {"+", "T", "E'"}}, {{"E'", ")"}, {"eps"}}, {{"E'", "$"}, {"eps"}},
{{"T", "id"}, {"F", "T'"}}, {{"T", "("}, {"F", "T'"}},
{{"T'", "+"}, {"eps"}}, {{"T'", "*"}, {"*", "F", "T'"}}, {{"T'", ")"}, {"eps"}}, {{"T'", "$"}, {"eps"}},
{{"F", "id"}, {"id"}}, {{"F", "("}, {"(", "E", ")"}}
};
void predictiveParse(string input) {
stack<string> st;
st.push("$"); // Stack-er niche end marker '$' push kora hoyeche
st.push("E"); // Start symbol 'E' stack-e push kora holo
// Input string ke alada kora (jemon 'id' thakle sheta ke ekta token dhora)
vector<string> tokens;
for (int i = 0; i < input.size(); ) {
if (isspace(input[i])) { i++; continue; }
if (input.substr(i, 2) == "id") { tokens.push_back("id"); i += 2; }
else { tokens.push_back(string(1, input[i])); i++; }
}
tokens.push_back("$"); // Input string-er sheshe '$' add kora holo
int ptr = 0; // Input pointer manage korar jonno
cout << left << setw(20) << "STACK" << setw(20) << "INPUT" << "ACTION" << endl;
while (!st.empty()) {
string top = st.top();
string curr = tokens[ptr];
// Current Stack state print korar jonno logic
stack<string> temp = st;
string sStack = "";
vector<string> v;
while(!temp.empty()){ v.push_back(temp.top()); temp.pop(); }
reverse(v.begin(), v.end());
for(string x : v) sStack += x;
// Current Input state print korar jonno logic
string sInput = "";
for(int i=ptr; i<tokens.size(); i++) sInput += tokens[i];
cout << left << setw(20) << sStack << setw(20) << sInput;
// MATCH: Stack top ebong Input symbol mile gele pop ebong pointer move hobe
if (top == curr) {
if (top == "$") { cout << "ACCEPT" << endl; return; }
cout << "match " << curr << endl;
st.pop();
ptr++;
}
// PRODUCTION: Table-e jodi oi (top, current) cell-e kono rule thake
else if (table.count({top, curr})) {
vector<string> prod = table[{top, curr}];
cout << top << " -> ";
for(string p : prod) cout << p;
cout << endl;
st.pop(); // Current non-terminal-ke stack theke ber kora holo
if (prod[0] != "eps") { // Rule-ti jodi epsilon na hoy, tobe reverse-e stack-e push hobe
for (int i = (int)prod.size() - 1; i >= 0; i--) st.push(prod[i]);
}
}
// ERROR: Table-e kono rule na thakle parsing error dekhabe
else {
cout << "ERROR" << endl;
return;
}
}
}
int main() {
string input;
cout << "Enter input (e.g., id+id*id): ";
cin >> input; // Udahoron hisebe 'id+id*id' dewa jete pare
predictiveParse(input);
return 0;
}
//Enter input (e.g., id+id*id): id+id*id
//STACK INPUT ACTION
//$E id+id*id$ E -> TE'
//$E'T id+id*id$ T -> FT'
//$E'T'F id+id*id$ F -> id
//$E'T'id id+id*id$ match id
//$E'T' +id*id$ T' -> eps
//$E' +id*id$ E' -> +TE'
//$E'T+ +id*id$ match +
//$E'T id*id$ T -> FT'
//$E'T'F id*id$ F -> id
//$E'T'id id*id$ match id
//$E'T' *id$ T' -> *FT'
//$E'T'F* *id$ match *
//$E'T'F id$ F -> id
//$E'T'id id$ match id
//$E'T' $ T' -> eps
//$E' $ E' -> eps
//$ $ ACCEPT
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBMTCgxKSBQYXJzaW5nIFRhYmxlOiB7Tm9uLXRlcm1pbmFsLCBUZXJtaW5hbH0gLT4ge1Byb2R1Y3Rpb24gU3ltYm9sc30KLy8gRWtoYW5lIG1hcCB1c2Uga29yZSB0YWJsZS1lciB2YWx1ZSBndWxvIHNldCBrb3JhIGhveWVjaGUKbWFwPHBhaXI8c3RyaW5nLCBzdHJpbmc+LCB2ZWN0b3I8c3RyaW5nPj4gdGFibGUgPSB7CiAgICB7eyJFIiwgImlkIn0sIHsiVCIsICJFJyJ9fSwge3siRSIsICIoIn0sIHsiVCIsICJFJyJ9fSwKICAgIHt7IkUnIiwgIisifSwgeyIrIiwgIlQiLCAiRScifX0sIHt7IkUnIiwgIikifSwgeyJlcHMifX0sIHt7IkUnIiwgIiQifSwgeyJlcHMifX0sCiAgICB7eyJUIiwgImlkIn0sIHsiRiIsICJUJyJ9fSwge3siVCIsICIoIn0sIHsiRiIsICJUJyJ9fSwKICAgIHt7IlQnIiwgIisifSwgeyJlcHMifX0sIHt7IlQnIiwgIioifSwgeyIqIiwgIkYiLCAiVCcifX0sIHt7IlQnIiwgIikifSwgeyJlcHMifX0sIHt7IlQnIiwgIiQifSwgeyJlcHMifX0sCiAgICB7eyJGIiwgImlkIn0sIHsiaWQifX0sIHt7IkYiLCAiKCJ9LCB7IigiLCAiRSIsICIpIn19Cn07Cgp2b2lkIHByZWRpY3RpdmVQYXJzZShzdHJpbmcgaW5wdXQpIHsKICAgIHN0YWNrPHN0cmluZz4gc3Q7CiAgICBzdC5wdXNoKCIkIik7IC8vIFN0YWNrLWVyIG5pY2hlIGVuZCBtYXJrZXIgJyQnIHB1c2gga29yYSBob3llY2hlCiAgICBzdC5wdXNoKCJFIik7IC8vIFN0YXJ0IHN5bWJvbCAnRScgc3RhY2stZSBwdXNoIGtvcmEgaG9sbwoKICAgIC8vIElucHV0IHN0cmluZyBrZSBhbGFkYSBrb3JhIChqZW1vbiAnaWQnIHRoYWtsZSBzaGV0YSBrZSBla3RhIHRva2VuIGRob3JhKQogICAgdmVjdG9yPHN0cmluZz4gdG9rZW5zOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBpbnB1dC5zaXplKCk7ICkgewogICAgICAgIGlmIChpc3NwYWNlKGlucHV0W2ldKSkgeyBpKys7IGNvbnRpbnVlOyB9CiAgICAgICAgaWYgKGlucHV0LnN1YnN0cihpLCAyKSA9PSAiaWQiKSB7IHRva2Vucy5wdXNoX2JhY2soImlkIik7IGkgKz0gMjsgfQogICAgICAgIGVsc2UgeyB0b2tlbnMucHVzaF9iYWNrKHN0cmluZygxLCBpbnB1dFtpXSkpOyBpKys7IH0KICAgIH0KICAgIHRva2Vucy5wdXNoX2JhY2soIiQiKTsgLy8gSW5wdXQgc3RyaW5nLWVyIHNoZXNoZSAnJCcgYWRkIGtvcmEgaG9sbwoKICAgIGludCBwdHIgPSAwOyAvLyBJbnB1dCBwb2ludGVyIG1hbmFnZSBrb3JhciBqb25ubwogICAgY291dCA8PCBsZWZ0IDw8IHNldHcoMjApIDw8ICJTVEFDSyIgPDwgc2V0dygyMCkgPDwgIklOUFVUIiA8PCAiQUNUSU9OIiA8PCBlbmRsOwoKCgogICAgd2hpbGUgKCFzdC5lbXB0eSgpKSB7CiAgICAgICAgc3RyaW5nIHRvcCA9IHN0LnRvcCgpOwogICAgICAgIHN0cmluZyBjdXJyID0gdG9rZW5zW3B0cl07CgogICAgICAgIC8vIEN1cnJlbnQgU3RhY2sgc3RhdGUgcHJpbnQga29yYXIgam9ubm8gbG9naWMKICAgICAgICBzdGFjazxzdHJpbmc+IHRlbXAgPSBzdDsKICAgICAgICBzdHJpbmcgc1N0YWNrID0gIiI7CiAgICAgICAgdmVjdG9yPHN0cmluZz4gdjsKICAgICAgICB3aGlsZSghdGVtcC5lbXB0eSgpKXsgdi5wdXNoX2JhY2sodGVtcC50b3AoKSk7IHRlbXAucG9wKCk7IH0KICAgICAgICByZXZlcnNlKHYuYmVnaW4oKSwgdi5lbmQoKSk7CiAgICAgICAgZm9yKHN0cmluZyB4IDogdikgc1N0YWNrICs9IHg7CgogICAgICAgIC8vIEN1cnJlbnQgSW5wdXQgc3RhdGUgcHJpbnQga29yYXIgam9ubm8gbG9naWMKICAgICAgICBzdHJpbmcgc0lucHV0ID0gIiI7CiAgICAgICAgZm9yKGludCBpPXB0cjsgaTx0b2tlbnMuc2l6ZSgpOyBpKyspIHNJbnB1dCArPSB0b2tlbnNbaV07CgogICAgICAgIGNvdXQgPDwgbGVmdCA8PCBzZXR3KDIwKSA8PCBzU3RhY2sgPDwgc2V0dygyMCkgPDwgc0lucHV0OwoKICAgICAgICAvLyBNQVRDSDogU3RhY2sgdG9wIGVib25nIElucHV0IHN5bWJvbCBtaWxlIGdlbGUgcG9wIGVib25nIHBvaW50ZXIgbW92ZSBob2JlCiAgICAgICAgaWYgKHRvcCA9PSBjdXJyKSB7CiAgICAgICAgICAgIGlmICh0b3AgPT0gIiQiKSB7IGNvdXQgPDwgIkFDQ0VQVCIgPDwgZW5kbDsgcmV0dXJuOyB9CiAgICAgICAgICAgIGNvdXQgPDwgIm1hdGNoICIgPDwgY3VyciA8PCBlbmRsOwogICAgICAgICAgICBzdC5wb3AoKTsKICAgICAgICAgICAgcHRyKys7CiAgICAgICAgfQogICAgICAgIC8vIFBST0RVQ1RJT046IFRhYmxlLWUgam9kaSBvaSAodG9wLCBjdXJyZW50KSBjZWxsLWUga29ubyBydWxlIHRoYWtlCiAgICAgICAgZWxzZSBpZiAodGFibGUuY291bnQoe3RvcCwgY3Vycn0pKSB7CiAgICAgICAgICAgIHZlY3RvcjxzdHJpbmc+IHByb2QgPSB0YWJsZVt7dG9wLCBjdXJyfV07CiAgICAgICAgICAgIGNvdXQgPDwgdG9wIDw8ICIgLT4gIjsKICAgICAgICAgICAgZm9yKHN0cmluZyBwIDogcHJvZCkgY291dCA8PCBwOwogICAgICAgICAgICBjb3V0IDw8IGVuZGw7CgogICAgICAgICAgICBzdC5wb3AoKTsgLy8gQ3VycmVudCBub24tdGVybWluYWwta2Ugc3RhY2sgdGhla2UgYmVyIGtvcmEgaG9sbwogICAgICAgICAgICBpZiAocHJvZFswXSAhPSAiZXBzIikgeyAvLyBSdWxlLXRpIGpvZGkgZXBzaWxvbiBuYSBob3ksIHRvYmUgcmV2ZXJzZS1lIHN0YWNrLWUgcHVzaCBob2JlCiAgICAgICAgICAgICAgICBmb3IgKGludCBpID0gKGludClwcm9kLnNpemUoKSAtIDE7IGkgPj0gMDsgaS0tKSBzdC5wdXNoKHByb2RbaV0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8vIEVSUk9SOiBUYWJsZS1lIGtvbm8gcnVsZSBuYSB0aGFrbGUgcGFyc2luZyBlcnJvciBkZWtoYWJlCiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNvdXQgPDwgIkVSUk9SIiA8PCBlbmRsOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQp9CgppbnQgbWFpbigpIHsKICAgIHN0cmluZyBpbnB1dDsKICAgIGNvdXQgPDwgIkVudGVyIGlucHV0IChlLmcuLCBpZCtpZCppZCk6ICI7CiAgICBjaW4gPj4gaW5wdXQ7IC8vIFVkYWhvcm9uIGhpc2ViZSAnaWQraWQqaWQnIGRld2EgamV0ZSBwYXJlCiAgICBwcmVkaWN0aXZlUGFyc2UoaW5wdXQpOwogICAgcmV0dXJuIDA7Cn0KCi8vRW50ZXIgaW5wdXQgKGUuZy4sIGlkK2lkKmlkKTogaWQraWQqaWQKLy9TVEFDSyAgICAgICAgICAgICAgIElOUFVUICAgICAgICAgICAgICAgQUNUSU9OCi8vJEUgICAgICAgICAgICAgICAgICBpZCtpZCppZCQgICAgICAgICAgIEUgLT4gVEUnCi8vJEUnVCAgICAgICAgICAgICAgICBpZCtpZCppZCQgICAgICAgICAgIFQgLT4gRlQnCi8vJEUnVCdGICAgICAgICAgICAgICBpZCtpZCppZCQgICAgICAgICAgIEYgLT4gaWQKLy8kRSdUJ2lkICAgICAgICAgICAgIGlkK2lkKmlkJCAgICAgICAgICAgbWF0Y2ggaWQKLy8kRSdUJyAgICAgICAgICAgICAgICtpZCppZCQgICAgICAgICAgICAgVCcgLT4gZXBzCi8vJEUnICAgICAgICAgICAgICAgICAraWQqaWQkICAgICAgICAgICAgIEUnIC0+ICtURScKLy8kRSdUKyAgICAgICAgICAgICAgICtpZCppZCQgICAgICAgICAgICAgbWF0Y2ggKwovLyRFJ1QgICAgICAgICAgICAgICAgaWQqaWQkICAgICAgICAgICAgICBUIC0+IEZUJwovLyRFJ1QnRiAgICAgICAgICAgICAgaWQqaWQkICAgICAgICAgICAgICBGIC0+IGlkCi8vJEUnVCdpZCAgICAgICAgICAgICBpZCppZCQgICAgICAgICAgICAgIG1hdGNoIGlkCi8vJEUnVCcgICAgICAgICAgICAgICAqaWQkICAgICAgICAgICAgICAgIFQnIC0+ICpGVCcKLy8kRSdUJ0YqICAgICAgICAgICAgICppZCQgICAgICAgICAgICAgICAgbWF0Y2ggKgovLyRFJ1QnRiAgICAgICAgICAgICAgaWQkICAgICAgICAgICAgICAgICBGIC0+IGlkCi8vJEUnVCdpZCAgICAgICAgICAgICBpZCQgICAgICAgICAgICAgICAgIG1hdGNoIGlkCi8vJEUnVCcgICAgICAgICAgICAgICAkICAgICAgICAgICAgICAgICAgIFQnIC0+IGVwcwovLyRFJyAgICAgICAgICAgICAgICAgJCAgICAgICAgICAgICAgICAgICBFJyAtPiBlcHMKLy8kICAgICAgICAgICAgICAgICAgICQgICAgICAgICAgICAgICAgICAgQUNDRVBUCgo=