Compiler Design 3170701 LabManual 2022
Compiler Design 3170701 LabManual 2022
(3170701)
Lab Manual
Practical-1: Implementation of Finite Automata and String Validation.
Related Theory:
Given DFA has following states. State 3 leads to the acceptance of the string, whereas
states 0, 1, 2 and 4 leads to the rejection of the string.
else if (dfa == 1)
state1(str[i]);
else if (dfa == 2)
state2(str[i]);
else if (dfa == 4)
state4(str[i]);
else
return 0;
}
if (dfa == 3)
return 1;
else
return 0;
}
// driver code
int main()
{
char str[] = "aaaaaabbbb";
if (isAccepted(str))
printf("ACCEPTED");
else
printf("NOT ACCEPTED");
return 0;
}
Output:
Related Theory:
Lex is a computer program that generates lexical analyzers ("scanners" or "lexers"). Lex
is commonly used with the yacc parser generator. Lex, originally written by Mike Lesk and Eric
Schmidt and described in 1975, is the standard lexical analyzer generator on many Unix
systems, and an equivalent tool is specified as part of the POSIX standard.
Lex reads an input stream specifying the lexical analyzer and writes source code which
implements the lexical analyzer in the C programming language. In addition to C, some old
versions of Lex could also generate a lexer in Ratfor.
Although originally distributed as proprietary software, some versions of Lex are now
open-source. Open-source versions of Lex, based on the original proprietary code, are now
distributed with open-source operating systems such as OpenSolaris and Plan 9 from Bell Labs.
One popular open-source version of Lex, called flex, or the "fast lexical analyzer", is not derived
from proprietary coding.
Function of Lex:
Firstly lexical analyzer creates a program lex.1 in the Lex language. Then Lex compiler
runs the lex.1 program and produces a C program lex.yy.c. Finally C compiler runs the lex.yy.c
program and produces an object program ‘a.out’. Here, ‘a.out’ is lexical analyzer that
transforms an input stream into a sequence of tokens.
A Lex program is separated into three sections by %% delimiters. The formal of Lex
source is as follows:
{ definitions }
%%
{ rules }
%%
{ user subroutines }
Input: words.l
/*lex program to count number of words*/
%{
#include<stdio.h>
#include<string.h>
int i = 0;
%}
/* Rules Section*/
%%
([a-zA-Z0-9])* {i++;} /* Rule for counting number of words*/
%%
int yywrap(void){}
int main()
{
return 0;
}
Output:
Input: countword.l
%{
#include<stdio.h>
#include<string.h>
%}
/* Rule Section */
/* Rule 1 compares the matched token with the word to
count and increments the count variableon successful
match */
/* Rule 2 matches everything other than string (consists of
albhabets only ) and do nothing */
%%
[a-zA-Z]+ { if(strcmp(yytext, word)==0)
count++; }
. ;
%%
int yywrap()
{
return 1;
}
printf("%d", count);
}
Compiler Design (3170701) 9
Input File: Input.txt
Output:
Input: cipher2.l
%%
[a-z] {char ch = yytext[0];ch += 3;
if (ch> 'z') ch -= ('z'+1- 'a');printf ("%c" ,ch );
}
[A-Z] { char ch = yytext[0] ;ch += 3;
if (ch> 'Z') ch -= ('Z'+1- 'A');
printf("%c",ch);
}
%%
Output:
Input:
/*Definition Section*/
%{
#include<stdio.h>
%}
/*Rule Section*/
%%
/*Regular expression for single line comment*/
\/\/(.*) {};
/*Regular expression for multi line comment*/
\/\*(.*\n)*.*\*\/ {};
%%
/*Auxiliary function*/
/*Driver function*/
int main()
{
yyin=fopen("input6.c","r");
yyout=fopen("out.c","w");
/*call the yylex function.*/
yylex();
return 0;
}
input.c
output.c
Input:roman.l
%{
#include<stdio.h>
#include<ctype.h>
%%
1 {fprintf(fr,"I");}
2|3|4 { z=atoi(yytext);
while(z!=0)
{
{fprintf(fr,"I");}z--;
}
}
5 {fprintf(fr,"V ");}
6|7|8 { a=atoi(yytext);
{fprintf(fr,"V ");}
while(z!=5)
{
{fprintf(fr,"I");}z--;
}
}
9 {fprintf(fr,"IX");}
10 {fprintf(fr,"X");}
. {fprintf(fr,yytext);}
Output:
Input.txt Output.txt
%{
#include<stdio.h>int
is_simple=1;
%}
%%
[ \t\n]+[aA][nN][dD][ \t\n]+ {is_simple=0;}
[ \t\n]+[bB][uU][tT][ \t\n]+ {is_simple=0;}
[ \t\n]+[oO][rR][ \t\n]+ {is_simple=0;}
main()
{
printf("Enter the sentence: ");
yylex();
if(is_simple==1)
printf("\n the given sentence is simple sentence\n");else
printf("\n the given sentence is compound sentence\n");
}
int yywrap()
{
return 1;
}
Output:
Input: extracttags.l
/* Declaration section*/
%{
%}
%%
"<"[^>]*> {printf("%s\n", yytext); } /* if anything enclosedin
these < > occur print
text*/
. ; // else do nothing
%%
int yywrap(){}
int main(int argc, char*argv[])
{
// Open tags.txt in read mode
extern FILE *yyin = fopen("tags.txt","r");
Output:
Input: Recursive-descent-parser.c
Example:
Grammar: E --> i E'
E' --> + i E' | e
____________________
int main()
{
// E is a start symbol.
E();
Output:
I+ie $
Pasring Sucessfully
Input: first_follow.c
int count, n = 0;
int kay;
char done[count];
int ptr = -1;
if (xxx == 1)
continue;
// Function call
findfirst(c, 0, 0);
Compiler Design (3170701) 21
ptr += 1;
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;
// Checking if Follow of ck
// has already been calculated
for(kay = 0; kay <= ptr; kay++)
if(ck == donee[kay])
xxx = 1;
if (xxx == 1)
continue;
land += 1;
// Function call
follow(ck);
ptr += 1;
Input: ThreeAddressCode.c
#include<stdio.h>
#include<string.h>
void pm();
void plus();
void div();
int i,ch,j,l,addr=100;
char ex[10], exp[10] ,exp1[10],exp2[10],id1[5],op[5],id2[5];
void main()
{
clrscr();
while(1)
{
printf("\n1.assignment\n2.arithmetic\n3.relational\n4.Exit\nEnter the choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("\nEnter the expression with assignment operator:");
scanf("%s",exp);
l=strlen(exp);
exp2[0]='\0';
i=0;
while(exp[i]!='=')
{
i++;
}
strncat(exp2,exp,i);
strrev(exp);
exp1[0]='\0';
strncat(exp1,exp,l-(i+1));
strrev(exp1);
printf("Three address code:\ntemp=%s\n%s=temp\n",exp1,exp2);
break;
case 2:
printf("\nEnter the expression with arithmetic operator:");
scanf("%s",ex);
strcpy(exp,ex);
l=strlen(exp);
exp1[0]='\0';
Compiler Design (3170701) 28
for(i=0;i<l;i++)
{
if(exp[i]=='+'||exp[i]=='-')
{
if(exp[i+2]=='/'||exp[i+2]=='*')
{
pm();
break;
}
else
{
plus();
break;
}
}
else if(exp[i]=='/'||exp[i]=='*')
{
div();
break;
}
}
break;
case 3:
printf("Enter the expression with relational operator");
scanf("%s%s%s",&id1,&op,&id2);
if(((strcmp(op,"<")==0)||(strcmp(op,">")==0)||(strcmp(op,"<=")==0)||(strcmp(op,">=")==0)||(strcmp(op,
"==")==0)||(strcmp(op,"!=")==0))==0)
printf("Expression is error");
else
{
printf("\n%d\tif %s%s%s goto %d",addr,id1,op,id2,addr+3);
addr++;
printf("\n%d\t T:=0",addr);
addr++;
printf("\n%d\t goto %d",addr,addr+2);
addr++;
printf("\n%d\t T:=1",addr);
}
break;
case 4:
exit(0);
}
}
Compiler Design (3170701) 29
}
void pm()
{
strrev(exp);
j=l-i-1;
strncat(exp1,exp,j);
strrev(exp1);
printf("Three address code:\ntemp=%s\ntemp1=%c%ctemp\n",exp1,exp[j+1],exp[j]);
}
void div()
{
strncat(exp1,exp,i+2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
void plus()
{
strncat(exp1,exp,i+2);
printf("Three address code:\ntemp=%s\ntemp1=temp%c%c\n",exp1,exp[i+2],exp[i+3]);
}
OUTPUT :
1. assignment
2. arithmetic
3. relational
4. Exit
Enter the choice:1
Enter the expression with assignment operator:
a=b
Three address code:
temp=b
a=temp
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a+b-c
Three address code:
temp=a+b
temp1=temp-c
1.assignment
Compiler Design (3170701) 30
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a-b/c
Three address code:
temp=b/c
temp1=a-temp
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:
a*b-c
Three address code:
temp=a*b
temp1=temp-c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:2
Enter the expression with arithmetic operator:a/b*c
Three address code:
temp=a/b
temp1=temp*c
1.assignment
2.arithmetic
3.relational
4.Exit
Enter the choice:3
Enter the expression with relational operator
a
<=
b
Input: InorderSuccessorPredecessor.java
// BST Node
struct Node
{
int key;
struct Node *left, *right;
};
if (suc != NULL)
cout << "Successor is " << suc->key;
else
cout << "No Successor";
return 0;
}
Output:
Predecessor is 60
Successor is 70
Related Theory:
Input File:
The definition part includes information about the tokens used in the
syntax definition:
Input File:
#include "lex.yy.c"
.y
Output Files:
Calculator Program:
/* Rule Section */
%%
[0-9]+ {
yylval=atoi(yytext);return
NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];
%token NUMBER
/* Rule Section */
%%
ArithmeticExpression: E{
printf("\nResult=%d\n", $$);return 0;
};
E:E'+'E {$$=$1+$3;}
|E'-'E {$$=$1-$3;}
|E'*'E {$$=$1*$3;}
|E'/'E {$$=$1/$3;}
|E'%'E {$$=$1%$3;}
|'('E')' {$$=$2;}
| NUMBER {$$=$1;}
%%
yyparse(); if(flag==0)
printf("\nEntered arithmetic expression is Valid\n\n");
}
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");flag=1;
}
Output:
Input:
#include<stdio.
h>
#include<ctype
.h>
#include<string
.h>
int count,n=0;
char
calc_first[10][100];
char
calc_follow[10][100];
int m=0;
char production[10][10],
first[10]; char f[10];
int k;
char
ck; int
e;
")
printf("\n");
;
}
int
j;
printf("\n\nPlease enter the desired INPUT
STRING = "); char input[100];
scanf("%s%c",input,&ch);
printf("\n\t\t\t\t\t=================================================================
======
====\n");
printf("\t\t\t\t\t\tStack\t\t\tInput\t\t\tAction");
printf("\n\t\t\t\t\t=================================================================
======
====\n");
int i_ptr = 0,s_ptr
= 1; char
stack[100];
stack[0] = '$';
stack[1] =
table[0][0];
while(s_ptr != -1){
printf("\t\t\t\t\t\t
"); int vamp = 0;
for(vamp=0;vamp<=s_ptr;vamp++){
printf("%c",stack[vamp]);
}
Compiler Design (3170701) 54
printf("\t\t\t
"); vamp =
i_ptr;
while(input[vamp] != '\0'){
printf("%c",input[vamp]);
vamp++;
}
printf("\t\t\t");
char her =
input[i_ptr]; char
him = stack[s_ptr];
s_ptr--;
if(!isupper(him)){
if(her == him){
}
}
else
{
for(i=0;i<sid;i++){
if(ter[i] == her)
break;
}
char produ[100];
for(j=0;j<land;j++){
if(him == table[j][0]){
if (table[j][i+1] == '#'){
printf("%c=#\n",table[j]
[0]); produ[0] = '#';
produ[1] = '\0';
}
else if(table[j][i+1] != '!'){
int mum =
(int)(table[j][i+1]); mum -=
65;
strcpy(produ,production[m
um]); printf("%s\n",produ);
}
else
{ printf("\nString Not Accepted by LL(1) Parser
!!\n"); exit(0);
}
}
}
int le =
strlen(produ); le =
le - 1;
if(le == 0){
continue;
Compiler Design (3170701) 56
}
for(j=le;j>=2;j--){
s_ptr++;
stack[s_ptr] = produ[j];
}
}
}
printf("\n\t\t\t===================================================================
=======
=============================================\n");
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!=productio
n[i][0]){ follow(production[i][0]);
}
}
}
}
}
}
else if(!isupper(production[j][2])){
first[n++]=production[j][2];
}
else
{ findfirst(production[j][2], j, 3);
}
}
}
}
Input: lalr.c
#include<stdio.
h>
#include<conio
.h>
#include<stdlib
.h>
#include<string
.h>
struct action
{
char row[6][5];
};
const struct action A[12]={
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","emp","acc"},
{"emp","rc","sh","emp","rc","rc"},
{"emp","re","re","emp","re","re"},
Compiler Design (3170701) 64
{"sf","emp","emp","se","emp","emp"},
{"emp","rg","rg","emp","rg","rg"},
{"sf","emp","emp","se","emp","emp"},
{"sf","emp","emp","se","emp","emp"},
{"emp","sg","emp","emp","sl","emp"},
{"emp","rb","sh","emp","rb","rb"},
{"emp","rb","rd","emp","rd","rd"},
{"emp","rf","rf","emp","rf","rf"}
};
struct gotol
{
char r[3][4];
};
char ter[6]={'i','+','*',')','(','$'};
char nter[3]={'E','T','F'};
char
states[12]={'a','b','c','d','e','f','g','h','m','j','k','
l'}; char stack[100];
int top=-1;
char
temp[10];
struct grammar
{
char left;
char
right[5];
};
void main()
{
Compiler Design (3170701) 66
char
inp[80],x,p,dl[80],y,bl='a';
int i=0,j,k,l,n,m,c,len;
printf(" Enter the
input :");
scanf("%s",inp);
len=strlen(inp);
inp[len]='$';
inp[len+1]='\0';
do
{
x=inp[i];
p=stacktop(sta
ck);
isproduct(x,p);
if(strcmp(temp,"emp")
==0) error();
if(strcmp(temp,"acc")=
=0) break;
else
{
if(temp[0]=='s')
{
push(stack,&top,inp[i]
);
push(stack,&top,temp
[1]); i++;
}
else
{
if(temp[0]=='r')
{
j=isstate(temp[1]);
strcpy(temp,rl[j-
2].right); dl[0]=rl[j-
2].left;
dl[1]='\0';
n=strlen(temp);
for(k=0;k<2*n;k
for(m=0;dl[m]!='\0';m++)
push(stack,&top,dl[m]);
l=top;
y=stack[l-
1];
isreduce(y,dl[0]);
for(m=0;temp[m]!='\0';m++)
printt(stack,&top,inp,i);
}while(inp[i]!='\0');
if(strcmp(temp,"acc")==
0)
printf(" \n accept the input ");
else
printf(" \n do not accept the
if(*sp==100)
printf(" stack is
full "); else
{
*sp=*sp+
1;
s[*sp]=ite
m;
}
}
return i;
Compiler Design (3170701) 70
}
k=ister(x)
;
l=isstate(
p);
strcpy(temp,A[l-1].row[k-1]);
int ister(char x)
{
int i;
for(i=0;i<6;i
++)
if(x==ter[i
])
return i+1;
return 0;
}
int isnter(char x)
{
int i;
for(i=0;i<3;i
++)
if(x==nter[
i]) return
i+1;
return 0;
}
int isstate(char p)
{
int i;
for(i=0;i<12;i+
+)
if(p==states
[i])
return i+1;
return 0;
}
Compiler Design (3170701) 72
void error()
{
printf(" error in the
input "); exit(0);
}
char
item;
if(*sp==-
1)
printf(" stack is
empty "); else
{
item=s[*sp];
*sp=*sp-1;
}
return item;
int r;
printf("\n
");
for(r=0;r<=*p;r
++) rep(t,r);
printf("\t\t\t");
for(r=i;inp[r]!='\0';r++)
printf("%c",inp[r]);
Compiler Design (3170701) 74
}
char
c;
c=t[r]
;
switch(c)
case 'a':
printf("0");
break;
case 'b':
printf("1");
break;
case 'c':
printf("2");
break;
case 'd':
printf("3");
break;
case 'e':
printf("4");
break;
case 'f':
printf("5");
break;
case 'g':
printf("6");
break;
case 'h':
printf("7");
break;
case 'm':
printf("8");
break;
case 'j':
printf("9");
break;
Compiler Design (3170701) 76
case 'k':
printf("10");
break;
case 'l':
printf("11");
break;
default
:printf("%c",t[r]);
break;
Input: OperatorPrecedence.c
#include<stdio.
h>
#include<string
.h>
#include<stdlib
.h>
char
*input; int
i=0;
char lasthandle[6],stack[50],handles[][5]={")E(","E*E","E+E","i","E^E"};
//(E) becomes )E( when pushed to stack
int top=0,l;
char prec[9][9]={
/*input*/
/*stack + - * / ^ i ( ) $ */
/* + */ '>', '>','<','<','<','<','<','>','>',
/* - */ '>', '>','<','<','<','<','<','>','>',
/* * */ '>', '>','>','>','<','<','<','>','>',
/* / */ '>', '>','>','>','<','<','<','>','>',
/* ^ */ '>', '>','>','>','<','<','<','>','>',
/* i */ '>', '>','>','>','>','e','e','>','>',
/* ( */ '<', '<','<','<','<','<','<','>','e',
/* ) */ '>', '>','>','>','>','e','e','>','>',
/* $ */ '<', '<','<','<','<','<','<','<','>',
};
int getindex(char c)
{
switch(c)
{
case '+':return 0;
case '-':return 1;
case '*':return 2;
Compiler Design (3170701) 79
case '/':return 3;
case '^':return 4;
case 'i':return 5;
case '(':return 6;
case ')':return 7;
case '$':return 8;
}
}
int reduce()
{
int i,len,found,t;
for(i=0;i<5;i++)//selecting
handles
{
len=strlen(handles[i]);
if(stack[top]==handles[i][0]&&top+1>=len)
{
found=1;
for(t=0;t<len;t
++)
{
if(stack[top-t]!=handles[i][t])
{
found=
0;
break;
}
}
if(found==1)
{
stack[top-
t+1]='E';
top=top-t+1;
strcpy(lasthandle,handles[i]);
stack[top+1]='\0';
return 1;//successful reduction
}
}
}
Compiler Design (3170701) 81
return 0;
}
void dispstack()
{
int j;
for(j=0;j<=top;j
++)
printf("%c",stack[j]);
}
void main()
{
int j;
input=(char*)malloc(50*sizeof(
char)); printf("\nEnter the
string\n"); scanf("%s",input);
input=strcat(input,"$");
l=strlen(input);
strcpy(stack,"$");
printf("\nSTACK\tINPUT\tACTION");
while(i<=l)
{
shift();
printf("\n");
dispstack();
printf("\t");
dispinput();
printf("\tShif
t");
if(prec[getindex(stack[top])][getindex(input[i])]=='>')
{
while(reduce())
{
printf("\n
");
dispstack
();
printf("\t
");
dispinput
();
Compiler Design (3170701) 83
printf("\tReduced: E->%s",lasthandle);
}
}
}
if(strcmp(stack,"$E$")==
0)
printf("\nAccepted;");
else
printf("\nNot Accepted;");
}