0% found this document useful (0 votes)
13 views39 pages

Lab Manual Compiler

The document outlines the Compiler Design Lab course for B.E. III Year students, detailing various experiments related to lexical analysis and parsing techniques using tools like C, Lex, and Yacc. It includes a list of experiments, course outcomes, and a lecture plan that emphasizes practical implementation of compiler concepts. The document also provides sample programs and expected outputs for each experiment.

Uploaded by

Harun Faridi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
13 views39 pages

Lab Manual Compiler

The document outlines the Compiler Design Lab course for B.E. III Year students, detailing various experiments related to lexical analysis and parsing techniques using tools like C, Lex, and Yacc. It includes a list of experiments, course outcomes, and a lecture plan that emphasizes practical implementation of compiler concepts. The document also provides sample programs and expected outputs for each experiment.

Uploaded by

Harun Faridi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 39

Department of Computer Science &

Engineering
SUBJECT: Compiler Design Lab
(CSP-350)

B.E. III Year – V Semester


(Branch: UIE-CSE)
(Batch: 2019-23)

Prepared by: Kundan Munjal


Table of Contents
Sr. No. Name of the Experiments
Unit 1
1 Design and implement a lexical analyzer for given language using C and the lexical
analyzer should ignore redundant spaces, tabs and new lines.

2 Implement the lexical analyzer using JLex/ flex or lex or other lexical analyzer generating
tools.
3 Write a lex program to find out total number of vowels, and consonants from the given
input sting.
4 Write a LEX Program to convert the substring abc to ABC from the given input string
Unit 2
5 Program to recognize a valid arithmetic expression that uses operator +, – , * and /.
6 Write a Program with Yacc for implementing calculator with atleast 10 operators.
7 Write a Program to convert Infix to Postfix using Yacc
Unit 3
8 Write a Program that outputs first and follow of a production grammar
9 Write a Program to implement Shift Reduce Parser for a given language.
10 Write a Program to implement Recursive Descent Parsing.

Course PSO PSO PSO


PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 PO11 PO12
Outcome 1 2 3
2 2 1
CO1 2 2 3 3 - 2 1 - 1 - 1 1
2 1 1
CO2 3 3 3 2 - 3 2 - 1 - - 3
2 2 1
CO3 2 3 3 3 - 3 3 - 2 - - 2
1 2 1
CO4 - - - - - 2 2 - 2 - - -
1 1 1
CO5 - - - - - 1 1 - 2 - 3 3
Course Outcomes

CO1 Understand the practical approach of how a compiler works.

CO2 Work in the development phase of new computer languages in industry

CO3 Apply the knowledge of Lex & Yacc tools to develop programs

CO4 Implement the techniques of Lexical Analysis and Syntax Analysis.

CO5 Implement Parsing Techniques for languages.


Lecture Plan

S.No Name of Experiment Text Book Pedagogical Tools Software used

1 Design and implement a lexical analyzer for Compiler Principles, Techniques and PPT/ Simulator C/C++
given language using C and the lexical analyzer Tools Pearson/ Lex & Yacc O’ Reily
should ignore redundant spaces, tabs and new
lines.

2 Write a program to Implement the lexical Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
analyzer using JLex/ flex or lex or other lexical Tools Pearson/ Lex & Yacc O’ Reily
analyzer generating tools.

3 Write a lex program to find out total number of Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
vowels, and consonants from the given input Tools Pearson/ Lex & Yacc O’ Reily
string.

4 Write a LEX Program to convert the substring Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
abc to ABC from the given input string. Tools Pearson/ Lex & Yacc O’ Reily

5 Program to recognize a valid arithmetic Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
expression that uses operator +, – , * and /. Tools Pearson/ Lex & Yacc O’ Reily

6 Write a YACC program to implement a Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
Calculator and recognize a valid Arithmetic Tools Pearson/ Lex & Yacc O’ Reily
expression.

7 WAP to convert Infix to Postfix using Yacc. Compiler Principles, Techniques and PPT/ Simulator Lex and Yacc
Tools Pearson/ Lex & Yacc O’ Reily

8 Write a Program that outputs first and follow of Compiler Principles, Techniques and PPT/ Simulator C/C++
a production grammar Tools Pearson/ Lex & Yacc O’ Reily

9 Write a Program to implement Shift Reduce Compiler Principles, Techniques and PPT/ Simulator C/C++
Parser for a given language. Tools Pearson/ Lex & Yacc O’ Reily

10 Write a Program to implement Recursive Compiler Principles, Techniques and PPT/ Simulator C/C++
Descent Parsing. Tools Pearson/ Lex & Yacc O’ Reily
EXPERIMENT - 01

