Design requirements: For a ll (1) Grammar of any input, construct its predictive analysis table and parse the specified input string to see if it is a sentence of that grammar.
Idea: Firstly, the set first (X) construction algorithm and the set follow (A) construction algorithm are constructed, and then the Prediction Analysis table is built according to the set of primary and follow, and the analysis process of the analysis stack is printed on the specified sentence, and the sentence of the grammar is judged.
Specify grammar:
Grammar e->tkk->+tkk-> $T->fmm->*fmm-> $F->if-> (E)
For input string i+i*i#, here we give the experimental results first:
This experiment took me a day, the main difficulty lies in the first set and the recursive judgment part of the follow concentration, the other as long as the following process to determine the decision to go.
(1) The algorithm idea of finding first set
If the first character on the right of the resulting type is terminator, it is counted in the left
If the first character in the right of the resulting type is a non-terminator
The first set of the non-Terminator is asked
The non-terminator non-$first set is counted into the first set on the left
If $ is present, the pointer to the resulting type is shifted right
If there is no $, stop traversing the production and go to the next production type
If you have reached the right-most non-terminator of the production, add $ to the left first set
Handles the Terminator in the repeating first set in the array
(2) algorithm idea of seeking follow set
For each non-terminator A constructed follow (a) in the grammar G, the following rules are used consecutively until each follow is not increased.
(1) For the beginning sign of the grammar s, place # in follow (s);
(2) If the A->abb is a production type, the first (b) \{?ε} is added to follow (b);
(3) If A->ab is a production, or A->abb is a production and b=>ε (that is, Ε∈first (? b)) adds follow (A) to follow (b)
(3) algorithm idea of generating prediction analysis table
The algorithm for constructing analysis table M is:
(1) Perform the second and third steps for each a->a of grammar g;
(2) for each Terminator A∈first (a), add a->a to M[a,a];
(3) if Ε∈first (a), add any B∈follow (a) a->a to m[a,b];
(4) Mark all undefined m[a,a] with an error mark.
(4) The analysis process of the symbolic string
The general control program of the Predictive Analyzer is at all times acted upon by the stack top symbol X and the current input symbol, for any (x,a), master control program
Perform one of the following three possible actions each time;
(1) If x=a= "#", then declare the analysis successful, stop the analysis process.
(2) If X=a≠ "#", the X is evicted from the top of the stack stack, so that a points to the next input symbol.
(3) If X is a non-terminator, then view the analysis table M, if M[a,a] contains a production about X, then first drive x out of the stack stack, and then
The right symbol string of the resulting type is pushed in the reverse order one by one to advance the stack stack (if the right symbol is ε, it means not pushing anything into the stack). At the right side of the production
The symbol pushes the stack simultaneously should do this produces the corresponding semantic action, if m[a,a "the error sign" is stored, then invokes the error examination program error.
In my program, base class is the base class, is responsible for the first and follow sets, tablestack inherit the base class, to find out the analysis of the Predictive analysis table and display symbol string.
Base.h
struct Node{char left;string right;}; Class Base{protected:int T;node analy_str[100];//input Grammar parsing set<char> First_set[100];//first set set<char> Follow_set[100];//follow set vector<char> ter_copy; Go $ terminator vector<char> ter_colt;//Terminator vector<char> non_colt;//non-Terminator public:base (): T (0) {}bool isnotsymbol ( char c); int Get_index (char target);//Get subscript int Get_nindex (char target) in Terminator collection,//get subscript void Get_first in non-Terminator collection (char Target); Get first set void Get_follow (char target);//get follow set void Inputandsolve (); Processed to get first and followvoid display (); Display};
TableStack.h
Class Tablestack:p ublic base{protected:vector<char> to_any;//analysis stack vector<char> left_any;//remaining input string int tablemap[100][100];//Prediction Table Public:tablestack () {memset (Tablemap,-1, sizeof (TABLEMAP));} void Get_table (); Get the prediction table void Analyexp (string s); Processing of the analysis stack void print_out ();//output void Getans (); Combined processing};
Next, only the core recursion process in the first set is listed, with detailed comments:
void Base::get_first (char target) {int tag = 0;int flag = 0;for (int i = 0; i<t; i++) {if (Analy_str[i].left = = target)// Match the resulting left {if (!isnotsymbol (analy_str[i].right[0]))//For Terminator, directly join First{first_set[get_index (target)].insert (analy_str [i].right[0]);} else{for (int j = 0; J<analy_str[i].right.length (); j + +) {if (!isnotsymbol (Analy_str[i].right[j]))//Terminator End {First_set [Get_index (target)].insert (Analy_str[i].right[j]); Get_first (Analy_str[i].right[j]);//Recursive//cout<< "Curr:" <<ANALY_STR[I].RIGHT[J];SET<CHAR>:: Iterator it; for (it = First_set[get_index (Analy_str[i].right[j])].begin (); It! = First_set[get_index (Analy_str[i].right[j])].end (); it++) {if (*it = = ' $ ') flag = 1;elsefirst_set[get_index (target)].insert (*it);//Add non-$ in first (Y) to First (X)}if (flag = = 0) Break;else{tag + = Flag;flag = 0;}} if (tag = = Analy_str[i].right.length ())//All Right First (Y) has $, add $ to First (X) in First_set[get_index (target)].insert (' $ ');}}}
This syntax analysis of all the engineering code in my
Github, Welcome to star Study, I hope we can bring help.
Compilation principle: LL (1) Grammar parser (Predictive analysis table method)