Write a program to find out the FIRST of the Non‐terminals in a grammar.
#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
// Data structure to represent a production rule
struct Production
{
string nonTerminal;
string expression;
};
// Function to calculate the FIRST set for a non-terminal
unordered_set<char> calculateFirst(const string &nonTerminal, const vector<Production> &productions, unordered_map<string, unordered_set<char>> &firstCache)
{
// If FIRST set for the non-terminal is already calculated, return it
if (firstCache.find(nonTerminal) != firstCache.end())
{
return firstCache[nonTerminal];
}
unordered_set<char> firstSet;
for (const Production &production : productions)
{
if (production.nonTerminal == nonTerminal)
{
char firstSymbol = production.expression[0];
if (isalpha(firstSymbol) && islower(firstSymbol))
{
firstSet.insert(firstSymbol);
}
else if (isalpha(firstSymbol) && isupper(firstSymbol))
{
const auto &firstSetOfSymbol = calculateFirst(string(1, firstSymbol), productions, firstCache);
firstSet.insert(firstSetOfSymbol.begin(), firstSetOfSymbol.end());
}
else if (firstSymbol == '\0')
{
firstSet.insert('\0');
}
}
}
// Cache the calculated FIRST set for future use
firstCache[nonTerminal] = firstSet;
return firstSet;
}
// Function to display a set
void displaySet(const string &setName, const unordered_set<char> &set)
{
cout << "FIRST(" << setName << "): { ";
for (char symbol : set)
{
cout << symbol << ' ';
}
cout << '}' << endl;
}
int main()
{
// Define the grammar with production rules
vector<Production> productions = {
{"S", "aAB"},
{"A", "b"},
{"A", ""},
{"B", "cC"},
{"C", "d"},
{"C", ""}};
// Cache for storing calculated FIRST sets
unordered_map<string, unordered_set<char>> firstCache;
// Calculate and display FIRST sets for each non-terminal
unordered_set<string> displayedNonTerminals;
for (const Production &production : productions)
{
const string &nonTerminal = production.nonTerminal;
// Display FIRST set only if not displayed before
if (displayedNonTerminals.find(nonTerminal) == displayedNonTerminals.end()) {
const unordered_set<char> &firstSet = calculateFirst(nonTerminal, productions, firstCache);
displaySet(nonTerminal, firstSet);
displayedNonTerminals.insert(nonTerminal);
}
}
return 0;
}
Comments
Post a Comment