0% found this document useful (0 votes)
85 views36 pages

CS3501-CD Lab Manual

The document is a lab manual for the Compiler Design course at T.J.S Engineering College, detailing the vision, mission, course objectives, experiments, and outcomes for the CS3501 Compiler Design Laboratory. It includes specific experiments using tools like LEX and YACC to develop a lexical analyzer, recognize valid arithmetic expressions, and implement code optimization techniques. The manual aims to equip students with practical skills in compiler design and programming.

Uploaded by

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

CS3501-CD Lab Manual

The document is a lab manual for the Compiler Design course at T.J.S Engineering College, detailing the vision, mission, course objectives, experiments, and outcomes for the CS3501 Compiler Design Laboratory. It includes specific experiments using tools like LEX and YACC to develop a lexical analyzer, recognize valid arithmetic expressions, and implement code optimization techniques. The manual aims to equip students with practical skills in compiler design and programming.

Uploaded by

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

T.J.

S ENGINEERING COLLEGE
(Approved by AICTE &Affiliated to Anna University, Chennai)

Peruvoyal, (Near Kavarapettai), Gummidipoondi Taluk,

Thiruvallur District-601206

DEPARTMENT OF COMPUTER SCIENCE AND


ENGINEERING
B. E CSE – III YEAR/ V SEM- (R- 2021)

CS3501-COMPILER DESIGN LAB MANUAL


DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

VISION :

To create knowledge pool in the field of computer science and


engineering to empower the students to meet the challenges of the society

MISSION :

 Prepare the students with strong fundamental concepts, analytical


capabilities, programming and problem solving skills.
 Bringing an Eco-System to provide new cutting edge technologies required
to meet the challenges.
 Imparting necessary skills to become continuous learners in the field of
Computer Science and Engineering

CS3501 COMPILER DESIGN LABORATORY


Laboratory
CS3501 COMPILER DESIGN LABORATORY LTPC
0042
COURSE OBJECTIVES:

 To learn the various phases of compiler.


 To learn the various parsing techniques.
 To understand intermediate code generation and run-time environment.
 To learn to implement the front-end of the compiler.
 To learn to implement code generator.
 To learn to implement code optimization

LIST OF EXPERIMENTS:

1. Using the LEX tool, Develop a lexical analyzer to recognize a few patterns in C.
(Ex.identifiers, constants, comments, operators etc.). Create a symbol table, while
recognizing identifiers.
2. Implement a Lexical Analyzer using LEX Tool
3. Generate YACC specification for a few syntactic categories.
a. Program to recognize a valid arithmetic expression that uses operator +, -, * and /.
b. Program to recognize a valid variable which starts with a letter followed by any
number of letters or digits.
c. Program to recognize a valid control structures syntax of C language (For loop,
while loop, if-else, if-else-if, switch-case, etc.).
d. Implementation of calculator using LEX and YACC
4. Generate three address code for a simple program using LEX and YACC.
5. Implement type checking using Lex and Yacc.
6. Implement simple code optimization techniques (Constant folding, Strength
reduction and Algebraic transformation)
7. Implement back-end of the compiler for which the three address code is given as
input and the 8086 assembly language code is produced as output.

CS3501 COMPILER DESIGN LABORATORY


Laboratory
COURSE OUTCOMES:

On Completion of the course, the students should be able to:

CO1: Understand the techniques in different phases of a compiler.


CO2: Design a lexical analyser for a sample language and learn to use the LEX tool.
CO3: Apply different parsing algorithms to develop a parser and learn to use YACC tool
CO4: Understand semantics rules (SDT), intermediate code generation and run-time environment.
CO5: Implement code generation and apply code optimization techniques

CO-PO & PSO Mapping:

PO1 PO2 PO3 PO PO PO PO PO PO PO PO PO PSO PSO PSO3


4 5 6 7 8 9 10 11 12 1 2
CO1 3 3 3 3 - - - - 3 3 1 3 2 3 2

