CD Lab
CD Lab
PRACTICAL FILE
COMPILER DESIGN LAB
(KCS-552)
SESSION: 2022-23
S.
Name of Experiment Date Sign.
No.
1 WAP in c to draw DFA which starts and ends with 01.
Implementation:
Code:
#include <stdio.h>
#define MAX_LEN 1024
int main ()
{
char ch;
int char_count = 0, word_count = 0, line_count = 0;
int in_word = 0;
char file_name[MAX_LEN];
FILE *fp;
printf ("Enter a file name: ");
scanf ("%s", file_name);
fp = fopen (file_name, "r");
if (fp == NULL)
{
printf("Could not open the file %s\n", file_name);
return 1;
}
while ((ch = fgetc (fp)) != EOF)
{
char_count++;
if (ch == ' ' || ch == '\t' || ch == '\0' || ch == '\n')
{
if (in_word)
{
in_word = 0;
word_count++;
}
if (ch = '\0' || ch == '\n') line_count++;
}
else
{
in_word = 1;
}
}
printf("In the file %s:\n", file_name);
printf("Number of characters: %d.\n", char_count);
printf("Number of words: %d.\n", word_count);
printf("Number of lines: %d.\n", line_count);
return 0;
}
Output:
Result:
We have successfully implemented the program in c that counts the number of
characters, words, spaces, end of lines in a given input file.
PROGRAM – 4
Objective:
Write a program to find ε – closure of all states of any given NFA with ε
transition.
Implementation:
Code:
#include<stdio.h>
#include<string.h>
char result[20][20],copy[3],states[20][20];
strcpy(result[i],a);
void display(int n)
int k=0;
while(k < n)
printf(" %s",result[k]);
k++;
}
printf(" } nnn");
int main()
FILE *INPUT;
INPUT=fopen("input.dat","r");
char state[3];
int end,i=0,n,k=0;
char state1[3],input[3],state2[3];
scanf("%d",&n);
for(k=0;k<3;k++)
scanf("%s",states[k]);
for( k=0;k<n;k++)
i=0;
strcpy(state,states[k]);
strcpy(copy,state);
add_state(state,i++);
while(1)
end = fscanf(INPUT,"%s%s%s",state1,input,state2);
if (end == EOF )
break;
if( strcmp(state,state1) == 0 )
if( strcmp(input,"e") == 0 )
add_state(state2,i++);
strcpy(state, state2);
display(i);
rewind(INPUT);
}
return 0;
}
Output:
Result:
We have successfully implemented the program that find ε – closure of all states
in any given NFA with ε transition.
PROGRAM – 5
Objective:
Implementation of Lex analyser using Lex tools.
Introduction:
Lex is officially known as a “Lexical Analysers” .Its main job is to break up an input
stream into more into meaningful units, or tokens. For example, consider
breaking a text file up into individual words. More pragmatically, Lex is a tool for
automatically generating a lexer (also known as scanner) starting from a lex
specification.
Implementation:
Code:
int COMMENT=0;
int cnt=0;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* { printf("\n%s is a PREPROCESSOR DIRECTIVE",yytext);}
int |
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const |
typedef |
return |
else |
goto {printf("\n\t%s is a KEYWORD",yytext);}
"/*" {COMMENT = 1;}
"*/" {COMMENT = 0; cnt++;}
{identifier}\( {if(!COMMENT)printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {if(!COMMENT) printf("\n BLOCK BEGINS");}
\} {if(!COMMENT) printf("\n BLOCK ENDS");}
{identifier}(\[[0-9]*\])? {if(!COMMENT) printf("\n %s IDENTIFIER",yytext);}
\".*\" {if(!COMMENT) printf("\n\t%s is a STRING",yytext);}
[0-9]+ {if(!COMMENT) printf("\n\t%s is a NUMBER",yytext);}
\)(\;)? {if(!COMMENT) printf("\n\t");ECHO;printf("\n");}
\( ECHO;
= {if(!COMMENT)printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\< |
== |
\> {if(!COMMENT) printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
%%
int main(int argc,char **argv)
{
if (argc > 1)
{
FILE *file;
file = fopen(argv[1],"r");
if(!file)
{
printf("could not open %s \n",argv[1]);
exit(0);
}
yyin = file;
}
yylex();
printf("\n\n Total No.Of comments are %d",cnt);
return 0;
}
int yywrap()
{
return 1;
}
Output:
⮚ Input:
#include<stdio.h>
main ()
{
Int a, b;
}
⮚ Output:
#include<stdio.h> is a PREPROCESSOR DIRECTIVE
FUNCTION
main(
)
BLOCK BEGINS
Int is a keyword
a Identifier
b Identifier
BLOCK ENDS
Result:
Thus the C program to implement the lexical analyzer using LEX tool was
executed and the output is verified.
PROGRAM – 6
Objective:
Generate YACC specification for a Program to recognize a valid arithmetic
expression that uses operator +, –, * and /.
Implementation:
Code:
⮚ Lex Analyzer Code:
%
{
/* Definition section*/
#include "y.tab.h"
extern yylval;
%
}
%%
[0 - 9]
+
{
yylval = atoi(yytext);
return NUMBER;
}
[a - zA - Z] + { return ID; }
[\t] + ;
\n { return 0; }
. { return yytext[0]; }
%%
/* Definition section */
#include
%
% token NUMBER ID
// setting the precedence
// and associativity of operators
% left '+''-'
% left '*''/'
/* Rule Section */
%
%E:T
{
T : T '+'T { $$ = $1 + $3; }
| T '-'T { $$ = $1 - $3; }
| T '*'T { $$ = $1 * $3; }
| T '/'T { $$ = $1 / $3; }
| '-'NUMBER { $$ = -$2; }
| '-'ID { $$ = -$2; }
| '('T ')'{ $$ = $2; }
| NUMBER { $$ = $1; }
| ID { $$ = $1; };
%%
intmain()
{
printf("Enter the expression:\n");
yyparse();
}
Output:
Enter the expression: (6/ (3-2) + 1 – 4) * 2
Result: 6
Result:
We have successfully implemented a program that recognize a valid arithmetic
expression that uses operator +, –, * and /.
PROGRAM – 7
Objective:
Write program to convert NFA to DFA
#include<stdio.h>
int Fa[10][10][10],states[2][10],row=0,col=0,sr=0,sc=0,th=0,
in,stat,new_state[10][10],max_inp=-1,no_stat;
FILE *fp;
int i;
for(i=0;i<no_stat;i++)
if(search_var == states[1][i])
return 1;
return 0;
}
t=0;
for(j=i;j<c;j++)
{
arr[j]=new_state[temp][t];
t++;
}
}
}
c=0;
for(i=0;arr[i]!=-1;i++)
c++;
*count=c;
return 0;
}
for(t=0;t<=max_inp;t++)
{
count=0;
for(k=0;k<10;k++)
arr[k]=-1;
trans(i,j,t,c,&count,arr);
checkcon(arr,&count);
sort(arr,count);
remove_duplicate(arr,&count);
for(k=0;k<count;k++)
Fa[stat][t][k]=arr[k];
}
Fa[i][j][0]=stat++;
for(t=1;t<c;t++)
Fa[i][j][t]=-1;
}
else
{
Fa[i][j][0]=name ;
for(t=1;t<c;t++)
Fa[i][j][t]=-1;
}
}
}
}
return 0;
}
int main()
{
int i,j,k,flag=0,start,end;
char c,ch;
fp=fopen("Nfa_ip.txt","r+");
for(i=0;i<2;i++)
for(j=0;j<10;j++)
states[i][j]=-1;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
new_state[i][j]=-1;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
for(k=0;k<10;k++)
Fa[i][j][k]=-1;
while(fscanf(fp,"%d",&in)!=EOF)
{
fscanf(fp,"%c",&c);
if(flag)
{
states[sr][sc++]=in;
if(c=='\n')
{
sr++;
sc=0;
}
}
else if(c=='#')
{
flag=1;
Fa[row][col][th]=in;
}
else if(!flag)
{
Fa[row][col][th]=in;
if(c==',')
{
th++;
}
else if(c=='\n')
{
if(max_inp<col)
max_inp=col;
col=0;
row++;
th=0;
}
else if(c!=',')
{
col++;
th=0;
}
}
}
no_stat=0;
i=0;
while(states[1][i++]!=-1)
no_stat++;
stat=row+1;
start=0;end=row;
while(1)
{
nfa2dfa(start,end);
start=end+1;
end=row;
if(start>end)
break;
}
printf("\n\nDFA IS : \n\n\n");
for(i=0;i<=max_inp;i++)
printf("\t%d",i);
printf("\n");
printf("----------------------------\n");
for(i=0;i<stat;i++)
{
printf("%d-> |",i);
for(j=0;j<=max_inp;j++)
{
printf("%2d ",Fa[i][j][0]);
}
printf("\n");
}
printf("\n\n");
printf("Total Number Of State Is : %d \n\n",stat);
printf("Final States Are : ");
for(i=0;states[1][i]!=-1;i++)
printf("%d ",states[1][i]);
printf("\n\n");
getch();
return 0;
}
PROGRAM – 8
Objective:
Write program to convert NFA to DFA
#include<stdio.h>
#include<ctype.h>
void FIRST(char[],char );
void addToResultSet(char[],char);
int numOfProductions;
char productionSet[10][10];
main()
{
int i;
char choice;
char c;
char result[20];
printf("How many number of productions ? :");
scanf(" %d",&numOfProductions);
for(i=0;i<numOfProductions;i++)//read production string eg:
E=E+T
{
printf("Enter productions Number %d : ",i+1);
scanf(" %s",productionSet[i]);
}
do
{
printf("\n Find the FIRST of :");
scanf(" %c",&c);
FIRST(result,c); //Compute FIRST; Get Answer in 'result'
array
printf("\n FIRST(%c)= { ",c);
for(i=0;result[i]!='\0';i++)
printf(" %c ",result[i]); //Display result
printf("}\n");
printf("press 'y' to continue : ");
scanf(" %c",&choice);
}
while(choice=='y'||choice =='Y');
}
/*
*Function FIRST:
*Compute the elements in FIRST(c) and write them
*in Result Array.
*/
void FIRST(char* Result,char c)
{
int i,j,k;
char subResult[20];
int foundEpsilon;
subResult[0]='\0';
Result[0]='\0';
//If X is terminal, FIRST(X) = {X}.
if(!(isupper(c)))
{
addToResultSet(Result,c);
return ;
}
//If X is non terminal
//Read each production
for(i=0;i<numOfProductions;i++)
{
//Find production with X as LHS
if(productionSet[i][0]==c)
{
//If X → ε is a production, then add ε to FIRST(X).
if(productionSet[i][2]=='$') addToResultSet(Result,'$');
//If X is a non-terminal, and X → Y1 Y2 … Yk
//is a production, then add a to FIRST(X)
//if for some i, a is in FIRST(Yi),
//and ε is in all of FIRST(Y1), …, FIRST(Yi-1).
else
{
j=2;
while(productionSet[i][j]!='\0')
{
foundEpsilon=0;
FIRST(subResult,productionSet[i][j]);
for(k=0;subResult[k]!='\0';k++)
addToResultSet(Result,subResult[k]);
for(k=0;subResult[k]!='\0';k++)
if(subResult[k]=='$')
{
foundEpsilon=1;
break;
}
//No ε found, no need to check next element
if(!foundEpsilon)
break;
j++;
}
}
}
}
return ;
}
/* addToResultSet adds the computed
*element to result set.
*This code avoids multiple inclusion of elements
*/
void addToResultSet(char Result[],char val)
{
int k;
for(k=0 ;Result[k]!='\0';k++)
if(Result[k]==val)
return;
Result[k]=val;
Result[k+1]='\0';
}