Lab6
Lab6
Lab6
Aim: Write a program in C to create LL (1) parsing table for the grammar and show the
processing of any string that belong to that grammar.
E -> TE’
E’ ->+T E’|Є
T -> F T’
T’ -> *F T’ | Є
F -> (E) | id
Code:
#include <bits/stdc++.h>
struct Production
char left;
vector<char> rights;
};
struct Grammar
int num;
vector<char> T;
vector<char> N;
vector<Production> prods;
};
Grammar grammar;
stack<char> ST;
string str;
vector<char> M[50][50];
if (grammar.T[i] == ch)
return i + 1;
return 0;
if (grammar.N[i] == ch)
return i + 1;
return 0;
}
void FindFirst()
char X = grammar.T[i];
set<char> tmp;
tmp.insert(X);
first[X] = tmp;
while (change)
change = false;
char X = P.left;
auto it = FX.find(P.rights[0]);
if (it == FX.end())
change = true; // the label FIRST set has changed, the loop continues
FX.insert(P.rights[0]);
else
/* The current symbol is a non-terminal symbol, and the current symbol can be
deduced to be empty, then the next symbol needs to be judged */
int idx = 0;
next = false;
char Y = P.rights[idx];
/* Add non-empty elements in the FIRST set of the current symbol to the FIRST
set of the left symbol */
// // if (*it != '@')
if (itt == FX.end())
change = true;
FX.insert(*it);
/* The FIRST set of the current symbol is empty, mark next as true, idx subscript +1
*/
auto it = FY.find('@');
if (it != FY.end())
next = true;
idx = idx + 1;
}
cout << "FIRST:" << endl;
char X = grammar.N[i];
/* Generate the FIRST set of the alpha string and save it to the FS set */
/* The current symbol is a non-terminal symbol, if the current symbol can be pushed out, the
next symbol needs to be judged */
int idx = 0;
next = false;
if (itt == FS.end())
FS.insert(alpha[idx]);
else
char B = alpha[idx];
/* The current symbol FIRST set contains empty, mark next as true, and skip the
current loop */
if (*it == '@')
next = true;
continue;
if (itt == FS.end())
{
FS.insert(*it);
idx = idx + 1;
/* If next is true when it reaches the end of the right part of the production, it means that alpha
can be pushed empty, and the empty will be added to the FIRST set */
if (next)
FS.insert('@');
void FindFollow()
char B = grammar.N[i];
follow[B] = set<char>();
char S = grammar.N[0];
follow[S].insert('$');
while (change)
change = false;
char B = P.rights[j];
if (isNonTerminal(B))
set<char> FS;
/* alpha is the symbol string starting from the symbol next to the current symbol */
getFirstByAlphaSet(alpha, FS);
/* Add all non-empty elements in alpha's FIRST set to the current symbol's
FOLLOW set */
if (*it == '@')
continue;
if (itt == FB.end())
change = true;
FB.insert(*it);
/* If alpha can be pushed empty, or the current symbol is the end of the right-hand
side of the production, add the FOLLOW set of the left-hand symbol of the grammar to the
FOLLOW set of the current symbol */
if (itt == FB.end())
change = true;
FB.insert(*it);
}
char X = grammar.N[i];
/* Insert the generation into the corresponding item in the predictive analysis table */
int j = isTerminal(a) - 1;
/* Insert P.left->P.rights */
M[i][j].push_back(P.left);
M[i][j].push_back('-');
M[i][j].push_back('>');
M[i][j].push_back(*it);
/* Take out the production in the item corresponding to the predictive analysis table */
int i = isNonTerminal(A) - 1;
int j = isTerminal(a) - 1;
/* take out */
s.assign(M[i][j].begin(), M[i][j].end());
void BuildTable()
/* Suppose P is A->alpha */
set<char> FS;
getFirstByAlphaSet(P.rights, FS);
/* If alpha can be pushed empty, put each b in FOLLOW(A) and put A->alpha into M[A,
b]*/
if (itt != FS.end())
void parser()
if (str[str.size() - 1] != '$')
str += '$';
ST.push('$');
ST.push(grammar.N[0]);
curr_stack += '$';
curr_stack += grammar.N[0];
int idx = 0;
<< endl;
cout <<
"====================================================================
===" << endl;
do
if (isTerminal(ST.top()))
if (ST.top() == str[idx])
ST.pop();
curr_stack.pop_back();
idx++;
else
return;
else
vector<char> s;
if (!s.empty())
/* Pop the stack and push the right symbol string on the stack in reverse order */
ST.pop();
curr_stack.pop_back();
{
if (s[i] != '@')
ST.push(s[i]);
curr_stack += s[i];
else
return;
}
int main()
string s;
cin >> s;
Production temp;
temp.left = s[0];
temp.rights.push_back(s[j]);
grammar.prods.push_back(temp);
// terminals
char X = P.left;
if (!isNonTerminal(X))
grammar.N.push_back(X);
}
// non-terminals
char Y = P.rights[j];
grammar.T.push_back(Y);
grammar.T.push_back('$');
FindFirst();
FindFollow();
BuildTable();
parser();
return 0;
Output:
Aim: Write a recursive descent parser for the grammar-
S-> cAd
A->a | ab
Code:
#include <bits/stdc++.h>
string str;
if (str[str.size() - 1] != '$')
str += '$';
int idx = 0;
S(str, idx);
if (str[idx] == '$')
else
return 0;
if (str[idx] == 'c')
advance(idx);
else
return;
A(str, idx);
if (str[idx] == 'd')
advance(idx);
else
return;
if (str[idx] == 'a')
advance(idx);
else
return;
if (str[idx] == 'b')
advance(idx);
Output: