SCHOOL OF INFORMATION TECHNOLOGY,
RGPV BHOPAL (M.P.)
COMPILER DESIGN LAB MANUAL
CD-502
COMPUTER SCIENCE
&
DATA SCIENCE
Submitted By
Vinay Jain
Enrollment No.: 0002CD221071
SEMESTER: Vth
School of Information Technology
Submitted To
Mr. Vipin Verma
Assistant Professor (SoIT, RGPV)
School of Information Technology
(University Teaching Department)
December - 2024
RAJIV GANDHI PROUDYOGIKI VISHWAVIDYALAYA BHOPAL (M.P.)
Compiler Design Lab Manual CD-502
INDEX
S. NO. PRACTICAL NAME PAGE NO.
1. Practice of LEX/YACC for compiler writing. 3
2. Write a program to check whether a string belongs to the grammar or not. 5
3. Write a program to find leading terminals. 8
4. Write a program to find trailing terminals. 11
5. Write a program to compute FIRST of non-terminals. 14
6. Write a program to compute FOLLOW of non-terminals. 17
7. Write a program to check whether a string is a keyword or not. 19
LIST OF FIGURES
FIGURE PAGE NO.
Figure 1.1 …………………………..............................................................................................3
Figure 1.2 …………………………..............................................................................................4
Figure 6.1 …………………………..............................................................................................18
SOIT RGPV BHOPAL 2
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 01
Aim: Practice of Lex/Yacc for compiler writing.
Theory: Lex is a tool/computer program which generates lexical analyzer. It is used with
YACC parser generator. It is written by Mike Lesk and Eric Schmidt and described in 1975.
Lexical Analyzer: Ist phase of compiler which converts source code in HLL to stream of
codes.
Figure 1.1
Lex compiler: It will transform the input patterns into a transition diagram and generates
code in a file called lex.yy.c
File.l: Lex source program file will always have (.l) extension.
lex.yy.c: C program/C language file.
a.out: object program/lexical analyzer
Program:
%{
#include<stdio.h>
%}
%%
SOIT RGPV BHOPAL 3
Compiler Design Lab Manual CD-502
"int" {printf("Valid Keyword\n");}
.* {printf("Lexical Error\n");}
%%
int main() {
printf("Enter input string: ");
yylex();
return 0;
}
int yywrap() {
return 1;
}
Output:
Figure 1.2
SOIT RGPV BHOPAL 4
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 02
Aim: Write a program to check whether a string belongs to the grammar.
Program:
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main() {
int a = 0, b = 0;
char str[20], tok[11];
clrscr();
printf("Input the expression: ");
gets(str);
while (str[a] != '\0') {
if (str[a] == '(' || str[a] == '{') {
tok[b] = '4';
b++;
} else if (str[a] == ')' || str[a] == '}') {
tok[b] = '5';
b++;
} else if (isdigit(str[a])) {
while (isdigit(str[a])) {
a++;
}
a--;
} else if (str[a] == '+') {
tok[b] = '2';
b++;
} else if (str[a] == '*') {
SOIT RGPV BHOPAL 5
Compiler Design Lab Manual CD-502
tok[b] = '3';
b++;
}
a++;
}
tok[b] = '\0';
puts(tok);
b = 0;
while (tok[b] != '\0') {
if (((tok[b] == '6') && (tok[b+1] == '2') && (tok[b+2] == '6')) ||
((tok[b] == '6') && (tok[b+1] == '3') && (tok[b+2] == '6')) ||
((tok[b] == '4') && (tok[b+1] == '6') && (tok[b+2] == '5'))) {
tok[b] = '6';
int c = b + 1;
while (tok[c] != '\0') {
tok[c] = tok[c + 2];
c++;
}
tok[c] = '\0';
puts(tok);
b = 0;
} else {
b++;
}
}
int d = strcmp(tok, "6");
if (d == 0) {
printf("It is in the grammar.\n");
} else {
printf("It is not in the grammar.\n");
}
getch();
SOIT RGPV BHOPAL 6
Compiler Design Lab Manual CD-502
Output:
Input the expression = (23+)
4625
4625
4625
4625
4625
It is not in the grammar.
Input the expression = (2+(3+4+5)
4624626 265
46246265265
4624626 265
4624626 265
4624626 265
462465265
462465265
462465265
462465265
4626265
4626265
46265
46265
465
6
6
It is in the grammar.
SOIT RGPV BHOPAL 7
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 03
Aim: Write a program to find the leading terminals of a grammar.
Program:
#include<conio.h>
#include<stdio.h>
char arr[18][3] = {
{'E', '+', 'F'}, {'E', '*', 'F'}, {'E', '(', 'F'}, {'E', ')', 'F'},
{'E', 'i', 'F'}, {'E', ' ', 'F'}, {'F', '+', 'F'}, {'F', '*', 'F'},
{'F', '(', 'F'}, {'F', ')', 'F'}, {'F', 'i', 'F'}, {'F', ' ', 'F'},
{'T', '+', 'F'}, {'T', '*', 'F'}, {'T', '(', 'F'}, {'T', ')', 'F'},
{'T', 'i', 'F'}, {'T', ' ', 'F'}
};
char prod[6] = "EETTFF";
char res[6][3] = {
{'E', '+', 'T'}, {'T', '\0', '\0'}, {'T', '*', 'F'}, {'F', '\0', '\0'},
{'(', 'E', ')'}, {'i', '\0', '\0'}
};
char stack[5][2];
int top = -1;
void install(char pro, char re) {
int i;
for (i = 0; i < 18; ++i) {
if (arr[i][0] == pro && arr[i][1] == re) {
arr[i][2] = 'T';
break;
}
SOIT RGPV BHOPAL 8
Compiler Design Lab Manual CD-502
}
++top;
stack[top][0] = pro;
stack[top][1] = re;
}
void main() {
int i = 0;
char pro, re, pri = ' ';
clrscr();
for (i = 0; i < 6; ++i) {
for (int j = 0; j < 3 && res[i][j] != '\0'; ++j) {
if (res[i][j] == '+' || res[i][j] == '*' || res[i][j] == '(' || res[i][j] == ')' || res[i][j] == 'i' ||
res[i][j] == ' ') {
install(prod[i], res[i][j]);
break;
}
}
}
while (top >= 0) {
pro = stack[top][0];
re = stack[top][1];
--top;
for (i = 0; i < 6; ++i) {
if (res[i][0] == pro && res[i][0] != prod[i]) {
install(prod[i], re);
}
}
}
for (i = 0; i < 18; ++i) {
printf("\n\t");
for (int j = 0; j < 3; ++j) {
SOIT RGPV BHOPAL 9
Compiler Design Lab Manual CD-502
printf("%c\t", arr[i][j]);
}
}
getch();
}
Output:
E + T
E * T
E ( T
E ) F
E i T
E $ F
F + F
F * F
F ( T
F ) F
F i T
F $ F
T + F
T * T
T ( T
T ) F
T i T
T $ F
SOIT RGPV BHOPAL 10
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 04
Aim: Write a program to find trailing terminals.
Program:
#include <conio.h>
#include <stdio.h>
char arr[18][3] = {
{'E', '+', 'F'}, {'E', '*', 'F'}, {'E', '(', 'F'}, {'E', ')', 'F'},
{'E', 'i', 'F'}, {'E', ' ', 'F'}, {'F', '+', 'F'}, {'F', '*', 'F'},
{'F', '(', 'F'}, {'F', ')', 'F'}, {'F', 'i', 'F'}, {'F', ' ', 'F'},
{'T', '+', 'F'}, {'T', '*', 'F'}, {'T', '(', 'F'}, {'T', ')', 'F'},
{'T', 'i', 'F'}, {'T', ' ', 'F'}};
char prod[6] = "EETTFF";
char res[6][3] = {
{'E', '+', 'T'}, {'T', '\0', '\0'},
{'T', '*', 'F'}, {'F', '\0', '\0'},
{'(', 'E', ')'}, {'i', '\0', '\0'}};
char stack[5][2];
int top = -1;
void install(char pro, char re) {
int i;
for (i = 0; i < 18; ++i) {
if (arr[i][0] == pro && arr[i][1] == re) {
arr[i][2] = 'T';
break;
}
}
++top;
stack[top][0] = pro;
stack[top][1] = re;
}
SOIT RGPV BHOPAL 11
Compiler Design Lab Manual CD-502
void main() {
int i = 0;
char pro, re, pri = ' ';
clrscr();
for (i = 0; i < 6; ++i) {
for (int j = 2; j >= 0; --j) {
if (res[i][j] == '+' || res[i][j] == '*' || res[i][j] == '(' || res[i][j] == ')' || res[i][j] == 'i' ||
res[i][j] == ' ') {
install(prod[i], res[i][j]);
break;
}
}
}
while (top >= 0) {
pro = stack[top][0];
re = stack[top][1];
--top;
for (i = 0; i < 6; ++i) {
for (int j = 2; j >= 0; --j) {
if (res[i][0] == pro && res[i][0] != prod[i]) {
install(prod[i], re);
break;
}
}
}
}
for (i = 0; i < 18; ++i) {
printf("\n\t");
for (int j = 0; j < 3; ++j) {
printf("%c\t", arr[i][j]);
}
}
SOIT RGPV BHOPAL 12
Compiler Design Lab Manual CD-502
getch();
clrscr();
printf("\n\n");
for (i = 0; i < 18; ++i) {
if (pri != arr[i][0]) {
pri = arr[i][0];
printf("\n\t%c -> ", pri);
}
if (arr[i][2] == 'T')
printf("%c ", arr[i][1]);
}
getch();
}
Output:
E + T
E * T
E ( F
E ) T
E i T
E $ F
F + F
F * F
F ( F
F ) T
F i T
F $ F
T + F
T * T
T ( F
T ) T
T i T
T $ F
E -> + *) i
F ->) i
T -> *) i
SOIT RGPV BHOPAL 13
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 05
Aim: Write a program to compute FIRST of non-terminals.
Program:
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main() {
char t[5], nt[10], p[5][10], first[5][5], temp;
int i, j, k = 0, f = 0, nont, not;
clrscr();
printf("\nEnter the no. of Non-terminal in the grammar:");
scanf("%d", &nont);
printf("\nEnter the Non-terminals in the grammar:\n");
for (i = 0; i < nont; i++) {
scanf(" %c", &nt[i]);
}
printf("\nEnter the no. of Terminals in the grammar: (Enter e for epsilon):");
scanf("%d", ¬);
printf("\nEnter the Terminals in the grammar:\n");
for (i = 0; i < not; i++) {
scanf(" %c", &t[i]);
}
for (i = 0; i < nont; i++) {
p[i][0] = nt[i];
first[i][0] = nt[i];
}
printf("\nEnter the productions:\n");
for (i = 0; i < nont; i++) {
printf("\nEnter the production for %c (End the production with ' '):", p[i][0]);
SOIT RGPV BHOPAL 14
Compiler Design Lab Manual CD-502
for (j = 1; (p[i][j - 1] != ' '); j++) {
scanf(" %c", &p[i][j]);
}
}
for (i = 0; i < nont; i++) {
printf("\nThe production for %c -> ", p[i][0]);
for (j = 1; p[i][j] != ' '; j++) {
printf("%c", p[i][j]);
}
}
for (i = 0; i < nont; i++) {
f = 0;
for (j = 1; p[i][j] != ' '; j++) {
for (k = 0; k < not; k++) {
if (f == 1)
break;
if (p[i][j] == t[k]) {
first[i][j] = t[k];
first[i][j + 1] = ' ';
f = 1;
break;
} else if (p[i][j] == nt[k]) {
first[i][j] = first[k][j];
if (first[i][j] == 'e')
continue;
first[i][j + 1] = ' ';
f = 1;
break;
}
}
}
}
SOIT RGPV BHOPAL 15
Compiler Design Lab Manual CD-502
for (i = 0; i < nont; i++) {
printf("\n\nThe first of %c -> %c", first[i][0], first[i][1]);
for (j = 1; first[i][j] != ' '; j++) {
printf("%c\t", first[i][j]);
}
}
getch();
}
Output:
Enter the no. of Non-terminals in the grammar: 3
Enter the Non-terminals in the grammar: E R T
Enter the no. of Terminals in the grammar: (Enter e for epsilon) 5
Enter the Terminals in the grammar: a s e * +
Enter the productions:
Enter the production for E (End the production with '$'): a + s$
Enter the production for R (End the production with '$'): e$
Enter the production for T (End the production with '$'): R s$
The production for E -> a + s
The production for R -> e
The production for T -> R s
The first of E -> a
The first of R -> e
The first of T -> e, s
SOIT RGPV BHOPAL 16
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 06
Aim: Write a program to find FOLLOW of non-terminals.
Program:
#include <stdio.h>
#include <string.h>
int n, m = 0, p, i = 0, j = 0;
char a[10][10], f[10];
void follow(char c);
void first(char c);
void follow(char c) {
if (a[0][0] == c) f[m++] = '$';
for (i = 0; i < n; i++) {
for (j = 2; a[i][j] != '\0'; j++) {
if (a[i][j] == c) {
if (a[i][j + 1] != '\0') first(a[i][j + 1]);
if (a[i][j + 1] == '\0' && c != a[i][0]) follow(a[i][0]);
}
}
}
}
void first(char c) {
int k;
if (!(isupper(c))) f[m++] = c;
for (k = 0; k < n; k++) {
if (a[k][0] == c) {
if (a[k][2] == '#') follow(a[k][0]);
else if (islower(a[k][2])) f[m++] = a[k][2];
else first(a[k][2]);
}
}
SOIT RGPV BHOPAL 17
Compiler Design Lab Manual CD-502
}
int main() {
int i, z;
char c, ch;
printf("Enter the number of productions: ");
scanf("%d", &n);
printf("Enter the productions:\n");
for (i = 0; i < n; i++) scanf("%s", a[i]);
do {
m = 0;
printf("Enter the element whose FOLLOW is to be found: ");
scanf(" %c", &c);
follow(c);
printf("FOLLOW(%c) = { ", c);
for (i = 0; i < m; i++) printf("%c ", f[i]);
printf("}\n");
printf("Continue (0/1)? ");
scanf("%d", &z);
} while (z == 1);
return 0;
}
Output:
Figure 6.1
SOIT RGPV BHOPAL 18
Compiler Design Lab Manual CD-502
EXPERIMENT NO. – 07
Aim: Write a program to check whether a string is a keyword or not.
Program:
#include <stdio.h>
#include <string.h>
void main() {
int flag = 0, i;
char keywords[5][10] = {"if", "else", "goto", "continue", "return"};
char input[10];
printf("\nEnter the string: ");
gets(input);
for (i = 0; i < 5; i++) {
if (strcmp(input, keywords[i]) == 0) {
flag = 1;
break;
}
}
if (flag == 0)
printf("\nIt is not a keyword.\n");
else
printf("\nIt is a keyword.\n");
}
Output:
Enter the string: return
It is a keyword.
Enter the string: hello
It is not a keyword.
SOIT RGPV BHOPAL 19