The last article "Compiling principle" syntax analysis-from the top down analysis and analysis of LL1 Grammar, the article finally said to give chestnuts, now fill up.
Description: This parser is implemented using the LL1 analysis method. Predictive analysis tables and terminator and non-terminator are all defined for a particular grammar. The parse string entered must begin and end with #.
Original grammar:
E-e + T | T-t
* t | F
-F (E) | i
After removing left recursion
E, TE '
e ', +te ' | e
t, FT '
t ', *ft ' | e
F-C (e) | I
//remark
e means one step Sailen
e ' Using Z instead of
T ' in the actual program in the actual program using Y instead
The procedure is as follows:
#include <iostream> #include <vector> #include <string> #include <stack> #define BEGIN_SYB ' E '
A single production public:tab (char N,char e,std::string p) in the class Tab {//Prediction Analysis Table: Noend (n), End (e), prod (p) {};
Char noend;
Char end;
std::string prod;
}; Std::vector<tab> PTab; Prediction Analysis Table std::stack<char> Pstack; Stack std::string pStr; Input string int index = 0; Input string subscript int num = 0; Subscript Char X; Remove the symbol from the top of the stack char A; The string is currently parsed to the location of std::vector<char> vt{' i ', ' + ', ' * ', ' (', ') ', ' # '}; End symbol set std::vector<char> vn{' E ', ' Z ', ' T ', ' Y ', ' F '};
Non-terminating symbol collection int ISPARTVT (char ch) {for (auto u:vt) {if (U = = ch) {return 1;
}} return 0;
} int ispartvn (char ch) {for (auto u:vn) {if (U = = ch) {return 1;
}} return 0; } void Initptab () {Ptab.push_back (tab (' E ', ' I ', "TZ")); Z means E ' ptab.push_back (tab (' E ', ' (', ' TZ '));
Ptab.push_back (Tab (' Z ', ' + ', ' +tz '));
Ptab.push_back (Tab (' Z ', ') ', "$"));
Ptab.push_back (Tab (' Z ', ' # ', ' $ '));
Ptab.push_back (Tab (' T ', ' I ', "FY")); Ptab.push_back (Tab (' T ', ' (', ' FY '));
Y means t ' ptab.push_back (tab (' Y ', ' + ', ' $ '));
Ptab.push_back (Tab (' Y ', ' * ', ' *fy '));
Ptab.push_back (Tab (' Y ', ') ', ' $ '));
Ptab.push_back (Tab (' Y ', ' # ', ' $ '));
Ptab.push_back (Tab (' F ', ' I ', "I"));
Ptab.push_back (Tab (' F ', ' (', ' (E) '));}
void Printstack () {std::stack<char> ptemp (pstack);
while (Ptemp.size ()! = 0) {std::cout << ptemp.top () << "";
Ptemp.pop ();
} std::cout << "";}
int Synaly () {Pstack.push (pstr[index++]);
Pstack.push (BEGIN_SYB);
A = pstr[index++];
BOOL flag = TRUE; while (flag) {std::cout << num++ << "";
Output line number printstack (); if (pstack.size ()! = 0) {X = Pstack.top (); Top the symbol stack to x pstack.pop (); } if (ISPARTVT (x)) {//if terminator if (x = = ' # ' && a = = ' # ') {flag
= false;
}else if (X = = a) {std::cout << Std::endl;
A = pstr[index++];
}else {std::cout << "eroor!" << Std::endl;
return 0;
}}else if (x = = ' # ') {if (x = = a) {flag = false;
}else {std::cout << "eroor!" << Std::endl;
return 0;
}}else if (ISPARTVN (X) && ISPARTVT (a)) {//If non-terminator int type = 0; for (auto U:ptab) {if (U.noend = = X && U.end = = a) {std::string Tempprod = U.P
Rod
Std::cout << X << "," << Tempprod << Std::endl;
if (Tempprod = = "$") { Type = 1;
Break }else {for (int i = tempprod.size () -1;i >= 0;--i) {Pstack.push (TEM
Pprod[i]);
} type = 1;
Break }}} if (type! = 1) {std::cout << "eroor!" << std::en
dl
return 0;
}}else {std::cout << "eroor!" << Std::endl;
return 0;
}} return 1;
} int main (int argc,char *argv[]) {initptab ();
Std::cout << "Please input syntax string:";
Std::cin >> pStr;
Std::cout << "Steps" << "<<" symbol stacks "<<" << "The resulting formula" << Std::endl;
int flag = Synaly ();
Std::cout << Std::endl;
if (flag = = 1) {std::cout << "analysis Success ~ ~" << Std::endl; }else {
Std::cout << "Analysis failed ~ ~" << Std::endl;
} return 0; }