Skip to content

Commit 378961a

Browse files
authored
Update prog.c
1 parent e5b3f16 commit 378961a

File tree

1 file changed

+74
-103
lines changed
  • Program 6 - First of a grammar

1 file changed

+74
-103
lines changed

Program 6 - First of a grammar/prog.c

+74-103
Original file line numberDiff line numberDiff line change
@@ -1,127 +1,98 @@
11
#include <stdio.h>
22
#include <ctype.h>
3-
#include <string.h>
43

5-
int count, n = 0;
6-
// Stores the final result of the First Sets
7-
char calc_first[10][100];
8-
9-
// Stores the production rules
10-
char production[10][10];
11-
char first[10];
12-
int k;
13-
14-
void findfirst(char c, int q1, int q2)
4+
void FIRST(char[], char);
5+
void addToResultSet(char[], char);
6+
int numOfProductions;
7+
char productionSet[10][10];
8+
void main()
159
{
16-
int j;
17-
18-
// Terminal encountered
19-
if (isupper(c) == 0)
10+
int i, j;
11+
char choice;
12+
char c, g;
13+
char result[20];
14+
printf("How many number of productions ? :");
15+
scanf(" %d", &numOfProductions);
16+
for (i = 0; i < numOfProductions; i++) // read production string eg: E=E+T
2017
{
21-
first[n++] = c;
18+
printf("Enter production Number %d : ", i + 1);
19+
scanf(" %s", productionSet[i]); // contains set of all productions
2220
}
23-
24-
for (j = 0; j < count; j++)
21+
printf("FIRST OF : \n");
22+
for (i = 0; i < numOfProductions; i++)
2523
{
26-
if (production[j][0] == c)
24+
c = productionSet[i][0];
25+
FIRST(result, c); // Compute FIRST; Get Answer in 'result' array
26+
if (productionSet[i][2] != '$')
2727
{
28-
if (production[j][2] == '#')
28+
printf("(%c) ={", c);
29+
for (j = 0; result[j] != '\0'; j++)
2930
{
30-
if (production[q1][q2] == '\0')
31-
first[n++] = '#';
32-
else if (production[q1][q2] != '\0' && (q1 != 0 || q2 != 0))
33-
{
34-
// Recursion to calculate First of New non-terminal we encounter after epsilon
35-
findfirst(production[q1][q2], q1, (q2 + 1));
36-
}
37-
else
38-
first[n++] = '#';
39-
}
40-
else if (!isupper(production[j][2]))
41-
{
42-
first[n++] = production[j][2];
43-
}
44-
else
45-
{
46-
// Recursion to calculate First of new Non-Terminal we encounter at the beginning
47-
findfirst(production[j][2], j, 3);
48-
}
31+
printf("%c ", result[j]);
32+
} // Display result
33+
printf("}\n");
4934
}
5035
}
5136
}
52-
53-
int main(int argc, char **argv)
37+
/*
38+
Function FIRST:
39+
Compute the elements in FIRST(c) and write them in Result Array.
40+
*/
41+
void FIRST(char *Result, char c)
5442
{
55-
int jm = 0;
56-
int i, j, choice;
57-
char c, ch;
58-
59-
printf("Enter no. of productions: ");
60-
scanf("%d", &count);
61-
for (int i = 0; i < count; i++)
43+
int i, j, k;
44+
char subResult[20];
45+
int foundEpsilon;
46+
subResult[0] = '\0';
47+
Result[0] = '\0';
48+
// If X is terminal, FIRST(X) = {X}.
49+
if (!(isupper(c)))
6250
{
63-
printf("Enter production %d: ", i);
64-
scanf("%s", production[i]);
51+
addToResultSet(Result, c);
52+
return;
6553
}
66-
67-
char done[count];
68-
int ptr = -1;
69-
70-
// Initializing the calc_first array
71-
for (i = 0; i < count; i++)
54+
// If X is non terminal Read each production
55+
for (i = 0; i < numOfProductions; i++)
7256
{
73-
for (j = 0; j < 100; j++)
57+
// Find production with X as LHS
58+
if (productionSet[i][0] == c)
7459
{
75-
calc_first[i][j] = '!';
76-
}
77-
}
78-
int point1 = 0, point2, flag;
79-
80-
for (k = 0; k < count; k++)
81-
{
82-
c = production[k][0];
83-
point2 = 0;
84-
flag = 0;
85-
86-
// Checking if First of c has already been calculated
87-
for (int t = 0; t <= ptr; t++)
88-
if (c == done[t])
89-
flag = 1;
90-
91-
if (flag == 1)
92-
continue;
93-
94-
// Function call
95-
findfirst(c, 0, 0);
96-
ptr += 1;
97-
98-
// Adding c to the calculated list
99-
done[ptr] = c;
100-
printf("\nFirst(%c) = {", c);
101-
calc_first[point1][point2++] = c;
102-
103-
// Printing the First Sets of the grammar
104-
for (i = 0 + jm; i < n; i++)
105-
{
106-
int p = 0, chk = 0;
107-
108-
for (p = 0; p < point2; p++)
60+
// If X → ε is a production, then add ε to FIRST(X).
61+
if (productionSet[i][2] == '$')
62+
addToResultSet(Result, '$');
63+
// If X is a non-terminal, and X → Y1 Y2 … Yk is a production, then add a to FIRST(X) if for some i, a is in FIRST(Yi), and ε is in all of FIRST(Y1), …, FIRST(Yi-1).
64+
else
10965
{
110-
if (first[i] == calc_first[point1][p])
66+
j = 2;
67+
while (productionSet[i][j] != '\0')
11168
{
112-
chk = 1;
113-
break;
69+
foundEpsilon = 0;
70+
FIRST(subResult, productionSet[i][j]);
71+
for (k = 0; subResult[k] != '\0'; k++)
72+
addToResultSet(Result, subResult[k]);
73+
for (k = 0; subResult[k] != '\0'; k++)
74+
if (subResult[k] == '$')
75+
{
76+
foundEpsilon = 1;
77+
break;
78+
}
79+
// No ε found, no need to check next element
80+
if (!foundEpsilon)
81+
break;
82+
j++;
11483
}
11584
}
116-
117-
if (chk == 0)
118-
{
119-
printf("%c, ", first[i]);
120-
calc_first[point1][point2++] = first[i];
121-
}
12285
}
123-
printf("}\n");
124-
jm = n;
125-
point1++;
12686
}
87+
return;
88+
}
89+
// addToResultSet adds the computed element to result set. This code avoids multiple inclusion of elements
90+
void addToResultSet(char Result[], char val)
91+
{
92+
int k;
93+
for (k = 0; Result[k] != '\0'; k++)
94+
if (Result[k] == val)
95+
return;
96+
Result[k] = val;
97+
Result[k + 1] = '\0';
12798
}

0 commit comments

Comments
 (0)