CO2 3 3 3 3 3 - - - 3 2 3 2 2 1 2
CO3 3 3 2 2 3 - - - 3 1 1 1 2 2 3

CO4 3 2 2 1 1 - - - 2 3 2 3 1 2 1

CO5 3 3 3 2 1 - - - 2 1 1 3 2 1 2

AVG 3.00 2.80 2.60 2.20 2.00 - - - 2.60 2.0 1.6 2.40 1.80 1.80 2.00
0 0

CS3501 COMPILER DESIGN LABORATORY


Laboratory
INDEX

PAGE
S.NO NAME OF THE EXERCISE NUMBER

Using the LEX tool, Develop a lexical analyzer to recognize a few


1
1 patterns in C. (Ex. identifiers, constants, comments, operators etc.).
Create a symbol table, while recognizing identifiers.

2 Implement a Lexical Analyzer using LEX Tool 4

Generate YACC specification for a few syntactic categories.


a. Program to recognize a valid arithmetic expression that uses 7
operator +, -, * and /.
3
b. Program to recognize a valid variable which starts with a letter
followed by any number of letters or digits. 10
c. Program to recognize a valid control structures syntax of C
language (For loop, while loop, if-else, if-else-if, switch-case, etc.).
Generate three address code for a simple program using LEX and
4 13
YACC.

5 Implement type checking using Lex and Yacc. 13

Implement simple code optimization techniques (Constant folding, 19


6
Strength reduction and Algebraic transformation)

Implement back-end of the compiler for which the three address 23,26
7 code is given as input and the 8086 assembly language code is
produced as output.

CS3501 COMPILER DESIGN LABORATORY


Laboratory
EXP NO: 01 DEVELOP A LEXICAL ANALYZER TO RECOGNIZE A NEW
PATTERN IN C
DATE:

AIM:
To develop a lexical analyzer to identify identifiers, constants, comments, operators etc using
C program

ALGORITHM:
Step1: Start the program.
Step2: Declare all the variables and file pointers.
Step3: Display the input program.
Step4: Separate the keyword in the program and display it.
Step5: Display the header files of the input program
Step6: Separate the operators of the input program and display it.
Step7: Print the punctuation marks.
Step8: Print the constant that are present in input program.
Step9: Print the identifiers of the input program.

