Compiler Design Lab Manual
Compiler Design Lab Manual
Compiler Design Lab Manual
%{
int ch=0, bl=0, ln=0, wr=0;
%}
%%
[\n] {ln++;wr++;}
[\t] {bl++;wr++;}
[" "] {bl++;wr++;}
[^\n\t] {ch++;}
%%
int main()
{
FILE *fp;
char file[10];
printf("Enter the filename: ");
scanf("%s", file);
yyin=fp;
yylex();
printf("Character=%d\nBlank=%d\nLines=%d\nWords=%d",
ch, bl, ln, wr);
return 0;
}
OUTPUT
$cat > input
Girish rao salanke
$lex p1a.l
$cc lex.yy.c –ll
$./a.out
Enter the filename: input
Character=16
Blank=2
Lines=1
Word=3
%{
int com=0;
%}
%%
"/*"[^\n]+"*/" {com++;fprintf(yyout, " ");}
%%
int main()
{
printf("Write a C program\n");
yyout=fopen("output", "w");
yylex();
printf("Comment=%d\n",com);
return 0;
}
OUTPUT
$lex p1b.l
$cc lex.yy.c –ll
$./a.out
Write a C program
#include<stdio.h>
int main()
{
int a, b;
/*float c;*/
printf(“Hai”);
/*printf(“Hello”);*/
}
[Ctrl-d]
Comment=1
$cat output
#include<stdio.h>
int main()
{
int a, b;
printf(“Hai”);
}
OUTPUT
$lex p2a.l
$cc lex.yy.c –ll
$./a.out
Enter the expression
(a+b*c)
a is an identifier
b is an identifier
c is an identifier
[Ctrl-d]
Valid expression
Add=1
Sub=0
Mul=1
Div=0
Operators are:
+
*
%{
int flag=0;
%}
%%
(""[aA][nN][dD]"")|(""[oO][rR]"")|(""[bB][uU][tT]"")
{flag=1;}
%%
int main()
{
printf("Enter the sentence\n");
yylex();
if(flag==1)
printf("\nCompound sentence\n");
else
printf("\nSimple sentence\n");
return 0;
}
OUTPUT
$lex p2b.l
$cc lex.yy.c –ll
$./a.out
Enter the sentence
I am Pooja
I am Pooja
[Ctrl-d]
Simple sentence
$./a.out
Enter the sentence
CSE or ISE
CSE or ISE
[Ctrl-d]
Compound sentence
OUTPUT
$cat > input
int
float
78f
90gh
a
d
are case
default
printf
scanf
$lex p3.l
$cc lex.yy.c –ll
$./a.out
Enter the filename: input
int is a keyword
float is a keyword
78f is not an identifier
90g is not an identifier
h is an identifier
a is an identifier
d is an identifier
are is an identifier
case is a keyword
default is a keyword
printf is a keyword
scanf is a keyword
total identifiers are: 4
LEX
%{
#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];}
%%
YACC
%{
#include<stdio.h>
%}
%token NUMBER ID
%left '+' '-'
%left '*' '/'
%%
expr: expr '+' expr
|expr '-' expr
|expr '*' expr
|expr '/' expr
|'-'NUMBER
|'-'ID
|'('expr')'
|NUMBER
|ID
;
%%
main()
{
printf("Enter the expression\n");
yyparse();
printf("\nExpression is valid\n");
exit(0);
}
int yyerror(char *s)
{
printf("\nExpression is invalid");
exit(0);
}
OUTPUT
$lex p4a.l
$yacc –d p4a.y
$cc lex.yy.c y.tab.c –ll
$./a.out
Enter the expression
(a*b+5)
Expression is valid
$./a.out
Enter the expression
(a+6-)
Expression is invalid
YACC
%{
#include<stdio.h>
%}
%token LETTER DIGIT
%%
variable: LETTER|LETTER rest
;
rest: LETTER rest
|DIGIT rest
|LETTER
|DIGIT
;
%%
main()
{
yyparse();
printf("The string is a valid variable\n");
}
int yyerror(char *s)
{
printf("this is not a valid variable\n");
exit(0);
}
OUTPUT
$lex p4b.l
$yacc –d p4b.y
$cc lex.yy.c y.tab.c –ll
$./a.out
input34
The string is a valid variable
$./a.out
89file
This is not a valid variable
LEX
%{
#include"y.tab.h"
#include<math.h>
extern yylval;
%}
%%
[0-9]+ {yylval=atoi(yytext); return NUM;}
[+] {return '+';}
[-] {return '-';}
[*] {return '*';}
[/] {return '/';}
[\t]+ ;
[\n] {return 0;}
. {return yytext[0];}
%%
YACC
%{
#include<stdio.h>
%}
%token NUM
%left '-' '+'
%right '*' '/'
%%
start: exp {printf("%d\n", $$);}
exp: exp '+' exp {$$=$1+$3;}
| exp '-' exp {$$=$1-$3;}
| exp '*' exp {$$=$1*$3;}
| exp '/' exp
{
if($3==0)
yyerror("error");
else
{
$$=$1/$3;
}
}
| '('exp')' {$$=$2;}
| NUM {$$=$1;}
;
%%
main()
{
printf("Enter the expr in terms of integers\n");
if(yyparse()==0)
printf("Success\n");
}
yyerror()
{
printf("Error\n");
}
OUTPUT
$lex p5a.l
$yacc –d p5a.y
$cc lex.yy.c y.tab.c –ll
$./a.out
Enter the expr in terms of integers
5+6*3
23
Success
LEX
%{
#include"y.tab.h"
%}
%%
[a] return A;
[b] return B;
%%
YACC
%{
#include<stdio.h>
%}
%token A B
%%
S:A S B
|
;
%%
main()
{
printf("Enter the string\n");
if(yyparse()==0)
{
printf("Valid\n");
}
}
yyerror(char *s)
{
printf("%s\n",s);
}
OUTPUT
$lex p5b.l
$yacc –d p5b.y
$cc lex.yy.c y.tab.c –ll
$./a.out
Enter the string
aabb
[Ctrl-d]
Valid
$./a.out
Enter the string
aab
syntax error
LEX
%{
#include"y.tab.h"
%}
%%
[a] return A;
[b] return B;
%%
YACC
%{
#include<stdio.h>
%}
%token A B
%%
stat:exp B
;
exp:A A A A A A A A A exp1
;
exp1:A exp2
|A
|A A exp2
|A A A exp2
|A A A A exp2
;
exp2:A
;
%%
main()
{
printf("Enter the string\n");
if(yyparse()==0)
{
printf("Valid\n");
}
}
yyerror(char *s)
{
printf("error\n");
}
OUTPUT
$lex p6.l
$yacc –d p6.y
$cc lex.yy.c y.tab.c –ll
$./a.out
Enter the string
aaaaaaaaaaab
Valid
$./a.out
Enter the string
aab
error
PART – B
1 (a) Non-recursive shell script that accepts any number of
arguments and prints them in the reverse order.
OUTPUT
$chmod 777 1a.sh
$./1a.sh a b c
#include<stdio.h>
#include<sys/types.h>
int main()
{
char cmd[20];
pid_t pid;
int ch;
pid=fork();
if(pid==0)
{
do
{
printf("\nEnter the command to be executed:");
scanf("%s", cmd);
system(cmd);
printf("\nEnter 1 to continue and 0 to exit:");
}
while(ch!=0);
}
wait();
}
OUTPUT
$cc 1b.c
$./a.out
OUTPUT
$chmod 777 2a.sh
$cat > file1
This is the first file
$cat > file2
This is the second file
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
int fd;
char buf1[]="Department of CS";
char buf2[]="Department of IS";
fd=creat("cse", 0622);
if(fd<0)
{
printf("\nError in creating file");
exit(0);
}
write(fd, buf1, 16);
lseek(fd, 48, SEEK_SET);
write(fd, buf2, 16);
exit(0);
}
OUTPUT
$cc 2b.c
$./a.out
$od –c cse
0000000 D e p a r t m e n t O f C S
0000020 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
*
0000060 D e p a r t m e n t O f I S
0000100
OUTPUT
$chmod 777 3a.sh
$ls –l
total 12
-rwxr-xr-x 1 root root 148 Mar 1 22:17 1a.sh
-rwxr-xr-x 1 root root 366 Mar 1 22:17 2a.sh
-rwxrwxrwx 1 root root 192 Mar 1 22:17 3a.sh
$./3a.sh /cse/usp
The max size of the file in directory /cse/usp is 366 bytes
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char *argv[])
{
int i;
struct stat buf;
for(i=1;i<argc;i++)
{
printf("%s: ",argv[i]);
lstat(argv[i], &buf);
if(S_ISREG(buf.st_mode))
printf("File is a regular file\n");
if(S_ISDIR(buf.st_mode))
printf("File is a directory file\n");
if(S_ISCHR(buf.st_mode))
printf("File is a character file\n");
if(S_ISBLK(buf.st_mode))
printf("File is a block file\n");
if(S_ISLNK(buf.st_mode))
printf("File is a symbolic link file\n");
}
exit(0);
}
OUTPUT
$cc 3b.c
$./a.out /cse/3b.c
/cse/3b.c: File is a regular file
$./a.out /cse
/cse: File is a directory file
$./a.out /dev/tty /cse/prog3a
/dev/tty: File is a character file
/cse/prog3a: File is a symbolic link file
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh
$rm file1
rm: remove regular file ‘file1’? y
$rm file2
rm: remove regular file ‘file2’? y
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a
1b.c 5a.sh 6a.sh 7a.sh 9a.sh new.sh
$./new.sh
file1
file2
$ls
10b.c 4a.sh 5b.c 6b.c 8a.sh a file2
1b.c 5a.sh 6a.sh 7a.sh 9a.sh file1 new.sh
$cat file1
This is the first file
$cat file2
This is the second file
4 (b) C program to do the following: Using fork( ) create a child
process. The child process prints its own process-id and id of its
parent and then exits. The parent process waits for its child to
finish (by executing the wait()) and prints its own process-id and
the id of its child process and then exits.
#include<sys/types.h>
#include<stdio.h>
int main()
{
int pid;
pid=fork();
if(pid<0)
printf("fork error");
if(pid==0)
{
printf("\nThis is child process");
printf("\nChild PID: %d", getpid());
printf("\nParent PID: %d", getppid());
execlp("/bin/ls",NULL);
exit(0);
}
else
{
wait(NULL);
printf("\nThis is parent process");
printf("\nParent PID: %d", getpid());
printf("\nChild PID: %d", pid);
exit(0);
}
}
OUTPUT
$cc 4b.c
$./a.out
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int parsecondition(char[],int,char*,int);
void gen(char [],char [],char[],int);
int main()
{
int counter = 0,stlen =0,elseflag=0;
char stmt[60]; // contains the input statement
char strB[54]; // holds the expression for 'if'
condition
char strS1[50]; // holds the statement for true
condition
char strS2[45]; // holds the statement for false
condition
return 0;
}
if(stmt[counter]==')')
counter++; // increment over ')'
counter = counter + 3; // increment over 'else'
counter = parsecondition(stmt,counter,strS2,stlen);
counter = counter + 2; // move to the end of
statement
if(counter == stlen)
{ //generate the output
elseflag = 1;
printf("\n Parsing the input statement....");
gen(strB,strS1,strS2,elseflag);
return 0;
}
return 0;
}
/* Function : parsecondition
Description : This function parses the statement
from the given index to get the statement enclosed
in ()
Input : Statement, index to begin search, string
to store the condition, total string length
Output : Returns 0 on failure, Non zero counter
value on success
*/
int parsecondition(char input[],int cntr,char
*dest,int totallen)
{
int index = 0,pos = 0;
while(input[cntr]!= '(' && cntr <= totallen)
cntr++;
if(cntr >= totallen)
return 0;
index = cntr;
while (input[cntr]!=')')
cntr++;
if(cntr >= totallen)
return 0;
while(index<=cntr)
dest[pos++] = input[index++];
dest[pos]='\0'; //null terminate the string
return cntr; //non zero value
}
/* Function : gen ()
Description : This function generates three
address code
Input : Expression, statement for true condition,
statement for false condition, flag to denote if
the 'else' part is present in the statement
output :Three address code
*/
void gen(char B[],char S1[],char S2[],int elsepart)
{
int Bt =101,Bf = 102,Sn =103;
printf("\n\tIf %s goto %d",B,Bt);
printf("\n\tgoto %d",Bf);
printf("\n%d: ",Bt);
printf("%s",S1);
if(!elsepart)
printf("\n%d: ",Bf);
else
{ printf("\n\tgoto %d",Sn);
printf("\n%d: %s",Bf,S2);
printf("\n%d:",Sn);
}
}
OUTPUT
%{
/**
Yacc program to recognise a regular expression
and produce a parse tree as output
*/
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
%token ALPHABET
%left '|'
%left '.'
%nonassoc '*' '+'
%%
S : re '\n' {
printf ( "This is the rightmost derivation--\n" );
for ( i = count - 1 ; i >= 0 ; --i ) {
if ( i == count - 1 ) {
printf ( "\nre => " );
strcpy ( temp , productions[i] );
printf ( "%s" , productions[i] );
}
else {
printf ( "\n => " );
j = getREindex ( temp );
temp[j] = '\0';
sprintf ( temp2 , "%s%s%s" , temp ,
productions[i] , (temp + j + 2) );
printf ( "%s" , temp2 );
strcpy ( temp , temp2 );
}
}
printf ( "\n" );
exit ( 0 );
}
re : ALPHABET {
temp[0] = yylval; temp[1] = '\0';
strcpy ( productions[count++] , temp );
}
| '(' re ')'
{ strcpy ( productions[count++] , "(re)" ); }
| re '*'
{ strcpy ( productions[count++] , "re*" ); }
| re '+'
{ strcpy ( productions[count++] , "re+" ); }
| re '|' re
{strcpy ( productions[count++] , "re | re" );}
| re '.' re
{strcpy ( productions[count++] , "re . re" );}
;
%%
int main ( int argc , char **argv )
{
/*
Parse and output the rightmost derivation,
from which we can get the parse tree
*/
yyparse();
return 0;
}
yylex()
{
signed char ch = getchar();
yylval = ch;
if ( isalpha ( ch ) )
return ALPHABET;
return ch;
}
yyerror()
{
fprintf(stderr , "Invalid Regular Expression!!\n");
exit ( 1 );
}
$a.out
a+|b*|(b.c*)
This is the rightmost derivation--
re => re | re
=> re | (re)
=> re | (re . re)
=> re | (re . re*)
=> re | (re . c*)
=> re | (b . c*)
=> re | re | (b . c*)
=> re | re* | (b . c*)
=> re | b* | (b . c*)
=> re+ | b* | (b . c*)
=> a+ | b* | (b . c*)