Академический Документы
Профессиональный Документы
Культура Документы
Laboratory – Manual
For Academic Session Jan-June 2019
COMPILER DESIGN
Batch :- 2016-2020
Year/Semester :- VI-semester(III-year)
INDEX
Serial No. Topic Date of Teacher’s
submission Remark
10 To study object-oriented
Compiler
EXPERIMENT NO. 1
Lex can perform simple transformations by itself but its main purpose is to
facilitate lexical analysis, the processing of character sequences such
as source code to produce symbol sequences called tokens for use as input
to other programs such as parsers. Lex can be used with a parser generator
to perform lexical analysis. It is easy, for example, to interface Lex and Yacc,
an open source program that generates code for the parser in
the C programming language.
Lex is proprietary but versions based on the original code are available as
open source. These include a streamlined version called Flex, an acronym
for "fast lexical analyzer generator".
Lexical analysis is the first phase of a compiler. It takes the modified source
code from language preprocessors that are written in the form of sentences.
The lexical analyzer breaks these syntaxes into a series of tokens, by
removing any whitespace or comments in the source code.
If the lexical analyzer finds a token invalid, it generates an error. The lexical
analyzer works closely with the syntax analyzer. It reads character streams
from the source code, checks for legal tokens, and passes the data to the
syntax analyzer when it demands.
declarations
%%
translation rules
%%
auxiliary functions
Auxiliary functions This section holds additional functions which are used in actions.
These functions are compiled separately and loaded with lexical analyzer.
EXPERIMENT NO. 2
#include<iostream>
#include<fstream>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
"do","double","else","enum","extern","float","for","goto",
"if","int","long","register","return","short","signed",
"sizeof","static","struct","switch","typedef","union",
"unsigned","void","volatile","while"};
int i, flag = 0;
int main(){
char ch, buffer[15], operators[] = "+-*/%=";
ifstream fin("program.txt");
int i,j=0;
if(!fin.is_open()){
cout<<"error while opening the file\n";
exit(0);
}
while(!fin.eof()){
ch = fin.get();
if(isalnum(ch)){
buffer[j++] = ch;
}
else if((ch == ' ' || ch == '\n') && (j != 0)){
buffer[j] = '\0';
j = 0;
if(isKeyword(buffer) == 1)
cout<<buffer<<" is keyword\n";
else
cout<<buffer<<" is indentifier\n";
}
fin.close();
return 0;
}
Output
EXPERIMENT NO. 4
#include<stdio.h>
#include<ctype.h>
#include<string.h>
void followfirst(char, int, int);
void follow(char c);
void findfirst(char, int, int);
int count, n = 0;
char calc_first[10][100];
char calc_follow[10][100];
int m = 0;
char production[10][10];
char f[10], first[10];
int k;
char ck;
int e;
int main(int argc, char **argv)
{ int jm = 0;
int km = 0;
int i, choice;
char c, ch;
count = 8;
strcpy(production[0], "E=TR");
strcpy(production[1], "R=+TR");
strcpy(production[2], "R=#");
strcpy(production[3], "T=FY");
strcpy(production[4], "Y=*FY");
strcpy(production[5], "Y=#");
strcpy(production[6], "F=(E)");
strcpy(production[7], "F=i");
int kay;
char done[count];
int ptr = -1;
for(k = 0; k < count; k++) {
for(kay = 0; kay < 100; kay++) {
calc_first[k][kay] = '!'; } }
int point1 = 0, point2, xxx;
for(k = 0; k < count; k++)
{ c = production[k][0];
point2 = 0;
xxx = 0;
for(kay = 0; kay <= ptr; kay++)
if(c == done[kay])
xxx = 1;
if (xxx == 1)
continue;
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
for(i = 0 + jm; i < n; i++) {
int lark = 0, chk = 0;
for(lark = 0; lark < point2; lark++) {
if (first[i] == calc_first[point1][lark])
{ chk = 1;
break; } }
if(chk == 0)
{ printf("%c, ", first[i]);
calc_first[point1][point2++] = first[i]; } }
printf("}\n");
jm = n;
point1++; }
printf("\n");
printf("-----------------------------------------------\n\n");
char donee[count];
ptr = -1;
for(k = 0; k < count; k++) {
for(kay = 0; kay < 100; kay++) {
calc_follow[k][kay] = '!';
}}
point1 = 0;
int land = 0;
for(e = 0; e < count; e++)
{ ck = production[e][0];
point2 = 0;
xxx = 0;
for(kay = 0; kay <= ptr; kay++)
if(ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
follow(ck);
ptr += 1;
donee[ptr] = ck;
printf(" Follow(%c) = { ", ck);
calc_follow[point1][point2++] = ck;
for(i = 0 + km; i < m; i++) {
int lark = 0, chk = 0;
for(lark = 0; lark < point2; lark++)
{if (f[i] == calc_follow[point1][lark])
{chk = 1;
break; } }
if(chk == 0)
{ printf("%c, ", f[i]);
calc_follow[point1][point2++] = f[i]; } }
printf(" }\n\n");
km = m;
point1++; } }
void follow(char c)
{ int i, j;
if(production[0][0] == c) {
f[m++] = '$';
}
for(i = 0; i < 10; i++)
{ for(j = 2;j < 10; j++)
{ if(production[i][j] == c)
{ if(production[i][j+1] != '\0')
{ followfirst(production[i][j+1], i, (j+2)); }
if(production[i][j+1]=='\0' && c!=production[i][0])
{ follow(production[i][0]);
}}}}}
void findfirst(char c, int q1, int q2)
{ int j;
if(!(isupper(c))) {
first[n++] = c;
}
for(j = 0; j < count; j++)
{
if(production[j][0] == c)
{ if(production[j][2] == '#')
{
if(production[q1][q2] == '\0')
first[n++] = '#';
else if(production[q1][q2] != '\0'
&& (q1 != 0 || q2 != 0)) {
findfirst(production[q1][q2], q1, (q2+1));
}
else
first[n++] = '#';
}
else if(!isupper(production[j][2]))
{first[n++] = production[j][2;}
else
{findfirst(production[j][2], j, 3); } } } }
void followfirst(char c, int c1, int c2)
{ int k;
if(!(isupper(c)))
f[m++] = c;
else
{
int i = 0, j = 1;
for(i = 0; i < count; i++)
{
if(calc_first[i][0] == c)
else
cout<<buffer<<" is indentifier\n";
}
fin.close();
return 0;
}
Output
EXPERIMENT NO. 5
#include<stdio.h>
#include<conio.h>
void main(){
char stack[20],ip[20],opt[10][10][1],ter[10];
int i,j,k,n,top=0,col,row;
clrscr();
for(i=0;i<10;i++)
{
stack[i]=NULL;
ip[i]=NULL;
for(j=0;j<10;j++)
{
opt[i][j][1]=NULL;
}}
printf("Enter the no.of terminals :\n");
scanf("%d",&n);
printf("\nEnter the terminals :\n");
scanf("%s",&ter);
printf("\nEnter the table values :\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("Enter the value for %c %c:",ter[i],ter[j]);
scanf("%s",opt[i][j]);
}
}
printf("\n**** OPERATOR PRECEDENCE TABLE ****\n");
for(i=0;i<n;i++)
{
printf("\t%c",ter[i]);
}
printf("\n");
for(i=0;i<n;i++){printf("\n%c",ter[i]);
for(j=0;j<n;j++){printf("\t%c",opt[i][j][0]);}}
stack[top]='$';
printf("\nEnter the input string:");
scanf("%s",ip);
i=0;
printf("\nSTACK\t\t\tINPUT STRING\t\t\tACTION\n");
printf("\n%s\t\t\t%s\t\t\t",stack,ip);
while(i<=strlen(ip))
{
for(k=0;k<n;k++)
{
if(stack[top]==ter[k])
col=k;
if(ip[i]==ter[k])
row=k;
}
if((stack[top]=='$')&&(ip[i]=='$')){
printf("String is accepted\n");
break;}
else if((opt[col][row][0]=='<') ||(opt[col][row][0]=='='))
{ stack[++top]=opt[col][row][0];
stack[++top]=ip[i];
printf("Shift %c",ip[i]);
i++;
}
else{
if(opt[col][row][0]=='>')
{
while(stack[top]!='<'){--top;}
top=top-1;
printf("Reduce");
}
else
{
printf("\nString is not accepted");
break;
}
}
printf("\n");
for(k=0;k<=top;k++)
{
printf("%c",stack[k]);
}
printf("\t\t\t");
for(k=i;k<strlen(ip);k++){
printf("%c",ip[k]);
}
printf("\t\t\t");
}
getch();
}
/*
output:
Enter the value for * *:>
Enter the value for * $:>
Enter the value for $ i:<
Enter the value for $ +:<
Enter the value for $ *:<
Enter the value for $ $:accept
$ i*i Shift i
$<i *i Reduce
$ *i Shift *
$<* i Shift i
$<*<i
String is not accepted
EXPERIMENT NO. 6
#include <stdio.h>
#include <conio.h>
char input[100];
char prod[100][100];
int pos=-1,l,st=-1;
char id,num;
void E();
void T();
void F();
void advance();
void Td();
void Ed();
void advance()
{
pos++;
if(pos<l)
{
if(input[pos]>='0'&& input[pos]<='9')
{
num=input[pos];
id='\0';
}
if((input[pos]>='a' || input[pos]>='A')&&(input[pos]<='z' || input[pos]<='Z'))
{id=input[pos];
num='\0';
}
}
}
void E()
{
strcpy(prod[++st],"E->TE'");
T();
Ed();
}
void Ed()
{
int p=1;
if(input[pos]=='+')
{
p=0;
strcpy(prod[++st],"E'->+TE'");
advance();
T();
Ed();
}
if(input[pos]=='-')
{ p=0;
strcpy(prod[++st],"E'->-TE'");
advance();
T();
Ed();
}
int kay;
char done[count];
int ptr = -1;
for(k = 0; k < count; k++) {
for(kay = 0; kay < 100; kay++) {
calc_first[k][kay] = '!'; } }
int point1 = 0, point2, xxx;
for(k = 0; k < count; k++)
{ c = production[k][0];
point2 = 0;
xxx = 0;
for(kay = 0; kay <= ptr; kay++)
if(c == done[kay])
xxx = 1;
if (xxx == 1)
continue;
findfirst(c, 0, 0);
ptr += 1;
done[ptr] = c;
printf("\n First(%c) = { ", c);
calc_first[point1][point2++] = c;
for(i = 0 + jm; i < n; i++) {
int lark = 0, chk = 0;
for(lark = 0; lark < point2; lark++) {
if (first[i] == calc_first[point1][lark])
{ chk = 1;
}
void F()
{
if(input[pos]==id) {
strcpy(prod[++st],"F->id");
advance(); }
if(input[pos]=='(')
{
strcpy(prod[++st],"F->(E)");
advance();
E();
if(input[pos]==')') {
//strcpy(prod[++st],"F->(E)");
advance(); }
}
if(input[pos]==num)
{
strcpy(prod[++st],"F->num");
advance();
}
}
int main()
{
int i;
printf("Enter Input String ");
scanf("%s",input);
l=strlen(input);
input[l]='$';
advance();
E();
if(pos==l)
{
printf("String Accepted\n");
for(i=0;i<=st;i++)
{
printf("%s\n",prod[i]);
}
}
else
{
printf("String rejected\n");
}
getch();
return 0;
}
OUTPUT:
EXPERIMENT NO. 7
Problem Statement
Let X = (Qx, ∑, δx, q0, Fx) be an NDFA which accepts the language L(X). We have to
design an equivalent DFA Y = (Qy, ∑, δy, q0, Fy) such that L(Y) = L(X). The following
procedure converts the NDFA to its equivalent DFA −
Algorithm
Input − An NDFA
Step 2 − Create a blank state table under possible input alphabets for the equivalent
DFA.
Step 3 − Mark the start state of the DFA by q0 (Same as the NDFA).
Step 4 − Find out the combination of States {Q0, Q1,... , Qn} for each possible input
alphabet.
Step 5 − Each time we generate a new DFA state under the input alphabet columns, we
have to apply step 4 again, otherwise go to step 6.
Step 6 − The states which contain any of the final states of the NDFA are the final states
of the equivalent DFA.
Example
Let us consider the NDFA shown in the figure below.
Q δ(q,0) δ(q,1)
A {a,b,c,d,e} {d,e}
B {c} {e}
C ∅ {b}
D {e} ∅
E ∅ ∅
Using the above algorithm, we find its equivalent DFA. The state table of the DFA is
shown in below.
Q δ(q,0) δ(q,1)
[d,e] [e] ∅
[e] ∅ ∅
[c, e] ∅ [b]
[c] ∅ [b]
#include<stdio.h>
#include<conio.h>
void main(){
char stack[20],ip[20],opt[10][10][1],ter[10];
int i,j,k,n,top=0,col,row;
clrscr();
for(i=0;i<10;i++)
{
stack[i]=NULL;
ip[i]=NULL;
for(j=0;j<10;j++)
{
opt[i][j][1]=NULL;
}}
printf("Enter the no.of terminals :\n");
scanf("%d",&n);
printf("\nEnter the terminals :\n");
scanf("%s",&ter);
printf("\nEnter the table values :\n");
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
printf("Enter the value for %c %c:",ter[i],ter[j]);
scanf("%s",opt[i][j]);
}
}
printf("\n**** OPERATOR PRECEDENCE TABLE ****\n");
for(i=0;i<n;i++)
{
printf("\t%c",ter[i]);
}
printf("\n");
for(i=0;i<n;i++){printf("\n%c",ter[i]);
for(j=0;j<n;j++){printf("\t%c",opt[i][j][0]);}}
stack[top]='$';
printf("\nEnter the input string:");
scanf("%s",ip);
i=0;
printf("\nSTACK\t\t\tINPUT STRING\t\t\tACTION\n");
printf("\n%s\t\t\t%s\t\t\t",stack,ip);
while(i<=strlen(ip))
{
for(k=0;k<n;k++)
{
if(stack[top]==ter[k])
col=k;
if(ip[i]==ter[k])
row=k;
}
if((stack[top]=='$')&&(ip[i]=='$')){
printf("String is accepted\n");
break;}
else if((opt[col][row][0]=='<') ||(opt[col][row][0]=='='))
q0, q3, q5 } }.
Step 2. To calculate P1, we will check whether sets of partition P0 can be partitioned or
not:
i) For set { q1, q2, q4 } :
δ ( q1, 0 ) = δ ( q2, 0 ) = q2 and δ ( q1, 1 ) = δ ( q2, 1 ) = q5, So q1 and q2 are not
distinguishable.
Similarly, δ ( q1, 0 ) = δ ( q4, 0 ) = q2 and δ ( q1, 1 ) = δ ( q4, 1 ) = q5, So q1 and q4 are
not distinguishable.
Since, q1 and q2 are not distinguishable and q1 and q4 are also not distinguishable, So
q2 and q4 are not distinguishable. So, { q1, q2, q4 } set will not be partitioned in P1.
ii) For set { q0, q3, q5 } :
δ ( q0, 0 ) = q3 and δ ( q3, 0 ) = q0
δ ( q0, 1) = q1 and δ( q3, 1 ) = q4
Moves of q0 and q3 on input symbol 0 are q3 and q0 respectively which are in same set
in partition P0. Similarly, Moves of q0 and q3 on input symbol 1 are q3 and q0 which are
in same set in partition P0. So, q0 and q3 are not distinguishable.
δ ( q0, 0 ) = q3 and δ ( q5, 0 ) = q5 and δ ( q0, 1 ) = q1 and δ ( q5, 1 ) = q5
Moves of q0 and q5 on input symbol 0 are q3 and q5 respectively which are in different
set in partition P0. So, q0 and q5 are distinguishable. So, set { q0, q3, q5 } will be
partitioned into { q0, q3 } and { q5 }. So,
P1 = { { q1, q2, q4 }, { q0, q3}, { q5 } }
To calculate P2, we will check whether sets of partition P1 can be partitioned or not:
iii)For set { q1, q2, q4 } :
δ ( q1, 0 ) = δ ( q2, 0 ) = q2 and δ ( q1, 1 ) = δ ( q2, 1 ) = q5, So q1 and q2 are not
distinguishable.
Similarly, δ ( q1, 0 ) = δ ( q4, 0 ) = q2 and δ ( q1, 1 ) = δ ( q4, 1 ) = q5, So q1 and q4 are
not distinguishable.
Since, q1 and q2 are not distinguishable and q1 and q4 are also not distinguishable, So
q2 and q4 are not distinguishable. So, { q1, q2, q4 } set will not be partitioned in P2.
}
/*
output:
Enter the value for * *:>
Enter the value for * $:>
Enter the value for $ i:<
Enter the value for $ +:<
Enter the value for $ *:<
Enter the value for $ $:accept
$ i*i Shift i
$<i *i Reduce
$ *i Shift *
$<* i Shift i
$<*<i
String is not accepted
EXPERIMENT NO. 9
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main() {
char string[50];
int flag,count=o;
clrscr();
printf("The grammar is: S->aS, S->Sb, S->ab\n");
printf("Enter the string to be checked:\n");
gets(string);
if(string[0]=='a') {
flag=0;
for (count=1;string[count-1]!='\0';count++) {
if(string[count]=='b') {
flag=1;
continue;
} else if((flag==1)&&(string[count]=='a')) {
printf("The string does not belong to the specified
grammar");
break;
} else if(string[count]=='a')
continue; else if(flag==1)&&(string[count]='\0')) {
printf("String accepted…..!!!!");
break;
} else {
printf("String not accepted");
}
}
void E()
{
strcpy(prod[++st],"E->TE'");
T();
Ed();
}
void Ed()
{
int p=1;
if(input[pos]=='+')
{
p=0;
strcpy(prod[++st],"E'->+TE'");
advance();
T();
Ed();
}
if(input[pos]=='-')
{ p=0;
strcpy(prod[++st],"E'->-TE'");
advance();
T();
Ed();
}
Q δ(q,0) δ(q,1)
A {a,b,c,d,e} {d,e}
B {c} {e}
C ∅ {b}
D {e} ∅
E ∅ ∅
Using the above algorithm, we find its equivalent DFA. The state table of the DFA is
shown in below.
Q δ(q,0) δ(q,1)
[d,e] [e] ∅
[e] ∅ ∅
[c, e] ∅ [b]
[c] ∅ [b]