R20 CD Lab Manual
R20 CD Lab Manual
Lab Manual
1. #include <stdbool.h>
2. #include <stdio.h>
3. #include <string.h>
4. #include <stdlib.h>
5. // Returns 'true' if the character is a DELIMITER.
6. bool isDelimiter(char ch) {
7. if (ch == ' ' || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch ==
',' || ch == ';' || ch == '>' || ch == '<' || ch == '=' || ch == '(' || ch ==
')' || ch == '[' || ch == ']' || ch == '{' || ch == '}') return (true);
8. return (false);
9. }
10. // Returns 'true' if the character is an OPERATOR.
11. bool isOperator(char ch) {
12. if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '>' ||
ch == '<' || ch == '=')
13. return (true);
14. return (false);
15. }
16.
17. // Returns 'true' if the string is a VALID IDENTIFIER.
18. bool validIdentifier(char* str) {
19. if (str[0] == '0' || str[0] == '1' || str[0] == '2' ||
20. str[0] == '3' || str[0] == '4' || str[0] == '5' ||
21. str[0] == '6' || str[0] == '7' || str[0] == '8' || str[0]
== '9' || isDelimiter(str[0]) == true) return (false);
22. return (true);
23. }
24. // Returns 'true' if the string is a KEYWORD.
25. bool isKeyword(char* str) {
26. if (!strcmp(str, "if") || !strcmp(str, "else") ||
27. !strcmp(str, "while") || !strcmp(str, "do") ||
28. !strcmp(str, "break") ||
29. !strcmp(str, "continue") || !strcmp(str, "int")
30. || !strcmp(str, "double") || !strcmp(str, "float")
31. || !strcmp(str, "return") || !strcmp(str, "char")
32. || !strcmp(str, "case") || !strcmp(str, "char")
33. || !strcmp(str, "sizeof") || !strcmp(str, "long")
34. || !strcmp(str, "short") || !strcmp(str, "typedef")
35. || !strcmp(str, "switch") || !strcmp(str, "unsigned")
36. || !strcmp(str, "void") || !strcmp(str, "static")
37. || !strcmp(str, "struct") || !strcmp(str, "goto")) return
(true);
38. return (false);
39. }
40. // Returns 'true' if the string is an INTEGER.
41. bool isInteger(char* str) {
42. int i, len = strlen(str);
43.
44. if (len == 0) return (false);
45. for (i = 0; i < len; i++) {
46. if (str[i] != '0' && str[i] != '1' && str[i] != '2'
47. && str[i] != '3' && str[i] != '4' && str[i] != '5'
48. && str[i] != '6' && str[i] != '7' && str[i] != '8'
49. && str[i] != '9' || (str[i] == '-' && i > 0))
return (false);
50. }
51. return (true);
52. }
53.
54. // Returns 'true' if the string is a REAL NUMBER.
55. bool isRealNumber(char* str) {
56. int i, len = strlen(str);
57. bool hasDecimal = false;
58.
59. if (len == 0) return (false);
60. for (i = 0; i < len; i++) {
61. if (str[i] != '0' && str[i] != '1' && str[i] != '2'
62. && str[i] != '3' && str[i] != '4' && str[i] != '5'
63. && str[i] != '6' && str[i] != '7' && str[i] != '8'
64. && str[i] != '9' && str[i] != '.' ||
65. (str[i] == '-' && i > 0)) return (false);
66. if (str[i] == '.') hasDecimal = true;
67. }
68. return (hasDecimal);
69. }
70. // Extracts the SUBSTRING.
71. char* subString(char* str, int left, int right) {
72. int i;
73. char* subStr = (char*)malloc(
74. sizeof(char) * (right - left + 2));
75. for (i = left; i <= right; i++)
76. subStr[i - left] = str[i];
77. subStr[right - left + 1] = '\0';
78. return (subStr);
79. }
80. // Parsing the input STRING.
81. void parse(char* str) {
82. int left = 0, right = 0;
83. int len = strlen(str);
84. while (right <= len && left <= right) {
85. if (isDelimiter(str[right]) == false)
86. right++;
87.
88. if (isDelimiter(str[right]) == true && left == right) {
89. if (isOperator(str[right]) == true)
90. printf("'%c' IS AN OPERATOR\n", str[right]);
91.
92. right++;
93. left = right;
94. } else if (isDelimiter(str[right]) == true && left != right
95. || (right == len && left != right)) {
96. char* subStr = subString(str, left, right - 1);
97.
98. if (isKeyword(subStr) == true)
99. printf("'%s' IS A KEYWORD\n", subStr);
100.
101. else if (isInteger(subStr) == true) printf("'%s' IS AN
INTEGER\n", subStr);
102. else if (isRealNumber(subStr) == true) printf("'%s' IS A
REAL NUMBER\n", subStr);
103. else if (validIdentifier(subStr) == true
104. && isDelimiter(str[right - 1]) == false)
printf("'%s' IS A VALID IDENTIFIER\n", subStr);
105.
106. else if (validIdentifier(subStr) == false
107. && isDelimiter(str[right - 1]) == false)
108. printf("'%s' IS NOT A VALID IDENTIFIER\n", subStr);
109. left = right;
110. }
111. }
112. return;
113. }
114. // DRIVER FUNCTION
115. int main() {
116. // maximum length of string is 100 here
117. char str[100] = "int a = b + 1c; ";
118. parse(str); // calling the parse function
119. return (0);
120. }
Output:
'int' IS A KEYWORD
'a' IS A VALID IDENTIFIER
'=' IS AN OPERATOR
'b' IS A VALID IDENTIFIER
'+' IS AN OPERATOR
'1c' IS NOT A VALID IDENTIFIER
Experiment 2
Aim:
Write a Lex Program to implement a Lexical Analyzer using Lex tool.
Program:
1. %{
2. int COMMENT=0;
3. %}
4. identifier [a-zA-Z][a-zA-Z0-9]*
5. %%
6. #.* {printf("\n%s is a preprocessor directive",yytext);}
7. int |
8. float |
9. char |
10. double |
11. while |
12. for |
13. struct |
14. typedef |
15. do |
16. if |
17. break |
18. continue |
19. void |
20. switch |
21. return |
22. else |
23. goto {printf("\n%s is a keyword",yytext);}
24. "/*" {COMMENT=1;}{printf("\n%s is a COMMENT",yytext);}
25. {identifier}\( {if(!COMMENT)printf("\nFUNCTION\t%s",yytext);}
26. \{ {if(!COMMENT)printf("\nBLOCK BEGINS");}
27. \} {if(!COMMENT)printf("BLOCK ENDS");}
28. {identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n%s
IDENTIFIER",yytext);}
29. \".*\" {if(!COMMENT)printf("\n%s is a STRING",yytext);}
30. [0-9]+ {if(!COMMENT) printf("\n%s is a NUMBER ",yytext);}
31. \)(\:)? {if(!COMMENT)printf("\n");ECHO;printf("\n");}
32. \( ECHO;
33. = {if(!COMMENT)printf("\n%s is an ASSIGNMENT OPERATOR",yytext);}
34. \<= |
35. \>= |
36. \< |
37. == |
38. \> {if(!COMMENT) printf("\n%s is a RELATIONAL OPERATOR",yytext);}
39. %%
40. int main(int argc, char **argv)
41. {
42. FILE *file;
43. file=fopen("var.c","r");
44. if(!file)
45. {
46. printf("could not open the file");
47. exit(0);
48. }
49. yyin=file;
50. yylex();
51. printf("\n");
52. return(0);
53. }
54. int yywrap()
55. {
56. return(1);
57. }
Input:
(save as "var.c" file)
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
Output:
void is a keyword
FUNCTION main(
)
BLOCK BEGINS
int is a keyword
a IDENTIFIER,
b IDENTIFIER,
c IDENTIFIER;
a IDENTIFIER
= is an ASSIGNMENT OPERATOR
1 is a NUMBER ;
b IDENTIFIER
= is an ASSIGNMENT OPERATOR
2 is a NUMBER ;
c IDENTIFIER
= is an ASSIGNMENT OPERATOR
a IDENTIFIER+
b IDENTIFIER;
FUNCTION printf(
"Sum:%d" is a STRING,
c IDENTIFIER
)
;
BLOCK ENDS
Experiment 3
Aim:
Write a C program to Simulate Lexical Analyzer to validating a given input String.
Program:
1. #include <stdio.h>
2. #include <string.h>
3. int main() {
4. char arithmetic[5] = {'+', '-', '*', '/', '%'};
5. char relational[4] = {'<', '>', '!', '='};
6. char bitwise[5] = {'&', '^', '~', '|'};
7. char str[2] = {' ', ' '};
8. printf("Enter value to be identified: ");
9. scanf("%s", &str);
10. int i;
11. if (((str[0] == '&' || str[0] == '|') && str[0] == str[1]) ||
12. (str[0] == '!' && str[1] == '\0')) {
13. printf("\nIt is Logical operator");
14. }
15. for (i = 0; i < 4; i++) {
16. if (str[0] == relational[i] && (str[1] == '=' || str[1] == '\0')) {
17. printf("\nIt is relational operator.");
18. break;
19. }
20. }
21. for (i = 0; i < 4; i++) {
22. if ((str[0] == bitwise[i] && str[1] == '\0') ||
23. ((str[0] == '<' || str[0] == '>') && str[1] == str[0])) {
24. printf("\nIt is bitwise operator.");
25. break;
26. }
27. }
28. if (str[0] == '?' && str[1] == ':')
29. printf("\nIt is ternary operator.");
30. for (i = 0; i < 5; i++) {
31. if ((str[0] == '+' || str[0] == '-') && str[0] == str[1]) {
32. printf("\nIt is unary operator.");
33. break;
34. } else if ((str[0] == arithmetic[i] && str[1] == '=') ||
35. (str[0] == '=' && str[1] == ' ')) {
36. printf("\nIt is assignment operator.");
37. break;
38. } else if (str[0] == arithmetic[i] && str[1] == '\0') {
39. printf("\nIt is arithmetic operator.");
40. break;
41. }
42. }
43. printf("\n");
44. return 0;
45. }
Output:
Enter value to be identified: +
It is arithmetic operator.
Experiment 4
Aim:
Write a C program to implement the Brute force technique of Top down Parsing.
Program:
1. #include <iostream>
2. #include <cstring>
3. using namespace std;
4.
5. class parse {
6. int nt, t, m[20][20], i, s, n, p1, q, k, j;
7. char p[30][30], n1[20], t1[20], ch, b, c, f[30][30], fl[30][30];
8.
9. public:
10. int scant(char);
11. int scannt(char);
12. void process();
13. void input();
14. };
15.
16. int parse::scannt(char a) {
17. int c = -1, i;
18. for (i = 0; i < nt; i++) {
19. if (n1[i] == a) {
20. return i;
21. }
22. }
23. return c;
24. }
25.
26. int parse::scant(char b) {
27. int c1 = -1, j;
28. for (j = 0; j < t; j++) {
29. if (t1[j] == b) {
30. return j;
31. }
32. }
33. return c1;
34. }
35.
36. void parse::input()
37.
38. {
39. cout << "Enter the number of productions:";
40. cin >> n;
41. cout << "Enter the productions one by one" << endl;
42. for (i = 0; i < n; i++)
43. cin >> p[i];
44. nt = 0;
45. t = 0;
46. }
47.
48. void parse::process() {
49. for (i = 0; i < n; i++) {
50. if (scannt(p[i][0]) == -1)
51. n1[nt++] = p[i][0];
52. }
53. for (i = 0; i < n; i++) {
54. for (j = 3; j < strlen(p[i]); j++) {
55. if (p[i][j] != 'e') {
56. if (scannt(p[i][j]) == -1) {
57. if ((scant(p[i][j])) == -1)
58. t1[t++] = p[i][j];
59. }
60. }
61. }
62. }
63. t1[t++] = '$';
64. for (i = 0; i < nt; i++) {
65. for (j = 0; j < t; j++)
66. m[i][j] = -1;
67. }
68. for (i = 0; i < nt; i++) {
69. cout << "Enter first[" << n1[i] << "]:";
70. cin >> f[i];
71. }
72.
73. for (i = 0; i < nt; i++) {
74. cout << "Enter follow[" << n1[i] << "]:";
75. cin >> fl[i];
76. }
77. for (i = 0; i < n; i++) {
78. p1 = scannt(p[i][0]);
79. if ((q = scant(p[i][3])) != -1)
80. m[p1][q] = i;
81. if ((q = scannt(p[i][3])) != -1) {
82. for (j = 0; j < strlen(f[q]); j++)
83. m[p1][scant(f[q][j])] = i;
84. }
85. if (p[i][3] == 'e') {
86. for (j = 0; j < strlen(fl[p1]); j++)
87. m[p1][scant(fl[p1][j])] = i;
88. }
89. }
90. for (i = 0; i < t; i++)
91. cout << "\t" << t1[i];
92. cout << endl;
93. for (j = 0; j < nt; j++) {
94. cout << n1[j];
95. for (i = 0; i < t; i++) {
96. cout << "\t"
97. << " ";
98. if (m[j][i] != -1)
99. cout << p[m[j][i]];
100. }
101. cout << endl;
102. }
103. }
104.
105. int main() {
106. parse p;
107. p.input();
108. p.process();
109. }
Output:
Enter the number of productions: 8
Enter the productions one by one
E->TA
A->+TA
A->e
T->FB
B->e
B->*FB
F->(E)
F->i
Enter first[E]:(i
Enter first[A]:+e
Enter first[T]:(i
Enter first[B]:*e
Enter first[F]:(i
Enter follow[E]:$)
Enter follow[A]:$)
Enter follow[T]:+)$
Enter follow[B]:+)$
Enter follow[F]:+*)$
+ * ( ) i $
E E->TA E->TA
A A->+TA A->e A->e
T T->FB T->FB
B B->e B->*FB B->e B->e
F F->(E) F->i
Experiment 5
Aim:
Write a C program to implement a Recursive Descent Parser.
Program:
1. #include <stdio.h>
2. #include <string.h>
3.
4. #define SUCCESS 1
5. #define FAILED 0
6.
7. int E(), Edash(), T(), Tdash(), F();
8.
9. const char* cursor;
10. char string[64];
11.
12. int main() {
13. puts("Enter the string");
14. scanf("%s", string);
15. cursor = string;
16. puts("");
17. puts("Input\tAction");
18. puts("--------------------------------");
19.
20. if (E() && *cursor == '\0') {
21. puts("--------------------------------");
22. puts("String is successfully parsed");
23. return 0;
24. } else {
25. puts("--------------------------------");
26. puts("Error in parsing String");
27. return 1;
28. }
29. }
30.
31. int E() {
32. printf("%-16s E -> T E'\n", cursor);
33. if (T()) {
34. if (Edash())
35. return SUCCESS;
36. else
37. return FAILED;
38. } else
39. return FAILED;
40. }
41.
42. int Edash() {
43. if (*cursor == '+') {
44. printf("%-16s E' -> + T E'\n", cursor);
45. cursor++;
46. if (T()) {
47. if (Edash())
48. return SUCCESS;
49. else
50. return FAILED;
51. } else
52. return FAILED;
53. } else {
54. printf("%-16s E' -> $\n", cursor);
55. return SUCCESS;
56. }
57. }
58.
59. int T() {
60. printf("%-16s T -> F T'\n", cursor);
61. if (F()) {
62. if (Tdash())
63. return SUCCESS;
64. else
65. return FAILED;
66. } else
67. return FAILED;
68. }
69.
70. int Tdash() {
71. if (*cursor == '*') {
72. printf("%-16s T' -> * F T'\n", cursor);
73. cursor++;
74. if (F()) {
75. if (Tdash())
76. return SUCCESS;
77. else
78. return FAILED;
79. } else
80. return FAILED;
81. } else {
82. printf("%-16s T' -> $\n", cursor);
83. return SUCCESS;
84. }
85. }
86.
87. int F() {
88. if (*cursor == '(') {
89. printf("%-16s F -> ( E )\n", cursor);
90. cursor++;
91. if (E()) {
92. if (*cursor == ')') {
93. cursor++;
94. return SUCCESS;
95. } else
96. return FAILED;
97. } else
98. return FAILED;
99. } else if (*cursor == 'i') {
100. cursor++;
101. printf("%-16s F ->i\n", cursor);
102. return SUCCESS;
103. } else
104. return FAILED;
105. }
106.
Output:
Enter the string
i+i
Input Action
--------------------------------
i+i E -> T E'
i+i T -> F T'
+i F ->i
+i T' -> $
+i E' -> + T E'
i T -> F T'
F ->i
T' -> $
E' -> $
--------------------------------
String is successfully parsed
Experiment 6
Aim:
Write C program to compute the First and Follow Sets for the given Grammar.
Program:
1. #include <ctype.h>
2. #include <stdio.h>
3. #include <string.h>
4.
5. // Functions to calculate Follow
6. void followfirst(char, int, int);
7. void follow(char c);
8.
9. // Function to calculate First
10. void findfirst(char, int, int);
11. int count, n = 0;
12.
13. // Stores the final result
14. // of the First Sets
15. char calc_first[10][100];
16.
17. // Stores the final result
18. // of the Follow Sets
19. char calc_follow[10][100];
20. int m = 0;
21.
22. // Stores the production rules
23. char production[10][10];
24. char f[10], first[10];
25. int k;
26. char ck;
27. int e;
28.
29. int main(int argc, char** argv) {
30. int jm = 0;
31. int km = 0;
32. int i, choice;
33. char c, ch;
34. count = 8;
35.
36. // The Input grammar
37. strcpy(production[0], "E=TR");
38. strcpy(production[1], "R=+TR");
39. strcpy(production[2], "R=#");
40. strcpy(production[3], "T=FY");
41. strcpy(production[4], "Y=*FY");
42. strcpy(production[5], "Y=#");
43. strcpy(production[6], "F=(E)");
44. strcpy(production[7], "F=i");
45. int kay;
46. char done[count];
47. int ptr = -1;
48.
49. // Initializing the calc_first array
50. for (k = 0; k < count; k++) {
51. for (kay = 0; kay < 100; kay++) {
52. calc_first[k][kay] = '!';
53. }
54. }
55.
56. int point1 = 0, point2, xxx;
57. for (k = 0; k < count; k++) {
58. c = production[k][0];
59. point2 = 0;
60. xxx = 0;
61.
62. // Checking if First of c has
63. // already been calculated
64. for (kay = 0; kay <= ptr; kay++)
65. if (c == done[kay])
66. xxx = 1;
67.
68. if (xxx == 1)
69. continue;
70.
71. // Function call
72. findfirst(c, 0, 0);
73. ptr += 1;
74.
75. // Adding c to the calculated list
76. done[ptr] = c;
77. printf("\n First(%c) = { ", c);
78. calc_first[point1][point2++] = c;
79.
80. // Printing the First Sets of the grammar
81. for (i = 0 + jm; i < n; i++) {
82. int lark = 0, chk = 0;
83.
84. for (lark = 0; lark < point2; lark++) {
85. if (first[i] == calc_first[point1][lark]) {
86. chk = 1;
87. break;
88. }
89. }
90. if (chk == 0) {
91. printf("%c, ", first[i]);
92. calc_first[point1][point2++] = first[i];
93. }
94. }
95. printf("}\n");
96. jm = n;
97. point1++;
98. }
99. printf("\n");
100. printf("----------\n\n");
101. char donee[count];
102. ptr = -1;
103.
104. // Initializing the calc_follow array
105. for (k = 0; k < count; k++) {
106. for (kay = 0; kay < 100; kay++) {
107. calc_follow[k][kay] = '!';
108. }
109. }
110. point1 = 0;
111. int land = 0;
112. for (e = 0; e < count; e++) {
113. ck = production[e][0];
114. point2 = 0;
115. xxx = 0;
116.
117. // Checking if Follow of ck
118. // has already been calculated
119. for (kay = 0; kay <= ptr; kay++)
120. if (ck == donee[kay])
121. xxx = 1;
122.
123. if (xxx == 1)
124. continue;
125. land += 1;
126. // Function call
127. follow(ck);
128. ptr += 1;
129.
130. // Adding ck to the calculated list
131. donee[ptr] = ck;
132. printf(" Follow(%c) = { ", ck);
133. calc_follow[point1][point2++] = ck;
134.
135. // Printing the Follow Sets of the grammar
136. for (i = 0 + km; i < m; i++) {
137. int lark = 0, chk = 0;
138. for (lark = 0; lark < point2; lark++) {
139. if (f[i] == calc_follow[point1][lark]) {
140. chk = 1;
141. break;
142. }
143. }
144. if (chk == 0) {
145. printf("%c, ", f[i]);
146. calc_follow[point1][point2++] = f[i];
147. }
148. }
149. printf(" }\n\n");
150. km = m;
151. point1++;
152. }
153. }
154.
155. void follow(char c) {
156. int i, j;
157.
158. // Adding "$" to the follow
159. // set of the start symbol
160. if (production[0][0] == c) {
161. f[m++] = '$';
162. }
163. for (i = 0; i < 10; i++) {
164. for (j = 2; j < 10; j++) {
165. if (production[i][j] == c) {
166. if (production[i][j + 1] != '\0') {
167. // Calculate the first of the next
168. // Non-Terminal in the production
169. followfirst(production[i][j + 1], i, (j + 2));
170. }
171. if (production[i][j + 1] == '\0' && c != production[i][0]) {
172. // Calculate the follow of the Non-Terminal
173. // in the L.H.S. of the production
174. follow(production[i][0]);
175. }
176. }
177. }
178. }
179. }
180.
181. void findfirst(char c, int q1, int q2) {
182. int j;
183. // The case where we
184. // encounter a Terminal
185. if (!(isupper(c))) {
186. first[n++] = c;
187. }
188. for (j = 0; j < count; j++) {
189. if (production[j][0] == c) {
190. if (production[j][2] == '#') {
191. if (production[q1][q2] == '\0')
192. first[n++] = '#';
193. else if (production[q1][q2] != '\0' && (q1 != 0 || q2 != 0)) {
194. // Recursion to calculate First of New
195. // Non-Terminal we encounter after epsilon
196. findfirst(production[q1][q2], q1, (q2 + 1));
197. } else
198. first[n++] = '#';
199. } else if (!isupper(production[j][2])) {
200. first[n++] = production[j][2];
201. } else {
202. // Recursion to calculate First of
203. // New Non-Terminal we encounter
204. // at the beginning
205. findfirst(production[j][2], j, 3);
206. }
207. }
208. }
209. }
210.
211. void followfirst(char c, int c1, int c2) {
212. int k;
213.
214. // The case where we encounter
215. // a Terminal
216. if (!(isupper(c)))
217. f[m++] = c;
218. else {
219. int i = 0, j = 1;
220. for (i = 0; i < count; i++) {
221. if (calc_first[i][0] == c)
222. break;
223. }
224. // Including the First set of the
225. // Non-Terminal in the Follow of
226. // the original query
227. while (calc_first[i][j] != '!') {
228. if (calc_first[i][j] != '#') {
229. f[m++] = calc_first[i][j];
230. } else {
231. if (production[c1][c2] == '\0') {
232. // Case where we reach the
233. // end of a production
234. follow(production[c1][0]);
235. } else {
236. // Recursion to the next symbol
237. // in case we encounter a "#"
238. followfirst(production[c1][c2], c1, c2 + 1);
239. }
240. }
241. j++;
242. }
243. }
244. }
Output:
First(E) = { (, i, }
First(R) = { +, #, }
First(T) = { (, i, }
First(Y) = { *, #, }
First(F) = { (, i, }
----------
Follow(E) = { $, ), }
Follow(R) = { $, ), }
Follow(T) = { +, $, ), }
Follow(Y) = { +, $, ), }
Follow(F) = { *, +, $, ), }
Experiment 7
Aim:
Write a C program for eliminating the left recursion and left factoring of a given grammar.
Program:
1. #include <conio.h>
2. #include <stdio.h>
3. #include <string.h>
4. #include <iostream>
5. using namespace std;
6.
7. // Structure Declaration
8.
9. struct production {
10. char lf;
11. char rt[10];
12. int prod_rear;
13. int fl;
14. };
15. struct production prodn[20], prodn_new[20]; // Creation of object
16.
17. // Variables Declaration
18.
19. int b = -1, d, f, q, n, m = 0, c = 0;
20. char terminal[20], nonterm[20], alpha[10], extra[10];
21. char epsilon = '^';
22.
23. // Beginning of Main Program
24.
25. int main() {
26. // Input of Special characters
27. cout << "\nEnter the number of Special characters(except non-terminals):
";
28. cin >> q;
29. cout << "Enter the special characters for your production: ";
30. int cnt;
31. for (cnt = 0; cnt < q; cnt++) {
32. cin >> alpha[cnt];
33. }
34.
35. // Input of Productions
36.
37. cout << "\nEnter the number of productions: ";
38. cin >> n;
39. for (cnt = 0; cnt <= n - 1; cnt++) {
40. cout << "Enter the " << cnt + 1 << " production: ";
41. cin >> prodn[cnt].lf;
42. cout << "->";
43. cin >> prodn[cnt].rt;
44. prodn[cnt].prod_rear = strlen(prodn[cnt].rt);
45. prodn[cnt].fl = 0;
46. }
47.
48. // Condition for left factoring
49.
50. for (int cnt1 = 0; cnt1 < n; cnt1++) {
51. for (int cnt2 = cnt1 + 1; cnt2 < n; cnt2++) {
52. if (prodn[cnt1].lf == prodn[cnt2].lf) {
53. cnt = 0;
54. int p = -1;
55. while ((prodn[cnt1].rt[cnt] != '\0') && (prodn[cnt2].rt[cnt] !=
'\0')) {
56. if (prodn[cnt1].rt[cnt] == prodn[cnt2].rt[cnt]) {
57. extra[++p] = prodn[cnt1].rt[cnt];
58. prodn[cnt1].fl = 1;
59. prodn[cnt2].fl = 1;
60. } else {
61. if (p == -1)
62. break;
63. else {
64. int h = 0, u = 0;
65. prodn_new[++b].lf = prodn[cnt1].lf;
66. strcpy(prodn_new[b].rt, extra);
67. prodn_new[b].rt[p + 1] = alpha[c];
68. prodn_new[++b].lf = alpha[c];
69. int g;
70. for (g = cnt; g < prodn[cnt2].prod_rear; g++)
71. prodn_new[b].rt[h++] = prodn[cnt2].rt[g];
72. prodn_new[++b].lf = alpha[c];
73. for (g = cnt; g <= prodn[cnt1].prod_rear; g++)
74. prodn_new[b].rt[u++] = prodn[cnt1].rt[g];
75. m = 1;
76. break;
77. }
78. }
79. cnt++;
80. }
81. if ((prodn[cnt1].rt[cnt] == 0) && (m == 0)) {
82. int h = 0;
83. prodn_new[++b].lf = prodn[cnt1].lf;
84. strcpy(prodn_new[b].rt, extra);
85. prodn_new[b].rt[p + 1] = alpha[c];
86. prodn_new[++b].lf = alpha[c];
87. prodn_new[b].rt[0] = epsilon;
88. prodn_new[++b].lf = alpha[c];
89. for (int g = cnt; g < prodn[cnt2].prod_rear; g++)
90. prodn_new[b].rt[h++] = prodn[cnt2].rt[g];
91. }
92. if ((prodn[cnt2].rt[cnt] == 0) && (m == 0)) {
93. int h = 0;
94. prodn_new[++b].lf = prodn[cnt1].lf;
95. strcpy(prodn_new[b].rt, extra);
96. prodn_new[b].rt[p + 1] = alpha[c];
97. prodn_new[++b].lf = alpha[c];
98. prodn_new[b].rt[0] = epsilon;
99. prodn_new[++b].lf = alpha[c];
100. for (int g = cnt; g < prodn[cnt1].prod_rear; g++)
101. prodn_new[b].rt[h++] = prodn[cnt1].rt[g];
102. }
103. c++;
104. m = 0;
105. }
106. }
107. }
108.
109. // Display of Output
110.
111. cout << "\n\n********************************";
112. cout << "\n AFTER LEFT FACTORING ";
113. cout << "\n********************************";
114. cout << endl;
115. for (int cnt3 = 0; cnt3 <= b; cnt3++) {
116. cout << "Production " << cnt3 + 1 << " is: ";
117. cout << prodn_new[cnt3].lf;
118. cout << "->";
119. cout << prodn_new[cnt3].rt;
120. cout << endl << endl;
121. }
122.
123. for (int cnt4 = 0; cnt4 < n; cnt4++) {
124. if (prodn[cnt4].fl == 0) {
125. cout << "Production " << cnt4 + 1 << " is: ";
126. cout << prodn[cnt4].lf;
127. cout << "->";
128. cout << prodn[cnt4].rt;
129. cout << endl << endl;
130. }
131. }
132. }
Output:
Enter the number of Special characters(except non-terminals): 1
Enter the special characters for your production: R
Enter the number of productions: 4
Enter the 1 production: S
->iCtS
Enter the 2 production: S
->iCtSeS
Enter the 3 production: S
->a
Enter the 4 production: C
->b
********************************
AFTER LEFT FACTORING
********************************
Production 1 is: S->iCtSR
1. #include <stdio.h>
2. #include <string.h>
3.
4. char prol[7][10] = {"S", "A", "A", "B", "B", "C", "C"};
5. char pror[7][10] = {"A", "Bb", "Cd", "aB", "@", "Cc", "@"};
6.
7. char prod[7][10] = {"S->A", "A->Bb", "A->Cd", "B->aB", "B->@", "C->Cc", "C-
>@"};
8. char first[7][10] = {"abcd", "ab", "cd", "a@", "@", "c@", "@"};
9. char follow[7][10] = {"$", "$", "$", "a$", "b$", "c$", "d$"};
10. char table[5][6][10];
11.
12. int numr(char c) {
13. switch (c) {
14. case 'S':
15. return 0;
16.
17. case 'A':
18. return 1;
19.
20. case 'B':
21. return 2;
22.
23. case 'C':
24. return 3;
25. case 'a':
26. return 0;
27. case 'b':
28. return 1;
29.
30. case 'c':
31. return 2;
32.
33. case 'd':
34. return 3;
35.
36. case '$':
37. return 4;
38. }
39. return (2);
40. }
41. int main()
42.
43. {
44. int i, j, k;
45.
46. for (i = 0; i < 5; i++)
47. for (j = 0; j < 6; j++)
48. strcpy(table[i][j], " ");
49. printf("The following grammar is used for Parsing Table:\n");
50. for (i = 0; i < 7; i++)
51. printf("%s\n", prod[i]);
52. printf("\nPredictive parsing table:\n");
53. fflush(stdin);
54. for (i = 0; i < 7; i++) {
55. k = strlen(first[i]);
56. for (j = 0; j < 10; j++)
57. if (first[i][j] != '@')
58. strcpy(table[numr(prol[i][0]) + 1][numr(first[i][j]) + 1],
prod[i]);
59. }
60.
61. for (i = 0; i < 7; i++) {
62. if (strlen(pror[i]) == 1) {
63. if (pror[i][0] == '@') {
64. k = strlen(follow[i]);
65. for (j = 0; j < k; j++)
66. strcpy(table[numr(prol[i][0]) + 1][numr(follow[i][j]) + 1],
prod[i]);
67. }
68. }
69. }
70.
71. strcpy(table[0][0], " ");
72.
73. strcpy(table[0][1], "a");
74.
75. strcpy(table[0][2], "b");
76.
77. strcpy(table[0][3], "c");
78.
79. strcpy(table[0][4], "d");
80. strcpy(table[0][5], "$");
81. strcpy(table[1][0], "S");
82.
83. strcpy(table[2][0], "A");
84.
85. strcpy(table[3][0], "B");
86.
87. strcpy(table[4][0], "C");
88.
89. printf("\n \n");
90.
91. for (i = 0; i < 5; i++)
92. for (j = 0; j < 6; j++) {
93. printf("%-10s", table[i][j]);
94. if (j == 5)
95. printf("\n\t\n");
96. }
97. }
Output:
The following grammar is used for Parsing Table:
S->A
A->Bb
A->Cd
B->aB
B->@
C->Cc
C->@
a b c d $
1. #include <conio.h>
2. #include <stdio.h>
3. #include <string.h>
4.
5. char stack[30];
6. int top = -1;
7. void push(char c) {
8. top++;
9. stack[top] = c;
10. }
11. char pop() {
12. char c;
13. if (top != -1) {
14. c = stack[top];
15. top--;
16. return c;
17. }
18. return 'x';
19. }
20. void printstat() {
21. int i;
22. printf("\n$");
23. for (i = 0; i <= top; i++)
24. printf("%c", stack[i]);
25. }
26. void main() {
27. int i, j, k, l;
28. char s1[20], s2[20], ch1, ch2, ch3;
29. printf("\nLR PARSING");
30. printf("\nENTER THE EXPRESSION:\n");
31. scanf("%s", s1);
32. l = strlen(s1);
33. j = 0;
34. printf("\n$");
35. for (i = 0; i < l; i++) {
36. if (s1[i] == 'i' && s1[i + 1] == 'd') {
37. s1[i] = ' ';
38. s1[i + 1] = 'E';
39. printstat();
40. printf("id");
41. push('E');
42. printstat();
43. } else if (s1[i] == '+' || s1[i] == '-' || s1[i] == '*' || s1[i] ==
'/' ||
44. s1[i] == 'd') {
45. push(s1[i]);
46. printstat();
47. }
48. }
49. printstat();
50. l = strlen(s2);
51. while (l) {
52. ch1 = pop();
53. if (ch1 == 'x') {
54. printf("\n$");
55. break;
56. }
57. if (ch1 == '+' || ch1 == '/' || ch1 == '*' || ch1 == '-') {
58. ch3 = pop();
59. if (ch3 != 'E') {
60. printf("error\n");
61. return;
62. } else {
63. push('E');
64. printstat();
65. }
66. }
67. ch2 = ch1;
68. }
69. printf("\n");
70. }
Output:
LR PARSING
ENTER THE EXPRESSION:
id+id
$
$id
$E
$E+
$E+id
$E+E
$E+E
$E
$
Experiment 10
Aim:
Write a C program for implementation of a Shift Reduce Parser using Stack Data Structure to
accept a given input string of a given grammar.
Program:
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <string.h>
4. // Global Variables
5. int z = 0, i = 0, j = 0, c = 0;
6.
7. // Modify array size to increase
8. // length of string to be parsed
9. char a[16], ac[20], stk[15], act[10];
10.
11. // This Function will check whether
12. // the stack contain a production rule
13. // which is to be Reduce.
14. // Rules can be E->2E2 , E->3E3 , E->4
15. void check() {
16. // Copying string to be printed as action
17. strcpy(ac, "REDUCE TO E -> ");
18.
19. // c=length of input string
20. for (z = 0; z < c; z++) {
21. // checking for producing rule E->4
22. if (stk[z] == '4') {
23. printf("%s4", ac);
24. stk[z] = 'E';
25. stk[z + 1] = '\0';
26.
27. // printing action
28. printf("\n$%s\t%s$\t", stk, a);
29. }
30. }
31.
32. for (z = 0; z < c - 2; z++) {
33. // checking for another production
34. if (stk[z] == '2' && stk[z + 1] == 'E' && stk[z + 2] == '2') {
35. printf("%s2E2", ac);
36. stk[z] = 'E';
37. stk[z + 1] = '\0';
38. stk[z + 2] = '\0';
39. printf("\n$%s\t%s$\t", stk, a);
40. i = i - 2;
41. }
42. }
43.
44. for (z = 0; z < c - 2; z++) {
45. // checking for E->3E3
46. if (stk[z] == '3' && stk[z + 1] == 'E' && stk[z + 2] == '3') {
47. printf("%s3E3", ac);
48. stk[z] = 'E';
49. stk[z + 1] = '\0';
50. stk[z + 1] = '\0';
51. printf("\n$%s\t%s$\t", stk, a);
52. i = i - 2;
53. }
54. }
55. return; // return to main
56. }
57.
58. // Driver Function
59. int main() {
60. printf("GRAMMAR is:\nE->2E2 \nE->3E3 \nE->4\n");
61.
62. // a is input string
63. strcpy(a, "32423");
64. // strlen(a) will return the length of a to c
65. c = strlen(a);
66. // "SHIFT" is copied to act to be printed
67. strcpy(act, "SHIFT");
68.
69. // This will print Labels (column name)
70. printf("\nstack \t input \t action");
71.
72. // This will print the initial
73. // values of stack and input
74. printf("\n$\t%s$\t", a);
75.
76. // This will Run upto length of input string
77. for (i = 0; j < c; i++, j++) {
78. // Printing action
79. printf("%s", act);
80. // Pushing into stack
81. stk[i] = a[j];
82. stk[i + 1] = '\0';
83.
84. // Moving the pointer
85. a[j] = ' ';
86.
87. // Printing action
88. printf("\n$%s\t%s$\t", stk, a);
89.
90. // Call check function ..which will
91. // check the stack whether its contain
92. // any production or not
93. check();
94. }
95.
96. // Rechecking last time if contain
97. // any valid production then it will
98. // replace otherwise invalid
99. check();
100.
101. // if top of the stack is E(starting symbol)
102. // then it will accept the input
103. if (stk[0] == 'E' && stk[1] == '\0')
104. printf("Accept\n");
105. else // else reject
106. printf("Reject\n");
107. }
Output:
GRAMMAR is:
E->2E2
E->3E3
E->4
39. yyparse();
40. if(flag==0)
41. printf("\nEntered arithmetic expression is Valid\n\n");
42. }
43. void yyerror()
44. {
45. printf("\nEntered arithmetic expression is Invalid\n\n"); flag=1;
46. }
Output:
Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Division, Modulus and Round brackets:
(5+10-15+20)%3
Result=2
1. #include <stdio.h>
2. #include <string.h>
3.
4. void pm();
5. void plus();
6. void div();
7. int i, ch, j, l, addr = 100;
8. char ex[10], exp[10], exp1[10], exp2[10], id1[5], op[5], id2[5];
9. void main() {
10. while (1) {
11. printf(
12. "\n1. Assignment\n2. Arithmetic\n3. Relational\n4. Exit\nEnter the
"
13. "choice:");
14. scanf("%d", &ch);
15. switch (ch) {
16. case 1:
17. printf("\nEnter the expression with assignment operator: ");
18. scanf("%s", exp);
19. l = strlen(exp);
20. exp2[0] = '\0';
21. i = 0;
22. while (exp[i] != '=') {
23. i++;
24. }
25. strncat(exp2, exp, i);
26. strrev(exp);
27. exp1[0] = '\0';
28. strncat(exp1, exp, l - (i + 1));
29. strrev(exp1);
30. printf("Three address code:\ntemp=%s\n%s=temp\n", exp1, exp2);
31. break;
32.
33. case 2:
34. printf("\nEnter the expression with arithmetic operator: ");
35. scanf("%s", ex);
36. strcpy(exp, ex);
37. l = strlen(exp);
38. exp1[0] = '\0';
39.
40. for (i = 0; i < l; i++) {
41. if (exp[i] == '+' || exp[i] == '-') {
42. if (exp[i + 2] == '/' || exp[i + 2] == '*') {
43. pm();
44. break;
45. } else {
46. plus();
47. break;
48. }
49. } else if (exp[i] == '/' || exp[i] == '*') {
50. div();
51. break;
52. }
53. }
54. break;
55.
56. case 3:
57. printf("\nEnter the expression with relational operator: ");
58. scanf("%s%s%s", &id1, &op, &id2);
59. if (((strcmp(op, "<") == 0) || (strcmp(op, ">") == 0) ||
60. (strcmp(op, "<=") == 0) || (strcmp(op, ">=") == 0) ||
61. (strcmp(op, "==") == 0) || (strcmp(op, "!=") == 0)) == 0)
62. printf("Expression is error");
63. else {
64. printf("\n%d\tif %s%s%s goto %d", addr, id1, op, id2, addr + 3);
65. addr++;
66. printf("\n%d\t T:=0", addr);
67. addr++;
68. printf("\n%d\t goto %d", addr, addr + 2);
69. addr++;
70. printf("\n%d\t T:=1", addr);
71. }
72. break;
73. case 4:
74. exit(0);
75. }
76. }
77. }
78. void pm() {
79. strrev(exp);
80. j = l - i - 1;
81. strncat(exp1, exp, j);
82. strrev(exp1);
83. printf("Three address code:\ntemp=%s\ntemp1=%c%ctemp\n", exp1, exp[j +
1],
84. exp[j]);
85. }
86. void div() {
87. strncat(exp1, exp, i + 2);
88. printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n", exp1, exp[i +
2],
89. exp[i + 3]);
90. }
91. void plus() {
92. strncat(exp1, exp, i + 2);
93. printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n", exp1, exp[i +
2],
94. exp[i + 3]);
95. }
Output:
1. Assignment
2. Arithmetic
3. Relational
4. Exit
Enter the choice:1
1. Assignment
2. Arithmetic
3. Relational
4. Exit
Enter the choice:2
1. Assignment
2. Arithmetic
3. Relational
4. Exit
Enter the choice:4
Experiment 14
Aim:
Write a C program for implementation of a Code Generation Algorithm of a given
expression/statement.
Program:
1. #include <stdio.h>
2. #include <string.h>
3. #include <ctype.h>
4.
5. typedef struct {
6. char var[10];
7. int alive;
8. } regist;
9. regist preg[10];
10.
11. void substring(char exp[], int st, int end) {
12. int i, j = 0;
13. char dup[10] = "";
14. for (i = st; i < end; i++)
15. dup[j++] = exp[i];
16. dup[j] = '0';
17. strcpy(exp, dup);
18. }
19.
20. int getregister(char var[]) {
21. int i;
22. for (i = 0; i < 10; i++) {
23. if (preg[i].alive == 0) {
24. strcpy(preg[i].var, var);
25. break;
26. }
27. }
28. return (i);
29. }
30.
31. void getvar(char exp[], char v[]) {
32. int i, j = 0;
33. char var[10] = "";
34. for (i = 0; exp[i] != '\0'; i++)
35. if (isalpha(exp[i]))
36. var[j++] = exp[i];
37. else
38. break;
39. strcpy(v, var);
40. }
41.
42. void main() {
43. char basic[10][10], var[10][10], fstr[10], op;
44. int i, j, k, reg, vc, flag = 0;
45.
46. printf("\nEnter the three address code:\n");
47. for (i = 0;; i++) {
48. gets(basic[i]);
49. if (strcmp(basic[i], "exit") == 0)
50. break;
51. }
52. printf("\nThe equivalent assembly code is:");
53. for (j = 0; j < i; j++) {
54. getvar(basic[j], var[vc++]);
55. strcpy(fstr, var[vc - 1]);
56. substring(basic[j], strlen(var[vc - 1]) + 1, strlen(basic[j]));
57. getvar(basic[j], var[vc++]);
58. reg = getregister(var[vc - 1]);
59. if (preg[reg].alive == 0) {
60. printf("\nMOV R%d,%s", reg, var[vc - 1]);
61. preg[reg].alive = 1;
62. }
63. op = basic[j][strlen(var[vc - 1])];
64. substring(basic[j], strlen(var[vc - 1]) + 1, strlen(basic[j]));
65. getvar(basic[j], var[vc++]);
66. switch (op) {
67. case '+':
68. printf("\nADD");
69. break;
70. case '-':
71. printf("\nSUB");
72. break;
73. case '*':
74. printf("\nMUL");
75. break;
76. case '/':
77. printf("\nDIV");
78. break;
79. }
80. flag = 1;
81. for (k = 0; k <= reg; k++) {
82. if (strcmp(preg[k].var, var[vc - 1]) == 0) {
83. printf("R%d, R%d", k, reg);
84. preg[k].alive = 0;
85. flag = 0;
86. break;
87. }
88. }
89. if (flag) {
90. printf(" %s,R%d", var[vc - 1], reg);
91. printf("\nMOV %s,R%d", fstr, reg);
92. }
93. strcpy(preg[reg].var, var[vc - 3]);
94. }
95. printf("\n");
96. }
Output:
Enter the three address code:
a=b+c
c=a*c
exit