DHRUV RAI
EN22CS301335
EXPERIMENT-5
Objective: Write a program for implementation of Predictive Parsing Table for LL (1)
grammar.
CODE:
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <iomanip>
using namespace std;
// Function to compute FIRST set
void computeFirst(char nonTerminal, map<char, vector<string>>&
productions, map<char, set<char>>& first) {
for (string production : productions[nonTerminal]) {
char firstSymbol = production[0];
if (isupper(firstSymbol)) {
computeFirst(firstSymbol, productions, first);
for (char terminal : first[firstSymbol]) {
first[nonTerminal].insert(terminal);
}
} else {
first[nonTerminal].insert(firstSymbol);
}
}
}
// Function to compute FOLLOW set
void computeFollow(char nonTerminal, map<char, vector<string>>&
productions, map<char, set<char>>& first, map<char, set<char>>&
follow) {
for (auto& prod : productions) {
24
DHRUV RAI
EN22CS301335
for (string production : prod.second) {
size_t pos = production.find(nonTerminal);
if (pos != string::npos) {
if (pos + 1 < production.length()) {
char nextSymbol = production[pos + 1];
if (isupper(nextSymbol)) {
for (char terminal : first[nextSymbol])
{
follow[nonTerminal].insert(terminal);
}
} else {
follow[nonTerminal].insert(nextSymbol);
}
} else {
for (char terminal : follow[prod.first]) {
follow[nonTerminal].insert(terminal);
}
}
}
}
}
}
// Function to construct parsing table
void constructParsingTable(map<char, vector<string>>&
productions, map<char, set<char>>& first, map<char, set<char>>&
follow, map<char, map<char, string>>& parsingTable) {
for (auto& prod : productions) {
char nonTerminal = prod.first;
for (string production : prod.second) {
char firstSymbol = production[0];
25
DHRUV RAI
EN22CS301335
if (isupper(firstSymbol)) {
for (char terminal : first[firstSymbol]) {
parsingTable[nonTerminal][terminal]=production;
}
} else {
parsingTable[nonTerminal][firstSymbol]=production;
}
if (firstSymbol == 'e') { // 'e' represents epsilon
for (char terminal : follow[nonTerminal]) {
parsingTable[nonTerminal][terminal]=production;
}
}
}
}
}
// Function to parse input string using parsing table
bool parseInput(string input, map<char, map<char, string>>&
parsingTable, char startSymbol) {
stack<char> st;
st.push('$');
st.push(startSymbol);
input.push_back('$'); // Append end marker
size_t i = 0;
while (!st.empty()) {
char top = st.top();
st.pop();
if (top == input[i]) {
i++;
} else if (isupper(top)) {
26
DHRUV RAI
EN22CS301335
string production = parsingTable[top][input[i]];
if (production.empty()) {
return false;
}
if (production != "e") { // 'e' represents epsilon
for (int j = production.length() - 1; j >= 0; j-)
{
st.push(production[j]);
}
}
} else {
return false;
}
}
return true;
}
// Function to print the parsing table systematically
void printParsingTable(map<char, map<char, string>>&
parsingTable, set<char>& terminals) {
cout << "\nSystematic Parsing Table:\n";
cout << setw(10) << "NT/T";
for (char terminal : terminals) {
cout << setw(10) << terminal;
}
cout << endl;
for (auto& row : parsingTable) {
char nonTerminal = row.first;
cout << setw(10) << nonTerminal;
for (char terminal : terminals) {
if (row.second.find(terminal) != row.second.end()) {
cout << setw(10) << row.second[terminal];
27
DHRUV RAI
EN22CS301335
} else {
cout << setw(10) << "-";
}
}
cout << endl;
}
}
int main() {
map<char, vector<string>> productions;
map<char, set<char>> first, follow;
map<char, map<char, string>> parsingTable;
set<char> terminals;
// Input production rules
cout << "Enter the number of production rules: ";
int n;
cin >> n;
cin.ignore(); // Ignore newline character
for (int i = 0; i < n; i++) {
cout << "Enter production rule " << i + 1 << ": ";
string rule;
getline(cin, rule);
char nonTerminal = rule[0];
string production = rule.substr(3);
productions[nonTerminal].push_back(production);
// Collect terminals
for (char ch : production) {
if (!isupper(ch) && ch != 'e') {
terminals.insert(ch);
}
}
28
DHRUV RAI
EN22CS301335
}
terminals.insert('$'); // Add end marker
// Compute FIRST sets
for (auto& prod : productions) {
computeFirst(prod.first, productions, first);
}
// Compute FOLLOW sets
follow['S'].insert('$'); // Assuming 'S' is the start symbol
for (auto& prod : productions) {
computeFollow(prod.first, productions, first, follow);
}
// Construct parsing table
constructParsingTable(productions, first, follow,
parsingTable);
// Print systematic parsing table
printParsingTable(parsingTable, terminals);
// Parse input string
string input;
cout << "\nEnter input string to parse: ";
cin >> input;
if (parseInput(input, parsingTable, 'S')) {
cout << "Input string is accepted by the grammar.\n";
} else {
cout << "Input string is rejected by the grammar.\n";
}
return 0;
}
29
DHRUV RAI
EN22CS301335
OUTPUT:
30