PROGRAM CODE:
//Develop a lexical analyzer to recognize a few patterns in C.
#include<string.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
void keyword(char str[10])
{
if(strcmp("for",str)==0||strcmp("while",str)==0||strcmp("do",str)==0||strcmp("int",str)==0||str
cmp("float",str)==0||strcmp("char",str)==0||strcmp("double",str)==0||strcmp("printf",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);
}
void main()
{
FILE *f1,*f2,*f3;
char c,str[10],st1[10];
int num[100],lineno=0,tokenvalue=0,i=0,j=0,k=0;
f1=fopen("input","r");
f2=fopen("identifier","w");
f3=fopen("specialchar","w");
while((c=getc(f1))!=EOF)
{

1
CS3501-COMPILER DESIGN LABORATORY
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("\n the no's in the program are:");
for(j=0;j<i;j++)
printf("\t%d",num[j]);
printf("\n");
f2=fopen("identifier","r");
k=0;
printf("the keywords and identifier are:");
while((c=getc(f2))!=EOF)
if(c!=' ')
str[k++]=c;
else

2
CS3501-COMPILER DESIGN LABORATORY
{
str[k]='\0';
keyword(str);
k=0;
}
fclose(f2);
f3=fopen("specialchar","r");
printf("\n Special Characters are");
while((c=getc(f3))!=EOF)
printf("\t%c",c);
printf("\n");
fclose(f3);
printf("Total no of lines are:%d",lineno);
}

OUTPUT:

RESULT:
Thus, the program for developing a lexical analyzer to recognize a few patterns in C
has been executed successfully.

3
CS3501-COMPILER DESIGN LABORATORY
EXP NO: 02 IMPLEMENTATION OF A LEXICAL ANALYZER USING LEX

DATE :

AIM:
To write a program for implementing a Lexical analyser using LEX tool in Linux
platform.

ALGORITHM:
Step1: Lex program contains three sections: definitions, rules, and user subroutines. Each
section must be separated from the others by a line containing only the delimiter, %%. The
format is as follows: definitions %% rules %% user subroutines

Step2: In definition section, the variables make up the left column, and their definitions
make up the right column. Any C statements should be enclosed in %{..}%. Identifier is
defined such that the first letter of an identifier is alphabet and remaining letters are
alphanumeric.

Step3: In rules section, the left column contains the pattern to be recognized in an input file
to yylex(). The right column contains the C program fragment executed when that pattern is
recognized. The various patterns are keywords, operators, new line character, number, string,
identifier, beginning and end of block, comment statements, preprocessor directive statements
etc.

Step4: Each pattern may have a corresponding action, that is, a fragment of C source code to
execute when the pattern is matched.

Step5: When yylex() matches a string in the input stream, it copies the matched text to an
external character array, yytext, before it executes any actions in the rules section.

Step6: In user subroutine section, main routine calls yylex(). yywrap() is used to get more
input.

Step7: The lex command uses the rules and actions contained in file to generate a program,
lex.yy.c, which can be compiled with the cc command. That program can then receive input,
break the input into the logical pieces defined by the rules in file, and run program fragments
contained in the actions in file.

4
CS3501-COMPILER DESIGN LABORATORY
PROGRAM CODE:
//Implementation of Lexical Analyzer using Lex tool
%{
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 |
struct |
typedef |
do |
if |
break |
continue |
void |
switch |
return |
else |
goto {printf("\n\t%s is a keyword",yytext);}
"/*" {COMMENT=1;}{printf("\n\t %s is a COMMENT",yytext);}
{identifier}\( {if(!COMMENT)printf("\nFUNCTION \n\t%s",yytext);}
\{ {if(!COMMENT)printf("\n BLOCK BEGINS");}
\} {if(!COMMENT)printf("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 %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)
{
FILE *file;
file=fopen("var.c","r");
if(!file)
{
5
CS3501-COMPILER DESIGN LABORATORY
printf("could not open the file");
exit(0);
}
yyin=file;
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}
INPUT:
//var.c
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=1;
b=2;
c=a+b;
printf("Sum:%d",c);
}
OUTPUT:

RESULT:
Thus, the program for implementation of Lexical Analyzer using Lex tool has been
executed successfully.

6
CS3501-COMPILER DESIGN LABORATORY
EXP. NO :03 PROGRAM TO RECOGNIZE A VALID ARITHMETIC EXPRESSION
DATE :

AIM:

To write a Yacc program to valid arithmetic expression using Yacc.

ALGORITHM:

Step1: Start the program.

Step2: Reading an expression.

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program.

PROGRAM:

//Program to recognize a valid arithmetic expression that uses operator +, -, * and /

LEX PART:

%{

#include "y.tab.h"

%}

%%

[a-zA-Z_][a-zA-Z_0-9]* return id;

[0-9]+(\.[0-9]*)? return num;

[+/*] return op;

. return yytext[0];

\n return 0;

%%

7
CS3501-COMPILER DESIGN LABORATORY
int yywrap()

return 1;

YACC PART:

%{

#include<stdio.h>

int valid=1;

%}

%token num id op

%%

start : id '=' s ';'

s: id x

| num x

| '-' num x

| '(' s ')' x

x: op s

| '-' s

%%

int yyerror()

8
CS3501-COMPILER DESIGN LABORATORY
valid=0;

printf("\nInvalid expression!\n");

return 0;

int main()

printf("\nEnter the expression:\n");

yyparse();

if(valid)

printf("\nValid expression!\n");

OUTPUT:

RESULT:
Thus, the program for implementation of a Yacc program to valid arithmetic expression
using Yacc tool has been executed successfully.

9
CS3501-COMPILER DESIGN LABORATORY
EXP. NO :04 PROGRAM TO RECOGNIZE A VALID VARIABLE ANY NUMBER OF
LETTERS OR DIGITS

DATE :

AIM :

To write a yacc program to check valid variable followed by letter or digits

ALGORITHM:

Step1: Start the program

Step2: Reading an expression

Step3: Checking the validating of the given expression according to the rule using yacc.

Step4: Using expression rule print the result of the given values

Step5: Stop the program

PROGRAM CODE:

//Program to recognize a valid variable

LEX PART:

%{

#include "y.tab.h"

%}

%%

[a-zA-Z_][a-zA-Z_0-9]* return letter;

[0-9] return digit;

. return yytext[0];

\n return 0;

%%

int yywrap()

10
CS3501-COMPILER DESIGN LABORATORY
return 1;

YACC PART:

%{

#include<stdio.h>

int valid=1;

%}

%token digit letter

%%

start : letter s

s: letter s

| digit s

%%

int yyerror()

printf("\nIts not a identifier!\n");

valid=0;

return 0;

int main()

printf("\nEnter a name to tested for identifier ");

yyparse();

if(valid)

11
CS3501-COMPILER DESIGN LABORATORY
{

printf("\nIt is a identifier!\n");

OUTPUT:

RESULT:
Thus, the program for implementation of a a yacc program to check valid variable
followed by letter or digits using Yacc tool has been executed successfully.

12
CS3501-COMPILER DESIGN LABORATORY
EXP. NO : 05 IMPLEMENTATION OF CALCULATOR USING LEX & YACC
DATE :

AIM:

To write a program for implementing a calculator for computing the given expression using
semantic rules of the YACC tool and LEX.

ALGORITHM:

Step1: A Yacc source program has three parts as follows:

Declarations %% translation rules %% supporting C routines

Step2: Declarations Section: This section contains entries that:

i. Include standard I/O header file.

ii. Define global variables.

iii. Define the list rule as the place to start processing.

iv. Define the tokens used by the parser. v. Define the operators and their precedence.

Step3: Rules Section: The rules section defines the rules that parse the input stream. Each rule
of a grammar production and the associated semantic action.

Step4: Programs Section: The programs section contains the following subroutines. Because
these subroutines are included in this file, it is not necessary to use the yacc library when
processing this file.

Step5: Main- The required main program that calls the yyparse subroutine to start the program.

Step6: yyerror(s) -This error-handling subroutine only prints a syntax error message.

Step7: yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs.
The calc.lex file contains include statements for standard input and output, as programmar file
information if we use the -d flag with the yacc command. The y.tab.h file contains definitions
for the tokens that the parser program uses.

Step8: calc.lex contains the rules to generate these tokens from the input stream.

13
CS3501-COMPILER DESIGN LABORATORY
PROGRAM CODE:

//Implementation of calculator using LEX and YACC

LEX PART:

%{

#include<stdio.h>

#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;

14
CS3501-COMPILER DESIGN LABORATORY
YACC PART:

%{

#include<stdio.h>

int flag=0;

%}

%token NUMBER

%left '+' '-'

%left '*' '/' '%'

%left '(' ')'

%%

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;}

%%

15
CS3501-COMPILER DESIGN LABORATORY
void main()

printf("\nEnter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Divison, Modulus and Round brackets:\n");

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:

RESULT:
Thus, the program implementing a calculator for computing the given expression using
semantic rules of the YACC tool and LEX has been executed successfully.

16
CS3501-COMPILER DESIGN LABORATORY
EXP. NO : 06 IMPLEMENTATION OF TYPE CHECKING
DATE :

AIM:

To write a C program to implement type checking

ALGORITHM:

Step1: Track the global scope type information (e.g. classes and their members)

Step2: Determine the type of expressions recursively, i.e. bottom-up, passing the resulting
types upwards.

Step3: If type found correct, do the operation

Step4: Type mismatches, semantic error will be notified


PROGRAM CODE:
//To implement type checking
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n,i,k,flag=0;
char vari[15],typ[15],b[15],c;
printf("Enter the number of variables:");
scanf(" %d",&n);
for(i=0;i<n;i++)
{
printf("Enter the variable[%d]:",i);
scanf(" %c",&vari[i]);
printf("Enter the variable-type[%d](float-f,int-i):",i);
scanf(" %c",&typ[i]);
if(typ[i]=='f')
flag=1;
}
printf("Enter the Expression(end with $):");
i=0;
getchar();
while((c=getchar())!='$')
{
b[i]=c;
i++; }
k=i;
for(i=0;i<k;i++)
{
if(b[i]=='/')
{

17
CS3501-COMPILER DESIGN LABORATORY
flag=1;
break; } }
for(i=0;i<n;i++)
{
if(b[0]==vari[i])
{
if(flag==1)
{
if(typ[i]=='f')
{ printf("\nthe datatype is correctly defined..!\n");
break; }
else
{ printf("Identifier %c must be a float type..!\n",vari[i]);
break; } }
else
{ printf("\nthe datatype is correctly defined..!\n");
break; } }
}
return 0;
}

OUTPUT:

RESULT:
Thus, the program implementing type checking has been executed successfully.

18
CS3501-COMPILER DESIGN LABORATORY
EXP. NO : 07 IMPLEMENTATION OF CODE OPTIMIZATION TECHNIQUE
DATE :

AIM:
To write a program for implementation of Code Optimization Technique.

ALGORITHM:
Step1: Generate the program for factorial program using for and do-while loop to specify
optimization technique.
Step2: In for loop variable initialization is activated first and the condition is checked next. If
the condition is true the corresponding statements are executed and specified increment /
decrement operation is performed.
Step3: The for loop operation is activated till the condition failure.

Step4: In do-while loop the variable is initialized and the statements are executed then the
condition checking and increment / decrement operation is performed.

Step5: When comparing both for and do-while loop for optimization dowhile is best because
first the statement execution is done then only the condition is checked. So, during the
statement execution itself we can find the inconvenience of the result and no need to wait for
the specified condition result.

Step6: Finally when considering Code Optimization in loop do-while is best with respect to
performance.

PROGRAM CODE:
//Code Optimization Technique
#include<stdio.h>
#include<string.h>
struct op
{
char l;
char r[20];
}
op[10],pr[10];
void main()
{
int a,i,k,j,n,z=0,m,q;
char *p,*l;
char temp,t;
char *tem;
printf("Enter the Number of Values:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
scanf(" %c",&op[i].l);
19
CS3501-COMPILER DESIGN LABORATORY
printf("right: ");
scanf(" %s",&op[i].r);
}
printf("Intermediate Code\n") ;
for(i=0;i<n;i++)
{
printf("%c=",op[i].l);
printf("%s\n",op[i].r);
}
for(i=0;i<n-1;i++)
{
temp=op[i].l;
for(j=0;j<n;j++)
{
p=strchr(op[j].r,temp);
if(p)
{
pr[z].l=op[i].l;
strcpy(pr[z].r,op[i].
r);
z++;
}
}
}
pr[z].l=op[n-1].l;
strcpy(pr[z].r,op[n-1].r);
z++;
printf("\nAfter Dead Code Elimination\n");
for(k=0;k<z;k++)
{
printf("%c\t=",pr[k].l);
printf("%s\n",pr[k].r);
}
for(m=0;m<z;m++)
{
tem=pr[m].r;
for(j=m+1;j<z;j++)
{
p=strstr(tem,pr[j].r);
if(p)
{
t=pr[j].l;
pr[j].l=pr[m].l;
for(i=0;i<z;i++)
{
l=strchr(pr[i].r,t) ;
if(l)
{

20
CS3501-COMPILER DESIGN LABORATORY
a=l-pr[i].r;
printf("pos: %d\n",a);
pr[i].r[a]=pr[m].l;
}}}}}
printf("Eliminate Common Expression\n");
for(i=0;i<z;i++)
{
printf("%c\t=",pr[i].l);
printf("%s\n",pr[i].r);
}
for(i=0;i<z;i++)
{
for(j=i+1;j<z;j++)
{
q=strcmp(pr[i].r,pr[j].r);
if((pr[i].l==pr[j].l)&&!q)
{
pr[i].l='\0';
}
}
}
printf("Optimized Code\n");
for(i=0;i<z;i++)
{
if(pr[i].l!='\0')
{
printf("%c=",pr[i].l);
printf("%s\n",pr[i].r);
}
}
}

21
CS3501-COMPILER DESIGN LABORATORY
OUTPUT:

RESULT:
Thus, the program implementing of Code Optimization Technique has been executed
successfully.

22
CS3501-COMPILER DESIGN LABORATORY
EX.NO.08 IMPLEMENT THE BACK END OF THE COMPILER
DATE:

AIM:
To implement the back end of the compiler which takes the three-address code and produces
the 8086 assembly language instructions that can be assembled and run using a 8086
assembler. The target assembly instructions can be simple move, add, sub, jump. Also
simple addressing modes are used.

ALGORITHM:
1. Start the program
2. Open the source file and store the contents as quadruples.
3. Check for operators, in quadruples, if it is an arithmetic operator generator it or if
assignment operator generates it, else perform unary minus on register C.
4. Write the generated code into output definition of the file in outp.c
5. Print the output.
6. Stop the program.

PROGRAM: (BACK END OF THE COMPILER)


#include<stdio.h>
#include<stdio.h>
//#include<conio.h>
#include<string.h>
void main()
{
char icode[10][30],str[20],opr[10];
int i=0;
//clrscr();
printf("\n Enter the set of intermediate code (terminated by
exit):\n");
do
{
23
CS3501-COMPILER DESIGN LABORATORY
scanf("%s",icode[i]);
} while(strcmp(icode[i++],"exit")!=0);
printf("\n target code generation");
printf("\n************************");
i=0;
do
{
strcpy(str,icode[i]);
switch(str[3])
{
case '+':
strcpy(opr,"ADD");
break;
case '-':
strcpy(opr,"SUB");
break;
case '*':
strcpy(opr,"MUL");
break;
case '/':
strcpy(opr,"DIV");
break;
}
printf("\n\tMov %c,R%d",str[2],i);
printf("\n\t%s%c,R%d",opr,str[4],i);
printf("\n\tMov R%d,%c",i,str[0]);
}while(strcmp(icode[++i],"exit")!=0);
//getch();
}

24
CS3501-COMPILER DESIGN LABORATORY
OUTPUT:

RESULT:
Thus, the program was implemented to the TAC has been successfully executed

25
CS3501-COMPILER DESIGN LABORATORY
EX.NO.09 THREE ADDRESS CODE FOR A SIMPLE PROGRAM USING LEX AND
YACC.
DATE :

AIM:
To Generate three address code for a simple program using LEX and YACC.

ALGORITHM:
Step 1: Start at the root of the AST.
Step 2: If the node is a leaf node (a constant or variable), generate a temporary variable to hold
its value and return the temporary variable.
Step 3: If the node is a binary operator (e.g., +, -, *, /), recursively generate three-address code
for its left and right children.
Step 4: Generate a new temporary variable to store the result of the operation.
Step 5: Generate an instruction using the operator, the temporary variables for the left and right
children, and the new temporary variable created in the previous step.
Step 6: Return the new temporary variable.
Step 7: If the root of the AST is an assignment node, generate three-address code for the
expression on the right-hand side and then generate an assignment instruction to store the result
in the left-hand side variable.
Step 8: The final three-address code will consist of the generated instructions for each step
above.

PROGRAM:
Lex Program
%{
#include"y.tab.h"
extern char yyval;
%}
%%
[0-9]+ {yylval.symbol=(char)(yytext[0]);return NUMBER;}
[a-z] {yylval.symbol= (char)(yytext[0]);return LETTER;}
. {return yytext[0];}
26
CS3501-COMPILER DESIGN LABORATORY
\n {return 0;}
%%

YACC Program

%{
#include"y.tab.h"
#include<stdio.h>
char addtotable(char,char,char);
int index1=0;
char temp = 'A'-1;
struct expr{
char operand1;
char operand2;
char operator;
char result;
};
%}
%union{
char symbol;
}
%left '+' '-'
%left '/' '*'
%token <symbol> LETTER NUMBER
%type <symbol> exp
%%
statement: LETTER '=' exp ';' {addtotable((char)$1,(char)$3,'=');};
exp: exp '+' exp {$$ = addtotable((char)$1,(char)$3,'+');}
|exp '-' exp {$$ = addtotable((char)$1,(char)$3,'-');}
|exp '/' exp {$$ = addtotable((char)$1,(char)$3,'/');}
|exp '*' exp {$$ = addtotable((char)$1,(char)$3,'*');}
|'(' exp ')' {$$= (char)$2;}
|NUMBER {$$ = (char)$1;}
27
CS3501-COMPILER DESIGN LABORATORY
|LETTER {(char)$1;};
%%
struct expr arr[20];
void yyerror(char *s){
printf("Errror %s",s);
}
char addtotable(char a, char b, char o){
temp++;
arr[index1].operand1 =a;
arr[index1].operand2 = b;
arr[index1].operator = o;
arr[index1].result=temp;
index1++;
return temp;
}
void threeAdd(){
int i=0;
char temp='A';
while(i<index1){
printf("%c:=\t",arr[i].result);
printf("%c\t",arr[i].operand1);
printf("%c\t",arr[i].operator);
printf("%c\t",arr[i].operand2);
i++;
temp++;
printf("\n");
}
}
void fouradd(){
int i=0;
char temp='A';
while(i<index1){
28
CS3501-COMPILER DESIGN LABORATORY
printf("%c\t",arr[i].operator);
printf("%c\t",arr[i].operand1);
printf("%c\t",arr[i].operand2);
printf("%c",arr[i].result);
i++;
temp++;
printf("\n");
}
}
int find(char l){
int i;
for(i=0;i<index1;i++)
if(arr[i].result==l) break;
return i;
}
void triple(){
int i=0;
char temp='A';
while(i<index1){
printf("%c\t",arr[i].operator);
if(!isupper(arr[i].operand1))
printf("%c\t",arr[i].operand1);
else{
printf("pointer");
printf("%d\t",find(arr[i].operand1));
}
if(!isupper(arr[i].operand2))
printf("%c\t",arr[i].operand2);
else{
printf("pointer");
printf("%d\t",find(arr[i].operand2));
}
29
CS3501-COMPILER DESIGN LABORATORY
i++;
temp++;
printf("\n");
}
}
int yywrap(){
return 1;
}
int main(){
printf("Enter the expression: ");
yyparse();
threeAdd();
printf("\n");
fouradd();
printf("\n");
triple();
return 0;
}

OUTPUT:
[duke@duke-pc a5]$ yacc -d yacc.y
[duke@duke-pc a5]$ lex lex.l
[duke@duke-pc a5]$ gcc y.tab.c lex.yy.c -w
[duke@duke-pc a5]$ ./a.out
Enter the expression: a=b*c+1/3-5*f;
A:= b * c
B:= 1 / 3
C:= A + B
D:= 5 * f
E:= C - D
F:= a = E
* bcA
30
CS3501-COMPILER DESIGN LABORATORY
/13B
+AB C
*5fD
-CDE
=aEF
*bc
/13
+ pointer0 pointer1
*5f
- pointer2 pointer3
= a pointer4

RESULT:
Thus, the program implementing of Generate three address code for a simple program
using LEX and YACC has been executed successfully.

31
CS3501-COMPILER DESIGN LABORATORY

You might also like