Compiler Design Lab File Blank
Compiler Design Lab File Blank
10
11
12
13
14
15
16
EXPERIMENT 1
Implementation of Lexical Analyzer
Aim: Write a program in C/C++ to implement a lexical analyzer.
Algorithm:
1. Start
2. Get the input expression from the user. 3. Store the keywords and operators.
5. ASCII Range TOKEN TYPE 97-122 Keyword else identifier 48-57 Constant else operator
Greater than 12 Symbol
Program (lexi.c):
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <string.h>
using namespace std;
int main()
{
char key[11][10] = {"for", "while", "do", "then", "else", "break", "switch", "case", "if",
"continue "};
char oper[13] = {'+', '-', '*', '/', '%', '&', '<', '>', '=', ';', ':', '!'};
char a[20], b[20], c[20];
int i, j, l, m, k, flag;
printf("\n Enter the expression: ");
gets(a);
i = 0;
while (a[i])
{
flag = 0;
j = 0;
l = 0;
b[0] = '\0';
if ((toascii(a[i] >= 97)) && (toascii(a[i] <= 122)))
{
if ((toascii(a[i + 1] >= 97)) && (toascii(a[i + 1] <= 122)))
{
while ((toascii(a[i] >= 97)) && (toascii(a[i] <= 122)))
{
1
b[j] = a[i];
j++;
i++;
}
b[j] = '\0';
}
else
{
b[j] = a[i];
i++;
b[j + 1] = '\0';
}
for (k = 0; k <= 9; k++)
{
if (strcmp(b, key[k]) == 0)
{
flag = 1;
break;
}
}
if (flag == 1)
printf("\n %s is the keyword", b);
else
printf("\n %s is the identifier", b);
}
else if ((toascii(a[i] >= 48)) && (toascii(a[i] <= 57)))
{
if ((toascii(a[i + 1] >= 48)) && (toascii(a[i + 1] <= 57)))
{
while ((toascii(a[i] >= 48)) && (toascii(a[i] <= 57)))
{
c[l] = a[i];
l++;
i++;
}
}
else
{
c[l] = a[i];
i++;
l++;
}
c[l] = '\0';
printf("\n %s is the constant", c);
}
else
2
{
for (m = 0; m < 13; m++)
{
if (a[i] == oper[m])
{
printf("\n %c is the operator", a[i]);
break;
}
}
if (m >= 13)
printf("\n %c is the symbol", a[i]);
i++;
}
}
return 0;
}
OUTPUT:
3
EXPERIMENT -2
Regular Expression to NFA
Aim: To convert the given Regular expression to NFA by using JFLAP.
1. a*
2. (a+b)
4
3. (a+b)*
4. a*(a+b)
5
5. a*b*
6. ab*b
6
EXPERIMENT 3
Regular Expression to NFA to DFA
Aim: To convert the given Regular expression to DFA by using JFLAP.
OUTPUT: -
DFA for the given expression is:
Algorithm:
Procedure First
1. Input the number of production N.
2. Input all the production rule PArray
3. Repeat steps a, b, c until process all input production rule i.e. PArray[N]
a. If Xi ≠ Xi+1 then
i. Print Result array of Xi which contain FIRST(Xi)
b. If first element of Xi of PArray is Terminal or ε Then
i. Add Result = Result U first element
c. If first element of Xi of PArray is Non-Terminal Then
i. searchFirst(i, PArray, N)
4. End Loop
5. If N (last production) then
a. Print Result array of Xi which contain FIRST(Xi)
6. End
Procedure searchFirst(i, PArray, N)
1. Repeat steps Loop j=i+1 to N
a. If first element of Xj of PArray is Non-Terminal Then
i. searchFirst(j, of PArray, N)
b. If first element of Xj of PArray is Terminal or ε Then
i. Add Result = Result U first element
ii. Flag=0
2. End Loop
3. If Flag = 0 Then
a. Print Result array of Xj which contain FIRST(Xj)
4. End
Program:
#include <iostream>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
using namespace std;
void searchFirst(int n, int i, char pl[], char r[], char result[], int k)
{
int j, flag;
8
for (j = i + 1; j < n; j++)
{
if (r[i] == pl[j])
{
if (isupper(r[j]))
{
searchFirst(n, j, pl, r, result, k);
}
if (islower(r[j]) || r[j] == '+' || r[j] == '*' || r[j] == ')' || r[j] == '(')
{
result[k++] = r[j];
result[k++] = ',';
flag = 0;
}
}
}
if (flag == 0)
{
for (j = 0; j < k - 1; j++)
{
}
cout << result[j];
}
}
int main()
{
char pr[10][10], pl[10], r[10], prev, result[10];
int i, n, k, j;
cout << "\nHow many production rule : ";
cin >> n;
if (n == 0)
exit(0);
for (i = 0; i < n; i++)
{
cout << "\nInput left part of production rules : ";
cin >> pl[i];
cout << "\nInput right part of production rules : ";
cin >> pr[i];
r[i] = pr[i][0];
}
cout << "\nProduction Rules are : \n";
for (i = 0; i < n; i++)
{
cout << pl[i] << "->" << pr[i] << "\n"; //<<";"<<r[i]<<"\n";
}
cout << "\n----O U T P U T---\n\n";
9
prev = pl[0];
k = 0;
for (i = 0; i < n; i++)
{
if (prev != pl[i])
{
cout << "\nFIRST(" << prev << ")={";
for (j = 0; j < k - 1; j++)
cout << result[j];
cout << "}";
k = 0;
prev = pl[i];
// cout<<"\n3";
}
if (prev == pl[i])
{
if (islower(r[i]) || r[i] == '+' || r[i] == '*' || r[i] == ')' || r[i] == '(')
{
result[k++] = r[i];
result[k++] = ',';
}
if (isupper(r[i]))
{
cout << "\nFIRST(" << prev << ")={";
searchFirst(n, i, pl, r, result, k);
cout << "}";
k = 0;
prev = pl[i + 1];
}
}
}
if (i == n)
{
cout << "\nFIRST(" << prev << ")={";
for (j = 0; j < k - 1; j++)
cout << result[j];
cout << "}";
k = 0;
prev = pl[i];
}
return 0;
}
10
OUTPUT: -
11
EXPERIMENT 5
Computation of FOLLOW in a grammar
Aim: Write a program in C/C++ to find a FOLLOW set from a given set of
production rule.
Algorithm:
1. Declare the variables.
2. Enter the production rules for the grammar.
3. Calculate the FOLLOW set for each element call the user defined
function follow().
4. If x->aBb
a. If x is start symbol then FOLLOW(x)={$}.
b. If b is NULL then FOLLOW(B)=FOLLOW(x).
c. If b is not NULL then FOLLOW(B)=FIRST(b).
END.
Program:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
using namespace std;
int n, m = 0, p, i = 0, j = 0;
char a[10][10], f[10];
void follow(char c);
void first(char c);
int main()
{
int i, z;
char c, ch;
printf("Enter the no.of productions:");
scanf("%d", &n);
printf("Enter the productions(epsilon=$):\n");
for (i = 0; i < n; i++)
scanf("%s%c", a[i], &ch);
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++)
12
printf("%c ", f[i]);
printf(" }\n");
printf("Do you want to continue(0/1)?");
scanf("%d%c", &z, &ch);
} while (z == 1);
}
void follow(char c)
{
if (a[0][0] == c)
f[m++] = '$';
for (i = 0; i < n; i++)
{
for (j = 2; j < strlen(a[i]); 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[i][0]);
else if (islower(a[k][2]))
f[m++] = a[k][2];
else
first(a[k][2]);
}
}
}
13
OUTPUT: -
14
EXPERIMENT 6
Computation of Predictive Parsing
Aim: Write a program in c for construction of predictive parser table.
Program:
#include <stdio.h>
#include <conio.h>
#include <string.h>
using namespace std;
char prol[7][10] = {"S", "A", "A", "B", "B", "C", "C"};
char pror[7][10] = {"A", "Bb", "Cd", "aB", "@", "Cc", "@"};
char prod[7][10] = {"S->A", "A->Bb", "A->Cd", "B->aB", "B->@", "C->Cc", "C-> @"};
char first[7][10] = {"abcd", "ab", "cd", "a@", "@", "c@", "@"};
char follow[7][10] = {"$", "$", "$", "a$", "b$", "c$", "d$"};
char table[5][6][10];
int numr(char c)
{
switch (c)
{
case 'S':
return 0;
case 'A':
return 1;
case 'B':
return 2;
case 'C':
return 3;
case 'a':
return 0;
case 'b':
return 1;
case 'c':
return 2;
case 'd':
return 3;
case '$':
return 4;
}
return (2);
}
int main()
{
int i, j, k;
for (i = 0; i < 5; i++)
15
for (j = 0; j < 6; j++)
strcpy(table[i][j], " ");
printf("\nThe following is the predictive parsing table for the following grammar:\n");
OUTPUT:
17
EXPERIMENT 7
Computation of Shift Reduce Parsing
Aim: Write a program in C/C++ to implement the shift reduce parsing.
Algorithm:
1. Start the Process.
2. Symbols from the input are shifted onto stack until a handle appears on
top of the stack.
3. The Symbols that are the handle on top of the stack are then replaces by
the left-hand side of the production (reduced).
4. If this result in another handle on top of the stack, then another
reduction is done, otherwise we go back to shifting.
5. This combination of shifting input symbols onto the stack and reducing
productions when handles appear on the top of the stack continues until
all of the input is consumed and the goal symbol is the only thing on the
stack - the input is then accepted.
6. If we reach the end of the input and cannot reduce the stack to the goal
symbol, the input is rejected.
7. Stop the process.
Program (srp.cpp):
#include <stdio.h>
#include <string.h>
int k = 0, z = 0, i = 0, j = 0, c = 0;
char a[16], ac[20], stk[15], act[10];
void check();
int main()
{
puts("GRAMMAR is \n E->E+E \n E->E*E \n E->(E) \n E->id");
puts("Enter input string ");
gets(a);
c = strlen(a);
strcpy(act, "SHIFT->");
puts("STACK \t INPUT \tCOMMENT");
// puts("$ \t");
// puts(a);
printf("$ \t%s$\n", a);
for (k = 0, i = 0; j < c; k++, i++, j++)
{
if (a[j] == 'i' && a[j + 1] == 'd')
{
stk[i] = a[j];
stk[i + 1] = a[j + 1];
18
stk[i + 2] = '\0';
a[j] = ' ';
a[j + 1] = ' ';
// printf("$ \t%s$\n",a);
printf("\n$%s\t%s$\t%sid", stk, a, act);
check();
}
else
{
stk[i] = a[j];
stk[i + 1] = '\0';
a[j] = ' ';
printf("\n$%s\t%s$\t%ssymbols", stk, a, act);
check();
}
}
}
void check()
{
strcpy(ac, "REDUCE TO E");
for (z = 0; z < c; z++)
if (stk[z] == 'i' && stk[z + 1] == 'd')
{
stk[z] = 'E';
stk[z + 1] = '\0';
printf("\n$%s\t%s$\t%s", stk, a, ac);
j++;
}
for (z = 0; z < c; z++)
if (stk[z] == 'E' && stk[z + 1] == '+' && stk[z + 2] == 'E')
{
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 2] = '\0';
printf("\n$%s\t%s$\t%s", stk, a, ac);
i = i - 2;
}
for (z = 0; z < c; z++)
if (stk[z] == 'E' && stk[z + 1] == '*' && stk[z + 2] == 'E')
{
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 1] = '\0';
printf("\n$%s\t%s$\t%s", stk, a, ac);
i = i - 2;
}
19
for (z = 0; z < c; z++)
if (stk[z] == '(' && stk[z + 1] == 'E' && stk[z + 2] == ')')
{
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 1] = '\0';
printf("\n$%s\t%s$\t%s", stk, a, ac);
i = i - 2;
}
}
OUTPUT:
20