Aim: Design and implement a lexical analyzer for given language using C and the lexical analyzer should
ignore redundant spaces, tabs and new lines

PROGRAM:

#include<string.h>

#include<ctype.h>

#include<stdio.h>

void keyword(char str[10])

if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0|| strcmp("int",str)==0||strcmp("float",str)==0||
strcmp("char",str)==0||strcmp("double",str)==0||

strcmp("static",str)==0||strcmp("switch",str)==0||strcmp("case",str)==0)

printf("\n%s is a keyword",str);

else
printf("\n%s is an identifier",str);

main()

FILE *f1,*f2,*f3;

char c,str[10],st1[10];

int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;

printf("\nEnter the c program");/*gets(st1);*/

f1=fopen("input","w");

while((c=getchar())!=EOF)

putc(c,f1);

fclose(f1);

f1=fopen("input","r");

f2=fopen("identifier","w");

f3=fopen("specialchar","w");

while((c=getc(f1))!=EOF){

if(isdigit(c))

tokenvalue=c-'0';

c=getc(f1);

while(isdigit(c)){

tokenvalue*=10+c-'0';

c=getc(f1);

num[i++]=tokenvalue;
ungetc(c,f1);

else if(isalpha(c))

putc(c,f2);

c=getc(f1);

while(isdigit(c)||isalpha(c)||c=='_'||c=='$')

putc(c,f2);

c=getc(f1);

putc(' ',f2);

ungetc(c,f1);

else if(c==' '||c=='\t')

printf(" ");

else

if(c=='\n')

lineno++;

else

putc(c,f3);

fclose(f2);

fclose(f3);

fclose(f1);

printf("\nThe no's in the program are");


for(j=0;j<i;j++)

printf("%d",num[j]);

printf("\n");

f2=fopen("identifier","r");

k=0;

printf("The keywords and identifiersare:");

while((c=getc(f2))!=EOF){

if(c!=' ')

str[k++]=c;

else

str[k]='\0';

keyword(str);

k=0;

fclose(f2);

f3=fopen("specialchar","r");

printf("\nSpecial characters are");

while((c=getc(f3))!=EOF)

printf("%c",c);

printf("\n");

fclose(f3);

printf("Total no. of lines are:%d",lineno);

}
Input:
Enter Program $ for termination:
{
int a[3],t1,t2;
t1=2; a[0]=1; a[1]=2; a[t1]=3;
t2=-(a[2]+t1*6)/(a[2]-t1);
if t2>5 then
print(t2);
else {
int t3;
t3=99;
t2=-25;
print(-t1+t2*t3); /* this is a comment on 2 lines */
} endif
}
(cntrl+z)

Output:
Variables : a[3] t1 t2 t3
Operator : - + * / >
Constants : 2 1 3 6 5 99 -25
Keywords : int if then else endif
Special Symbols : , ; ( ) { }
Comments : this is a comment on 2 lines
EXPERIMENT - 02

Aim: Write a program to Implement the lexical analyzer using JLex/ flex or lex or other lexical analyzer

generating tools.

PROGRAM CODE:
PROGRAM:

%{

int COMMENT=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;}

/*{printf("\n\n\t%s is a COMMENT\n",yytext);}*/

"*/" {COMMENT = 0;}


/* printf("\n\n\t%s is a COMMENT\n",yytext);}*/

{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");

return 0;

int yywrap()

{
return 0;

Input

$vi var.c

#include<stdio.h>

main()

int a,b;

Output

$lex lex.l

$cc lex.yy.c

$./a.out var.c

#include<stdio.h> is a PREPROCESSOR DIRECTIVE


FUNCTION

main (

BLOCK BEGINS

int is a KEYWORD

a IDENTIFIER

b IDENTIFIER

BLOCK ENDS
EXPERIMENT - 03

AIM: Write a lex program to find out total number of vowels, and consonants from the

given input string.

PROGRAM CODE:
%{
int vow_count=0;
int const_count =0;
%}

%%
[aeiouAEIOU] {vow_count++;}
[a-zA-Z] {const_count++;}
%%
int yywrap(){}
int main()
{
printf("Enter the string of vowels and consonents:");
yylex();
printf("Number of vowels are: %d\n", vow_count);
printf("Number of consonants are: %d\n", const_count);
return 0;
}

SAMPLE OUTPUT:
EXPERIMENT - 04

AIM: Write a LEX Program to convert the substring abc to ABC from the given input string.

PROGRAM CODE:

%{

#include<stdio.h>

#include<string.h>

int i;

%}

%%

[a-z A-Z]* {

for(i=0;i<=yyleng;i++)

if((yytext[i]=='a')&&(yytext[i+1]=='b')&&(yytext[i+2]=='c'))

yytext[i]='A';

yytext[i+1]='B';

yytext[i+2]='C';

printf("%s",yytext);

[\t]* return;
.* {ECHO;}

\n {printf("%s",yytext);}

%%

main()

yylex();

int yywrap()

return 1;

OUTPUT:

[CSE@localhost ~]$ lex lex1.l

[CSE@localhost ~]$ cc lex.yy.c

[CSE@localhost ~]$. /a.out

abc

ABC
EXPERIMENT - 05
AIM: Program to recognize a valid arithmetic expression that uses operator +, – , * and /.

PROGRAM CODE:
/* Lex program to recognize valid arithmetic expression
and identify the identifiers and operators */
%{
#include <stdio.h>
#include <string.h>
int operators_count = 0, operands_count = 0, valid = 1, top = -1, l = 0, j = 0;
char operands[10][10], operators[10][10], stack[100];
%}
%%
"(" {
top++;
stack[top] = '(';
}
"{" {
top++;
stack[top] = '{';
}
"[" {
top++;
stack[top] = '[';
}
")" {
if (stack[top] != '(') {
valid = 0;
}
else if(operands_count>0 && (operands_count-operators_count)!=1){
valid=0;
}
else{
top--;
operands_count=1;
operators_count=0;
}
}
"}" {
if (stack[top] != '{') {
valid = 0;
}
else if(operands_count>0 && (operands_count-operators_count)!=1){
valid=0;
}
else{
top--;
operands_count=1;
operators_count=0;
}
}
"]" {
if (stack[top] != '[') {
valid = 0;
}
else if(operands_count>0 && (operands_count-operators_count)!=1){
valid=0;
}
else{
top--;
operands_count=1;
operators_count=0;
}

}
"+"|"-"|"*"|"/" {
operators_count++;
strcpy(operators[l], yytext);
l++;
}
[0-9]+|[a-zA-Z][a-zA-Z0-9_]* {
operands_count++;
strcpy(operands[j], yytext);
j++;
}
%%

int yywrap()
{
return 1;
}
int main()
{
int k;
printf("Enter the arithmetic expression: ");
yylex();

if (valid == 1 && top == -1) {


printf("\nValid Expression\n");
}
else
printf("\nInvalid Expression\n");

return 0;
}
SAMPLE OUTPUT:
EXPERIMENT - 06

AIM: Write a YACC program to implement a Calculator and recognize a valid Arithmetic expression.

Explanation:

Yacc (for “yet another compiler compiler.”) is the standard parser generator for the Unix operating system. An open
source program, yacc generates code for the parser in the C programming language. The acronym is usually rendered
in lowercase but is occasionally seen as YACC or Yacc.

Program Code:

%{

/* Definition section */

#include<stdio.h>

#include "y.tab.h"

extern int yylval;

%}

/* Rule Section */

%%

[0-9]+ {

yylval=atoi(yytext);

return NUMBER;
}

[\t] ;

[\n] return 0;

. return yytext[0];

%%

int yywrap()

return 1;

SAMPLE OUTPUT:
EXPERIMENT - 07

AIM: WAP to convert Infix to Postfix using yacc

PROGRAM CODE:

%{
#include "y.tab.h"
extern int yylval;
%}

%%
[0-9]+ {
yylval=atoi(yytext);
return NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];

%%
int yywrap()

{ return 1;}

YACC -
%{
#include<stdio.h>
%}

%token NUMBER
%left '+' '-'
%left '*' '/'
%right NEGATIVE

%%
S: E {printf("\n"); }

E: E '+' E {printf("+"); }
| E '*' E {printf("*"); }
| E '-' E {printf("-"); }
| E '/' E {printf("/"); }
| NUMBER {printf("%d",yylval);}

%%

int main(){ yyparse();}


int yyerror(char *err) { printf("Error =>",err); }
SAMPLE OUTPUT:
EXPERIMENT – 08

AIM: WAP that outputs first and follow of production grammar.

PROGRAM CODE:
Input -

Output -
EXPERIMENT – 09

AIM: WAP to implement Shift Reduce Parser

PROGRAM CODE:
// Including Libraries
#include <bits/stdc++.h>
using namespace std;

// Global Variables
int z = 0, i = 0, j = 0, c = 0;

// Modify array size to increase


// length of string to be parsed
char a[16], ac[20], stk[15], act[10];

// This Function will check whether


// the stack contain a production rule
// which is to be Reduce.
// Rules can be E->2E2 , E->3E3 , E->4
void check()
{
// Copying string to be printed as action
strcpy(ac,"REDUCE TO E -> ");

// c=length of input string


for(z = 0; z < c; z++)
{
// checking for producing rule E->4
if(stk[z] == '4')
{
printf("%s4", ac);
stk[z] = 'E';
stk[z + 1] = '\0';

//printing action
printf("\n$%s\t%s$\t", stk, a);
}
}

for(z = 0; z < c - 2; z++)


{
// checking for another production
if(stk[z] == '2' && stk[z + 1] == 'E' &&
stk[z + 2] == '2')
{
printf("%s2E2", ac);
stk[z] = 'E';
stk[z + 1] = '\0';
stk[z + 2] = '\0';
printf("\n$%s\t%s$\t", stk, a);
i = i - 2;
}

}
for(z = 0; z < c - 2; z++)
{
//checking for E->3E3
if(stk[z] == '3' && stk[z + 1] == 'E' &&
stk[z + 2] == '3')
{
printf("%s3E3", ac);
stk[z]='E';
stk[z + 1]='\0';
stk[z + 1]='\0';
printf("\n$%s\t%s$\t", stk, a);
i = i - 2;
}
}
return ; // return to main
}

// Driver Function
int main()
{
printf("GRAMMAR is -\nE->2E2 \nE->3E3 \nE->4\n");

// a is input string
strcpy(a,"32423");

// strlen(a) will return the length of a to c


c=strlen(a);

// "SHIFT" is copied to act to be printed


strcpy(act,"SHIFT");

// This will print Labels (column name)


printf("\nstack \t input \t action");

// This will print the initial


// values of stack and input
printf("\n$\t%s$\t", a);

// This will Run upto length of input string


for(i = 0; j < c; i++, j++)
{
// Printing action
printf("%s", act);

// Pushing into stack


stk[i] = a[j];
stk[i + 1] = '\0';

// Moving the pointer


a[j]=' ';

// Printing action
printf("\n$%s\t%s$\t", stk, a);

// Call check function ..which will


// check the stack whether its contain
// any production or not
check();
}

// Rechecking last time if contain


// any valid production then it will
// replace otherwise invalid
check();

// if top of the stack is E(starting symbol)


// then it will accept the input
if(stk[0] == 'E' && stk[1] == '\0')
printf("Accept\n");
else //else reject
printf("Reject\n");
}

SAMPLE OUTPUT:

GRAMMAR is -
E->2E2
E->3E3
E->4

stack input action


$ 32423$ SHIFT
$3 2423$ SHIFT
$32 423$ SHIFT
$324 23$ REDUCE TO E -> 4
$32E 23$ SHIFT
$32E2 3$ REDUCE TO E -> 2E2
$3E 3$ SHIFT
$3E3 $ REDUCE TO E -> 3E3

$E $ Accept
EXPERIMENT - 10

AIM: WAP to implement Recursive Descent Parsing

PROGRAM CODE:

#include<stdio.h>

#include<conio.h>

#include<string.h>

char input[100];

int i,l;

void main()

clrscr();

printf("\nRecursive descent parsing for the following grammar\n"); printf("\nE->TE'\nE'->+TE'/@\nT->FT'\nT'->*FT'/@\nF-


>(E)/ID\n"); printf("\nEnter the string to be checked:"); gets(input);

if(E())

if(input[i+1]=='\0')

printf("\nString is accepted");

else

printf("\nString is not accepted");

else

printf("\nString not accepted");

getch();
}

E()

if(T())

if(EP())

return(1);

else

return(0);

else

return(0);

EP()

if(input[i]=='+')

i++;

if(T())

if(EP())

return(1);

else
return(0);

else

return(0);

else

return(1);

T()

if(F())

if(TP())

return(1);

else

return(0);

else

return(0);

TP()

{
if(input[i]=='*')

i++;

if(F())

if(TP())

return(1);

else

return(0);

else

return(0);

else

return(1);

F()

if(input[i]=='(')

i++;

if(E())

{
if(input[i]==')')

i++;

return(1);

else

return(0);

else

return(0);

else if(input[i]>='a'&&input[i]<='z'||input[i]>='A'&&input[i]<='Z')

i++;

return(1);

else

return(0);

SAMPLE OUTPUT:

INPUT & OUTPUT:


Recursive descent parsing for the following grammar

E->TE'

E'->+TE'/@

T->FT'

T'->*FT'/@

F->(E)/ID

Enter the string to be checked:(a+b)*c

String is accepted

Recursive descent parsing for the following grammar

E->TE'

E'->+TE'/@

T->FT'

T'->*FT'/@

F->(E)/ID

You might also like