|
1 | 1 | #include <stdio.h>
|
2 | 2 | #include <ctype.h>
|
3 |
| -#include <string.h> |
4 | 3 |
|
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() |
15 | 9 | {
|
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 |
20 | 17 | {
|
21 |
| - first[n++] = c; |
| 18 | + printf("Enter production Number %d : ", i + 1); |
| 19 | + scanf(" %s", productionSet[i]); // contains set of all productions |
22 | 20 | }
|
23 |
| - |
24 |
| - for (j = 0; j < count; j++) |
| 21 | + printf("FIRST OF : \n"); |
| 22 | + for (i = 0; i < numOfProductions; i++) |
25 | 23 | {
|
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] != '$') |
27 | 27 | {
|
28 |
| - if (production[j][2] == '#') |
| 28 | + printf("(%c) ={", c); |
| 29 | + for (j = 0; result[j] != '\0'; j++) |
29 | 30 | {
|
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"); |
49 | 34 | }
|
50 | 35 | }
|
51 | 36 | }
|
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) |
54 | 42 | {
|
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))) |
62 | 50 | {
|
63 |
| - printf("Enter production %d: ", i); |
64 |
| - scanf("%s", production[i]); |
| 51 | + addToResultSet(Result, c); |
| 52 | + return; |
65 | 53 | }
|
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++) |
72 | 56 | {
|
73 |
| - for (j = 0; j < 100; j++) |
| 57 | + // Find production with X as LHS |
| 58 | + if (productionSet[i][0] == c) |
74 | 59 | {
|
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 |
109 | 65 | {
|
110 |
| - if (first[i] == calc_first[point1][p]) |
| 66 | + j = 2; |
| 67 | + while (productionSet[i][j] != '\0') |
111 | 68 | {
|
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++; |
114 | 83 | }
|
115 | 84 | }
|
116 |
| - |
117 |
| - if (chk == 0) |
118 |
| - { |
119 |
| - printf("%c, ", first[i]); |
120 |
| - calc_first[point1][point2++] = first[i]; |
121 |
| - } |
122 | 85 | }
|
123 |
| - printf("}\n"); |
124 |
| - jm = n; |
125 |
| - point1++; |
126 | 86 | }
|
| 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'; |
127 | 98 | }
|
0 commit comments