0% found this document useful (0 votes)
2 views6 pages

CC Laba3

The document contains a C++ program for compiler construction focusing on context-free grammar (CFG) analysis. It includes functions to handle productions, compute first and follow sets, and check for left recursion and left factoring. The program processes a predefined CFG and outputs the results of the analysis.

Uploaded by

Zunaira Ikram
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views6 pages

CC Laba3

The document contains a C++ program for compiler construction focusing on context-free grammar (CFG) analysis. It includes functions to handle productions, compute first and follow sets, and check for left recursion and left factoring. The program processes a predefined CFG and outputs the results of the analysis.

Uploaded by

Zunaira Ikram
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

ASFA SHAFIQUE

SP22-BCS-127
SECTION A
COMPILER CONSTRUCTION
LAB ASSIGNMENT # 4

#include <iostream>
#include <string>

using namespace std;

char nonTerminals[10];
string productions[10][10];
int prodCount[10];
int nonTerminalCount = 0;

char firstSet[10][10];
int firstCount[10];
char followSet[10][10];
int followCount[10];

int NonTerminalIndex(char nt) {


for (int i = 0; i < nonTerminalCount; i++) {
if (nonTerminals[i] == nt) return i;
}
return -1;
}

void addProduction(char lhs, string rhs) {


int idx = NonTerminalIndex(lhs);
if (idx == -1) {
idx = nonTerminalCount;
nonTerminals[nonTerminalCount++] = lhs;
prodCount[idx] = 0;
}
productions[idx][prodCount[idx]++] = rhs;
}

void CFG() {
string S = "S->aSBa|B;B->bA|^;A->c|^";
int i = 0;
while (i < S.length()) {
char lhs = S[i];
i += 3;
string rhs = "";
while (i < S.length() && S[i] != ';') {
if (S[i] == '|') {
addProduction(lhs, rhs);
rhs = "";
} else {
rhs += S[i];
}
i++;
}
addProduction(lhs, rhs);
i++;
}
}

bool LeftRecursion() {
for (int i = 0; i < nonTerminalCount; i++) {
for (int j = 0; j < prodCount[i]; j++) {
if (productions[i][j][0] == nonTerminals[i]) {
return true;
}
}
}
return false;
}

bool LeftFactoring() {
for (int i = 0; i < nonTerminalCount; i++) {
for (int j = 0; j < prodCount[i]; j++) {
for (int k = j + 1; k < prodCount[i]; k++) {
if (productions[i][j][0] == productions[i][k][0]) {
return true;
}
}
}
}
return false;
}

void addToFirst(int idx, char ch) {


for (int i = 0; i < firstCount[idx]; i++) {
if (firstSet[idx][i] == ch) return;
}
firstSet[idx][firstCount[idx]++] = ch;
}

void computeFirst(int idx) {


for (int i = 0; i < prodCount[idx]; i++) {
char ch = productions[idx][i][0];
if (!(ch >= 'A' && ch <= 'Z')) {
addToFirst(idx, ch);
} else {
int next = NonTerminalIndex(ch);
if (next != -1 && next != idx) {
computeFirst(next);
for (int k = 0; k < firstCount[next]; k++) {
addToFirst(idx, firstSet[next][k]);
}
}
}
}
}

void printFirstSets() {
cout << "\nFirst Sets:\n";
for (int i = 0; i < nonTerminalCount; i++) {
computeFirst(i);
cout << "First(" << nonTerminals[i] << ") = { ";
for (int j = 0; j < firstCount[i]; j++) {
cout << firstSet[i][j];
if (j != firstCount[i] - 1) cout << ",";
}
cout << " }\n";
}
}

bool addToFollow(int idx, char ch) {


for (int i = 0; i < followCount[idx]; i++) {
if (followSet[idx][i] == ch) return false;
}
followSet[idx][followCount[idx]++] = ch;
return true;
}

bool isNullable(int idx) {


for (int i = 0; i < prodCount[idx]; i++) {
if (productions[idx][i] == "^") return true;
}
return false;
}

void computeFollowSets() {
addToFollow(0, '$');
bool changed;
do {
changed = false;
for (int i = 0; i < nonTerminalCount; i++) {
char A = nonTerminals[i];
for (int j = 0; j < prodCount[i]; j++) {
string rhs = productions[i][j];
for (int k = 0; k < rhs.size(); k++) {
char B = rhs[k];
if (B >= 'A' && B <= 'Z') {
int Bidx = NonTerminalIndex(B);
bool nullable = true;
for (int m = k + 1; m < rhs.size(); m++) {
char sym = rhs[m];
if (sym >= 'A' && sym <= 'Z') {
int symIdx = NonTerminalIndex(sym);
for (int f = 0; f < firstCount[symIdx]; f++) {
if (firstSet[symIdx][f] != '^') {
if (addToFollow(Bidx, firstSet[symIdx][f])) changed = true;
}
}
if (!isNullable(symIdx)) {
nullable = false;
break;
}
} else {
if (sym != '^') {
if (addToFollow(Bidx, sym)) changed = true;
}
nullable = false;
break;
}
}
if (nullable || k + 1 == rhs.size()) {
for (int f = 0; f < followCount[i]; f++) {
if (addToFollow(Bidx, followSet[i][f])) changed = true;
}
}
}
}
}
}
} while (changed);
}

void printFollowSets() {
cout << "\nFollow Sets:\n";
for (int i = 0; i < nonTerminalCount; i++) {
cout << "Follow(" << nonTerminals[i] << ") = { ";
char temp[10];
int count = 0;
bool hasDollar = false;

for (int j = 0; j < followCount[i]; j++) {


if (followSet[i][j] == '$') {
hasDollar = true;
} else {
temp[count++] = followSet[i][j];
}
}
for (int j = 0; j < count; j++) {
cout << temp[j];
if (j != count - 1 || hasDollar) cout << ",";
}
if (hasDollar) {
cout << "$";
}

cout << " }\n";


}
}

int main() {
CFG();

if (LeftRecursion())
cout << "\nLeft Recursion Found" << endl;
else
cout << "\nNo Left Recursion Found" << endl;
if (LeftFactoring())
cout << "Left Factoring Found" << endl;
else
cout << "No Left Factoring Found" << endl;

printFirstSets();
computeFollowSets();
printFollowSets();

return 0;
}

OUTPUT:

You might also like