Professional Documents
Culture Documents
CD Assignment-4 21brs1018
CD Assignment-4 21brs1018
CD Assignment-4 21brs1018
S → aBDh
B → cC
C → bC / ∈
D → EF
E→g/∈
F→f/∈
AIM: -
The aim of this program is to compute the First and Follow for the given
productions.
ALGORITHM: -
1. Input Grammar: Define the grammar by specifying production rules.
2. Calculate First Sets:
Iterate through each non-terminal symbol in the grammar.
For each non-terminal symbol, recursively calculate its First set.
Store the calculated First sets.
3. Calculate Follow Sets:
Iterate through each non-terminal symbol in the grammar.
For each non-terminal symbol, recursively calculate its Follow set.
Store the calculated Follow sets.
4. Display Results:
Print out the calculated First and Follow sets for each non-terminal symbol.
1|Page
SOURCE CODE: -
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int count, n = 0;
char calc_first[10][100];
char calc_follow[10][100];
int m = 0;
char production[10][10];
char f[10], first[10];
int k;
char ck;
int e;
strcpy(production[0], "S=aBDh");
strcpy(production[1], "B=cC");
strcpy(production[2], "C=bC");
strcpy(production[3], "C=#");
strcpy(production[4], "D=EF");
strcpy(production[5], "E=g");
2|Page
strcpy(production[6], "E=#");
strcpy(production[7], "F=f");
int kay;
char done[count];
int ptr = -1;
if (xxx == 1)
continue;
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
3|Page
if (first[i] == calc_first[point1][lark]) {
chk = 1;
break;
}
}
if (chk == 0) {
printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i];
}
}
printf("}\n");
jm = n;
point1++;
}
printf("\n");
printf("-----------------------------------------------"
"\n\n");
char donee[count];
ptr = -1;
4|Page
if (xxx == 1)
continue;
land += 1;
follow(ck);
ptr += 1;
donee[ptr] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;
void follow(char c)
{
int i, j;
if (production[0][0] == c) {
f[m++] = '$';
}
5|Page
for (i = 0; i < 10; i++) {
for (j = 2; j < 10; j++) {
if (production[i][j] == c) {
if (production[i][j + 1] != '\0') {
followfirst(production[i][j + 1], i,
(j + 2));
}
if (production[i][j + 1] == '\0'
&& c != production[i][0]) {
follow(production[i][0]);
}
}
}
}
}
if (!(isupper(c))) {
first[n++] = c;
}
for (j = 0; j < count; j++) {
if (production[j][0] == c) {
if (production[j][2] == '#') {
if (production[q1][q2] == '\0')
first[n++] = '#';
else if (production[q1][q2] != '\0'
&& (q1 != 0 || q2 != 0)) {
findfirst(production[q1][q2], q1,
(q2 + 1));
}
6|Page
else
first[n++] = '#';
}
else if (!isupper(production[j][2])) {
first[n++] = production[j][2];
}
else {
findfirst(production[j][2], j, 3);
}
}
}
}
if (!(isupper(c)))
f[m++] = c;
else {
int i = 0, j = 1;
for (i = 0; i < count; i++) {
if (calc_first[i][0] == c)
break;
}
follow(production[c1][0]);
}
else {
7|Page
followfirst(production[c1][c2], c1,
c2 + 1);
}
}
j++;
}
}
}
1. If the first symbol in the R.H.S of the production is a Terminal then it can
directly be included in the first set.
2. If the first symbol in the R.H.S of the production is a non-Terminal then call
the find first function again on that non-Terminal. To handle these cases like
Recursion is the best possible solution. Here again, if the First of the new
non-Terminal contains an epsilon, then we have to move to the next symbol
of the original production which can again be a Terminal or a Non-Terminal.
OUTPUT: -
8|Page
9|Page
10 | P a g e
11 | P a g e
12 | P a g e
13 | P a g e
4.b. Construct a predictive parser table using the computed First and Follow
values.
AIM: -
The aim of this program is to Construct a predictive parser table using the
computed First and Follow values.
ALGORITHM: -
1. Initialize the parsing table with empty strings.
2. For each production rule in the grammar, determine the first set of the
non-terminal symbol on the left-hand side of the rule.
3. For each terminal in the first set, add the production rule to the
corresponding cell in the parsing table.
4. If epsilon is in the first set, add the production rule to cells in the parsing
table corresponding to follow sets of the non-terminal symbol.
5. Repeat steps 2-4 for each production rule in the grammar.
6. Print the parsing table.
SOURCE CODE: -
#include <stdio.h>
#define NON_TERMINALS_COUNT 5
#define TERMINALS_COUNT 8
char parsingTable[NON_TERMINALS_COUNT][TERMINALS_COUNT][10] = {
{"aBDh", "", "", "", "", "", ""},
{"", "", "cC", "", "", "", ""},
{"", "", "", "bc", "", "#", ""},
{"g", "", "", "f", "", "", ""},
{"f", "", "", "", "f", "", "#"}
};
int main() {
14 | P a g e
printf("Predictive Parsing Table:\n");
printf(" ");
for (int j = 0; j < TERMINALS_COUNT; j++) {
printf("%c\t", terminals[j]);
}
printf("\n");
for (int i = 0; i < NON_TERMINALS_COUNT; i++) {
printf("%c ", nonTerminals[i]);
for (int j = 0; j < TERMINALS_COUNT; j++) {
printf("%s\t", parsingTable[i][j]);
}
printf("\n");
}
return 0;
}
OUTPUT: -
15 | P a g e
16 | P a g e