Cs3501 CD Manual
Cs3501 CD Manual
IRUNGALUR
TIRUCHIRAPALLI-621 105
Regulation 2021
LAB MANUAL
ISSUE- B
REVISION – 00
Mrs. T. Suganya,
Assistant Professor HOD/CSE PRINCIPAL
1
SRM TRP ENGINEERING COLLEGE
LAB MANUAL
REGULATIONS 2021
YEAR/SEM : III/05
STRENGTH : 65
BATCH:2021-2025 ODD
STAFF NAME : T.SUGANYA AP/CSE
2
CS3501 COMPILER DESIGN LTPC
3024
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.
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 andthe
8086 assembly language code is produced as output.
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.
3
CONTENTS
Ex.
Name of the Experiment
No.
4b VARIABLE RECOGNITION
6
TYPE CHECKING USING LEX AND YACC
4
SRM TRP Engineering College
Vision of the Institute
To carve the youth as dynamic, competent, valued and knowledgeable Technocrats through
research, innovation and entrepreneurial development for accomplishing the global
expectations.
To be recognized as Centre of Excellence for innovation and research in computer science and
engineering through the futuristic technologies by developing technocrats with ethical valuesto
serve the society at global level.
5
Program Educational Objectives (PEO's)
PEO1: Ability to analyze and get solutions in the field of Computer Science and Engineering
through application of fundamental knowledge of Mathematics, Science and Electronics
(Preparation).
PEO2: Innovative ideas, methods and techniques thereby rendering expertise to the industrial
and societal needs in an effective manner and will be a competent computer/software engineer
(Core Competency).
PEO3: Good and broad knowledge with interpersonal skills so as to comprehend, analyze,
design and create novel products and solutions for real-time applications (Breadth).
PEO4: Professional with ethical values to develop leadership, effective communication skills
and teamwork to excel in career. (Professionalism)
PEO5: Strive to learn continuously and update their knowledge in the specific fields ofcomputer
science & engineering for the societal growth. (Learning environment).
PO1: Engineering knowledge: Apply the basic knowledge of science, mathematics and
engineering fundamentals in the field of Computer Science and Engineering to solve complex
engineering problems.
PO2: Problem analysis: Ability to use basic principles of mathematics, natural sciences,
and engineering sciences to Identify, formulate, review research literature and analyze
Computer Science and engineering problems.
PO3: Design/development of solutions: Ability to design solutions for complex Computer Science
and engineering problems and basic design system to meet the desired needs within realistic
constraints such as manufacturability, durability, reliability, sustainability and economy with
appropriate consideration for the public health, safety, cultural, societal, and environmental
considerations
PO5: Modern tool usage: Ability to use state of the art of techniques, skills and modern
engineering tools necessary for engineering practice to satisfy the needs of the society with
an understanding of the limitations.
6
PO6: The Engineer and Society: Ability to apply reasoning informed by the contextual
knowledge to assess the impact of Computer Science and engineering solutions in legal, health,
cultural, safety and societal context and the consequent responsibilities relevant to the
professional engineering practice.
PO8: Ethics: Ability to understand and apply ethical principles and commitment to address
the professional ethical responsibilities of an engineer.
PO11: Project management and finance: Ability to acquire and demonstrate the
knowledge of contemporary issues related to finance and managerial skills in one’s own
work, as a member and leader in a team, to manage projects and in multidisciplinary
environments.
PO12: Life-long learning: Ability to recognize and adapt to the emerging field of application
in engineering and technology by developing self-confidence for lifelonglearning process.
PSO1:Use Data structures, Data management, Networking, System software, Data science
with high end programming skills to design and implement automation in various domains
of emerging technologies.
PSO2: Apply engineering knowledge in project development with the end products and
services in the field of hardware and software platform to accomplish the industry
expectations.
7
SRM TRP ENGINEERING COLLEGE
IRUNGALUR, TRICHY
COURSE OUTCOME
Course Competency
Outcome
CS3501.1 Un Understand the techniques in different phases of a compiler.
CS3501.2 Design a lexical analyser for a sample language and learn to use the LEX tool.
CS3501.3 Apply different parsing algorithms to develop a parser and learn to use YACC tool.
CS3501.4 Understand semantics rules (SDT), intermediate code generation and run-time
environment.
CS3501.5 Implement code generation and apply code optimization techniques.
Course Code PO1 PO2 PO3 PO4 PO5 PO6 PO7 PO8 PO9 PO10 PO11 PO12
CS3501.1 3 3 3 3 - - - - 3 3 1 3
CS3501.2 3 3 3 3 3 - - - 3 2 3 2
CS3501.3 3 3 2 2 3 - - - 3 1 1 1
CS3501.4 3 2 2 1 1 - - - 2 3 2 3
CS3501.5 3 3 3 2 1 - - - 2 1 1 3
CS3501 3.00 2.80 2.60 2.20 2.00 - - - 2.60 2.00 1.60 2.40
CO-PSO Matrices
2. The declaration section includes declaration of variables, maintest, constants and regular
definitions.
4. In linux terminal Write a program in the vi editor and save it with .l extension.
$ vi filename.l
5. In vi editor , for typing press i – insert, for saving file click esc and type :wq – write and quit
6. Compile the lex program with lex compiler to produce output file as lex.yy.c.
$ lex filename.l
10
YACC PROGRAM COMPILATION PROCEDURE
6. In vi editor , for typing press i – insert, for saving file click esc and type :wq – write and quit
7. Compile the lex program with lex compiler to produce output file as y.tab.c.
$ yacc –d filename.y
11
EX.NO:1 IMPLEMENTATION OF SYMBOL TABLE
AIM:
To write a C program to implement a symbol table while recognizing patterns in c program.
ALGORITHM:
1. Start the program.
2. Get the input from the user with the terminating symbol ‘$’.
3. Allocate memory for the variable by dynamic memory allocation function.
4. If the next character of the symbol is an operator then only the memory is allocated.
5. While reading, the input symbol is inserted into symbol table along with its memory address.
6. The steps are repeated till ‘$’ is reached.
7. To reach a variable, enter the variable to the searched and symbol table has been checked for
corresponding variable, the variable along with its address is displayed as result.
8. Stop the program.
PROGRAM:
#include <stdio.h>
#include<ctype.h>
#include<alloc.h>
#include<string.h>
#include<math.h>
void main()
{ int i=0,j=0,x=0,n,flag=0;
void *p,*add[5];
char ch,srch,b[15],d[15],c;
printf("Expression terminated by $ : ");
while((c=getchar())!='$')
{
b[i]=c; i++;
}
n=i;
printf("Given Expression : ");
i=0;
while(i<=n)
{ printf("%c",b[i]);
i++;
}
printf("\n Symbol Table\n");
printf("Symbol\taddr\ttype");
while(j<=n)
{ c=b[j];
if(isalpha(toascii(c)))
{ if(j==n)
{ p=malloc(c);
add[x]=p;
d[x]=c; 12
printf("%c\t%d\tidentifier",c,p);
}
else
{ ch=b[j+1];
if(ch=='+'||ch=='-'||ch=='*'||ch=='=')
{ p=malloc(c);
add[x]=p;
d[x]=c;
printf("\n %c \t %d \t identifier \n",c,p);
x++;
}
}
}
j++;
}
printf("\nThe symbol is to be searched");
srch=getch();
for(i=0;i<=x;i++)
{ if(srch==d[i])
{ printf("\nSymbol Found");
printf("\n%c%s%d\n",srch," @address ",add[i]);
flag=1;
}
}
if(flag==0)
printf("\nSymbol Not Found");
getch();
}
OUTPUT:
Expression terminated by $ : b+c-d $
Given Expression : b+c-d
Symbol Table
Symbol addr type
b 1900 identifier
c 2002 identifier
d 2106 identifier
The symbol is to be searched b
Symbol Found
RESULT:
Thus the program of implementation of symbol table while recognizing pattern is executed and the
output is verified.
13
EX.NO:2 LEXICAL ANALYZER TO RECOGNIZE A FEW PATTERNS IN C
AIM:
To write a C Program to implement a Lexical analyzer.
ALGORITHM:
1) Start the program.
2) Declare all the variables and file pointers.
3) Display the input program.
4) Separate the keyword in the program and display it.
5) Display the header files of the input program.
6) Separate the operators of the input program and display it.
7) Print the punctuation marks.
8) Print the constant that are present in input program.
9) Print the identifiers of the input program.
10) Stop the program
PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<string.h>
void main()
{
FILE *fp;
int i,j;
char arr[100],k;
char kw[10][10]={"int","float","double","end","main","void","include","printf","scanf"};
char hf[2][10]={"stdio.h","conio.h"};
char op[5]={'+','-','*','/','%'};
char punc[6]={'(',')','{','}',','};
fp=fopen("input.c","r");
fclose(fp);
printf("\nSymbol table\n");
fp=fopen("input.c","r");
printf("\nKeywords");
while(!feof(fp))
{
arr[0]=fgetc(fp);
fscanf(fp,"%s",arr);
for(i=0;i<10;i++)
{
if(strcmp(arr,kw[i])==0)
{
printf("\t%s",arr);
}
}
} 14
fclose(fp);
fp=fopen("input.c","r");
printf("\nHeader files");
while(!feof(fp))
{ arr[0]=fgetc(fp);
fscanf(fp,"%s",arr);
for(i=0;i<2;i++)
{
if(strcmp(arr,hf[i])==0)
{
printf("\t%s",arr);
}
}
}
fclose(fp);
fp=fopen("input.c","r");
printf("\nOperators");
while(!feof(fp))
{ arr[0]=fgetc(fp); for(i=0;i<5;i++)
{
if(arr[0]==op[i])
{
printf("\t%c",arr[0]);
}
}
}
fclose(fp);
fp=fopen("input.c","r");
printf("\npunctuation");
while(!feof(fp))
{ arr[0]=fgetc(fp); for(i=0;i<6;i++)
{
if(arr[0]==punc[i])
{
printf("\t%c",arr[0]);
}
}
}
fclose(fp);
fp=fopen("input.c","r");
printf("\nConstants");
while(!feof(fp))
{
arr[0]=fgetc(fp); if(isdigit(arr[0]))
{
printf(" %c ",arr[0]);
}
}
fclose(fp);
fp=fopen("input.c","r");
printf("\nidentifier ");
while(!feof(fp))
{ 15
fscanf(fp,"%s",arr); for(i=0;i<2;i++)
{
if(strcmp(arr,kw[i])==0)
{ fscanf(fp,"%s",arr);
j=0;
while(j<strlen(arr) && arr[j]!=';')
{
printf("%c",arr[j]); j++;
}
}
}
}
fclose(fp);
getch();
}
INPUT: (input.c)
#include<stdio.h>
#include<conio.h>
void main()
{
int a,b,c;
a=10;
b=5;
c=a+b;
printf(“The sum is %d”,c);
getch();
}
OUTPUT:
Symbol table
Keywords void int
Header files
Operators + %
punctuation ( ) { , , ( , )
( ) }
Constants 1 0 5
identifier a,b,c
RESULT:
Thus the program to implement a Lexical analyzer is executed and the required output is verified.
16
EX.NO:3 IMPLEMENTATION OF LEXICAL ANALYZER USING LEX TOOL
AIM:
To implement Lexical Analyzer using Lex Tool.
ALGORITHM:
1. 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:
declaration %% rules %% auxiliary function or subroutine
2. Declare C variable, include c files in %{ .. %} section
3. The patterns like keyword, identifiers, constants, etc., and its associated actions written inside { .. }
are defined in rule section
4. The subroutine main( ) read the C file in read mode and store in into a yyin file pointer variable. If
not exist, show error.
5. In subroutine section, main routine calls yylex(). yywrap() is used to get more input.
6. 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.
7. The action rule defined for each pattern will be applied while match is performed with c program
8. The patterns identified are stored in symbol table for the next phase of compiler.
9. The lex generate lex.yy.c , then it is compiled with c compiler to generate output
10. Display the result and stop the execution
PROGRAM:
%{
int *a;
%}
identifier [a-zA-Z][a-zA-Z0-9]*
%%
#.* {printf("\n\t%s preproc directive\t -",yytext);}
int | float | char | double | while | for | struct | typedef | do | if |
else | break | continue | void | switch | return |
goto {printf("\n\t%s \t\t keyword",yytext);}
"/*" {printf("\n\t %s \t\t COMMENT",yytext);}
{identifier}\( {printf("\n \t%s)\t\t FUNCTION",yytext);}
\{ {printf("\n BLOCK BEGINS");}
\} {printf("BLOCK ENDS ");}
{identifier}(\[[0-9]*\])? {a=malloc(sizeof(yytext)); printf("\n\t %s \t\t IDENTIFIER \t
%d",yytext,a);}
\".*\" {printf("\n\t %s \t\t STRING",yytext);}
[0-9]+ { printf("\n %s \t\t NUMBER ",yytext);}
\) {printf("");}
\( ECHO;
= {printf("\n\t %s \t\t ASSIGNMENT OPERATOR",yytext);}
\<= | \>= | \< | == | \> {printf("\n\t%s \t\t RELATIONAL OPERATOR",yytext);}
\+ {printf("\n\t %s \t\t ARITHMETIC OPERATOR",yytext);}
%%
int main(int argc, char **argv)
{
FILE *file;
file=fopen("var.c","r"); 17
if(!file)
{printf("could not open the file");
exit(0);
}
yyin=file;
printf("\n\t**********SYMBOL TABLE*************\n");
printf("\n\tSymbol\t\t Type \t\t Address\n");
yylex();
printf("\n");
return(0);
}
int yywrap()
{
return(1);
}
INPUT (var.c):
#include<stdio.h>
int main()
{ int a,b,c;
c=a+b;
printf("hai");
}
OUTPUT:
[cse02@localhost cse02]$ lex lex1.l
[cse02@localhost cse02]$ cc lex.yy.c
[cse02@localhost cse02]$ ./a.out area.c
**********SYMBOL TABLE*************
Symbol Type Address
#include<stdio.h> preproc directive -
int keyword
main() FUNCTION
BLOCK BEGINS
int keyword
a IDENTIFIER 1446992,
b IDENTIFIER 1447024,
c IDENTIFIER 1447056;
c IDENTIFIER 1447088
= ASSIGNMENT OPERATOR
a IDENTIFIER 1447120
+ ARITHMETIC OPERATOR
b IDENTIFIER 1447152;
printf() FUNCTION
"hai" STRING;
BLOCK ENDS
RESULT:
Thus the program to implement Lexical Analyzer using Lex Tool is executed and the required
output is verified.
18
EX.NO:4 a. ARITHMETIC EXPRESSION RECOGNITION
AIM:
To write a yacc program to recognize a valid arithmetic expression that uses operator +, - , * and /.
ALGORITHM
1. Using vi editor, type the yacc program and save the file with .y extension
2. Define the rules for operators in YAAC specification.
3. The rules section defines the rules that parse the input stream. Each rule of a grammar production
and the associated semantic action.
4. In the yylex() function get the input expression and separate the tokens
5. Then identify the arithmetic operators and perform its operation accordingly otherwise returns the
error using yyerror() function.
PROGRAM
$ vi y1.y
%{
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
#define YYSTYPE double
%}
%token num
%left '+' '-'
%left '*' '/'
%%
Stmt: Stmt '\n' {printf("Value is %f\n",$1); exit(0);}
| Expr
|
| error '\n' {printf("Invalid"); exit(0);}
;
Expr: num { $$=$1; }
| Expr '+' Expr { $$=$1+$3; }
| Expr '-' Expr { $$=$1-$3; }
| Expr '*' Expr { $$=$1*$3; }
| Expr '/' Expr {
if($3==0)
{
printf("Division by zero\n");
exit(0);
}
else
$$=$1/$3;
}
| '(' Expr ')' { $$=$2;}
;
%%
main() 19
{
printf("Enter an expression to evaluate:\n");
yyparse();
}
yyerror(char *s)
{
printf("%s",s);
}
yylex()
{
char ch; while((ch=getchar())==' '); if(isdigit(ch)|ch=='.')
{
ungetc(ch,stdin); scanf("%lf",&yylval); return num;
}
return ch;
}
OUTPUT:
[cse02@localhost cse02]$ yacc -d y1.y
[cse02@localhost cse02]$ cc y.tab.c -ll
[cse02@localhost cse02]$ ./a.out
Enter an expression to evaluate:
2+3
Value is 5.000000
[cse02@localhost cse02]$ ./a.out
Enter an expression to evaluate:
10-9
Value is 1.000000
[cse02@localhost cse02]$ ./a.out
Enter an expression to evaluate:
3*4
Value is 12.000000
[cse02@localhost cse02]$ ./a.out
Enter an expression to evaluate:
10/2
Value is 5.000000
[cse02@localhost cse02]$ ./a.out
Enter an expression to evaluate:
190/0
Division by zero
[cse02@localhost cse02]$
RESULT
Thus the program to recognize a valid arithmetic expression that uses operator +, - , * and / is
executed and the required output is verified.
20
EX.NO:4. b VARIABLE RECOGNITION
AIM:
To write a yacc program to recognize a valid variable which starts with a letter followed by any
number of letters or digits.
ALGORITHM
1. Using vi editor, type the yacc program and save the file with .y extension
2. Declare C declaration such as header file inclusion, variable declaration, etc., in yacc declaration
part
3. Specify necessary tokens in declaration part to recognize variable as follows
%token <token name> <token name>
4. The rules section defines the rules that parse the input stream. Each rule of a grammar production
and the associated semantic action.
5. yyparse() reads a stream of token/value pairs from yylex(), which needs to be supplied.
6. In the yylex() function get the input variable and defines the variable as valid or not.
7. The isalpha() returns true, if the input is letter
8. The isdigit returns true, if the input is digit
9. The output of the program is to define valid variable according to the rule
letter(letter/digit)*.
10. If not valid variable, the yyerror() shows error message
PROGRAM
%{
#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>
%}
%token let dig
%%
main()
{
printf("Enter a variable:");
yyparse();
}
yylex()
{ 21
char ch; while((ch=getchar())==' ');
if(isalpha(ch))
return let;
if(isdigit(ch))
return dig;
return ch;
}
yyerror(char *s)
{
printf("%s",s);
}
OUTPUT
RESULT
Thus the program to recognize a valid variable which starts with a letter followed by any
number of letters or digits is executed and the required output is verified.
22
EX.NO:4. c. CONTROL STRUCTURES RECOGNITION
AIM:
To write a yacc program to recognize a valid control structures syntax of C language (FOR Loop
Statements)
ALGORITHM:
1. Using vi editor, type the lex, yacc program and save the file with .l, .y extension respectively.
2. Define the alpha, digit rules in declaration part, specify the action in rule part of lex program
which will be invoked by yacc program.
3. In the YAAC program define the rules for the control structure for, relational operator and
expression evaluation.
4. In the main function get the expression and parse it.
5. The expression evaluated by the program and produce the output as whether the for loop
statement is valid or not.
6. Display the result.
PRAGRAM:
// Lex file: for.l
alpha [A-Za-z]
digit [0-9]
%%
[\t \n]
for return FOR;
{digit}+ return NUM;
{alpha}({alpha}|{digit})* return ID;
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
. return yytext[0];
%%
// Yacc file: for.y
%{
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM FOR LE GE EQ NE OR AND
%right "="
%left OR AND
%left '>' '<' LE GE EQ NE
%left '+' '-'
%left '*' '/'
%right UMINUS
%left '!'
%% 23
E : ID '=' E
| E '+' E | E '-' E | E '*' E | E '/' E | E '<' E | E '>' E
| E LE E | E GE E | E EQ E | E NE E
| E OR E | E AND E | E '+' '+' | E '-' '-'
| ID | NUM
;
E2 : E'<'E
| E'>'E | E LE E | E GE E | E EQ E
| E NE E | E OR E | E AND E
;
%%
#include "lex.yy.c"
main() {
printf("Enter the expression:\n");
yyparse();
}
OUTPUT:
[cse02@localhost cse02]$ lex for.l
[cse02@localhost cse02]$ yacc for.y
conflicts: 25 shift/reduce, 4 reduce/reduce
[cse02@localhost cse02]$ cc y.tab.c -ll -ly
[cse02@localhost cse02]$./a.out
Enter the expression:
for(i=0;i<n;i++)
i=i+1;
Input accepted
[cse02@localhost cse02]$
RESULT:
Thus the program to recognize a valid control structures syntax of C language (FOR Loop
Statements) is executed and the required output is verified.
24
EX.NO: 4. d. CALCULATOR USING LEX AND YACC
AIM:
To write a program to implement calculator using lex and yacc.
ALGORITHM:
1. Start the program.
Yacc source program has three parts as follows:
Declarations
%%
translation rules
%%
supporting C routines
2. Declarations Section:
This section contains entries that:
vi. Include standard I/O header file.
vii. Define global variables.
viii. Define the list rule as the place to start processing.
ix. Define the tokens used by the parser.
x. Define the operators and their precedence.
3. Rules Section:
The rules section defines the rules that parse the input stream. Each rule of a grammar
production and the associated semantic action.
4. 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.
5. Main- The required main program that calls the yyparse subroutine to start the program.
6. yyerror(s) -This error-handling subroutine only prints a syntax error message.
7. yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs.
8. The calc.lex file contains include statements for standard input and output, as programmer file
information if we use the -d flag with the yacc command.
9. The y.tab.h file contains definitions for the tokens that the parser program uses.
10. calc.lex contains the rules to generate these tokens from the input stream.
PROGRAM:
\\cal.l
%{
#include<stdio.h>
#include"y.tab.h"
int c;
extern int yylaval;
%}
%%
"";
[a-z]
{ c=yytext[0]; yylaval=c-'a'; return(LETTER);
} 25
[0-9]
{ c=yytext[0];
yylaval=c-'0'; return(DIGIT);
}
[a-z0-9/b]{ c=yytext[0]; return(c);
}
\\cal.y
%{
#include<stdio.h>
int regs[26];
int base;
%}
%start list
%token DIGIT LETTER
%left'|'
%left'&'
%left'+''-'
%left'*''/''%'
%left UMINUS
%%
list:
|
list stat'\n'
|
list error'\n'
{
yyerror();
};
stat:expr
{
printf("%d\n",$1);
}
| LETTER'='expr
{
regs[$1]=$3;
};
expr:'('expr')'
{
$$=$2;
}
|
expr'*'expr
{
$$=$1*$3;
}
|
expr'/'expr
{
$$=$1/$3;
}
|
expr'%'expr
{ 26
$$=$1%$3;
}
|
expr'+'expr
{
$$=$1+$3;
}
|
expr'-'expr
{
$$=$1-$3;
}
|
expr'&'expr
{
$$=$1&$3;
}
|
expr'|'expr
{
$$=$1|$3;
}
|
'-'expr%prec UMINUS
{
$$=-$2;
}
|
LETTER
{
$$=regs[$1];
}
|
number
;
number:DIGIT
{
$$=$1;
base=($1==0)?8:10;
}
|
number DIGIT
{
$$=base*$1+$2;
}
%%
main()
{
return(yyparse());
}
yyerror(s)
char*s;
{ 27
fprintf(stderr,"%s\n",s);
}
yywrap()
{
return(1);
}
OUTPUT:
[cse02@localhost cse02]$ lex cal.l
[cse02@localhost cse02]$yacc –d cal.y
[cse02@localhost cse02]$cc y.tab.c lex.yy.c-ll-lm-ly
[cse02@localhost cse02]$./a.out
10+20
30
50-20
30
14/2
7
RESULT:
Thus the program to implement calculator using lex and yacc is executed and the required output is
verified.
28
EX.NO: 5. THREE ADDRESS CODE GENERATION USING LEX AND YACC
AIM:
To write a lex and yacc program to generate three address code for a simple expression using lex
and yacc
ALGORITHM:
1. Start the program.
Yacc source program has three parts as follows:
Declarations
%%
translation rules
%%
supporting C routines
2. 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.
3. Rules Section:
The rules section defines the rules that parse the input stream. Each rule of a grammar
production and the associated semantic action.
4. 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.
5. Main- The required main program that calls the yyparse subroutine to start the program.
6. yyerror(s) -This error-handling subroutine only prints a syntax error message.
7. yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs.
8. The three.l file contains include statements and declare pattern for number and letter.
9. The y.tab.h file contains definitions for the tokens that the parser program uses.
10. The three.y contains the rules to generate three address code. It takes an expression as input and store
the operands and operator into the table.
11. Based on the rule defined, the given expression is converted in to three address code
PROGRAM:
//three.l
%{
#include"y.tab.h"
%}
%%
int i=0;
while(i<index1){
printf("t%c:=\t",arr[i].result);
if(isalpha(arr[i].operand1))
printf("%c\t",arr[i].operand1);
else
printf("t%c\t",arr[i].operand1);
printf("%c\t",arr[i].operator);
if(isalpha(arr[i].operand2))
printf("%c\t",arr[i].operand2);
else
printf("t%c\t",arr[i].operand2);
i++;
temp++;
printf("\n");
}
}
int main(){
printf("Enter the expression: ");
yyparse();
threeAdd();
return 0;
}
OUTPUT:
[cse02@localhost cse02]$ lex three.l
[cse02@localhost cse02]$yacc –d three.y
[cse02@localhost cse02]$gcc y.tab.c lex.yy.c -w
[cse02@localhost cse02]$./a.out
RESULT:
Thus the program to generate three address code for a simple program using lex and yacc is
executed and the required output is verified.
31
EX.NO: 6 TYPE CHECKING USING LEX AND YACC
AIM:
To write a program to identify type declaration using lex and yacc.
ALGORITHM:
1. Start the program.
Yacc source program has three parts as follows:
Declarations
%%
translation rules
%%
supporting C routines
2. 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.
3. Rules Section:
The rules section defines the rules that parse the input stream. Each rule of a grammar
production and the associated semantic action.
4. 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.
5. Main- The required main program that calls the yyparse subroutine to start the program.
6. yyerror(s) -This error-handling subroutine only prints a syntax error message.
7. yywrap -The wrap-up subroutine that returns a value of 1 when the end of input occurs.
8. The typech.l file contains include statements and declare the basic type and identifier.
9. The y.tab.h file contains definitions for the tokens that the parser program uses.
10. The typech.y contains the rules to identify the correct declaration of input based on defined expression,
if not, it shows an error.
PROGRAM:
\\typech.l
%{
#include<stdio.h>
#include"y.tab.h"
int yylval;
%}
%%
int|float {return type;}
[a-zA-Z][a-zA-Z0-9]* {return ID;}
[\t];
[\n] {return 0;}
. {return yytext[0];}
%% 32
yywrap()
{
return 1;
}
\\typech.y
%{
#include<stdio.h>
int flag=0;
%}
%token type ID
%%
D:T' 'L';' {flag++;}
T:type;
L:L','ID|ID;
%%
main()
{
printf("enter the expression for the grammar\n");
yyparse();
if(flag)
{
printf("\n valid type declaration");
}
}
void yyerror()
{
printf("\n type Mismatch");
}
OUTPUT:
[cse02@localhost cse02]$ lex typech.l
[cse02@localhost cse02]$yacc –d typech.y
[cse02@localhost cse02]$gcc y.tab.c lex.yy.c -w
[cse02@localhost cse02]$./a.out
enter the expression for the grammar
int a,b,c;
RESULT:
Thus the program to implement type checking using Lex and Yacc is executed and the
required output is verified.
33
EX.NO: 7. SIMPLE CODE OPTIMIZATION TECHNIQUES (CONSTANT FOLDING,
STRENGTH REDUCTION AND ALGEBRAIC TRANSFORMATION)
AIM:
To write a C program to implement simple code optimization techniques (Constant folding,
Strength reduction and Algebraic transformation)
ALGORITHM:
1. Start the program
2. Enter the input as an intermediate code
3. Perform the common sub expression elimination and dead code elimination.
Dead code elimination
Eliminates code that cannot be reached or where the results are not subsequently used.
Common sub expression elimination
In common expressions, the same value is recalculated in a subsequent expression. The duplicate
expression can be eliminated by using the previous value.
4.Display the code after the optimization.
5.Stopthe program.
PROGRAM:
#include<stdio.h>
#include<conio.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; clrscr();
printf("Enter the Number of Values:");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("left: ");
op[i].l=getche(); printf("\tright: ");
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++) 34
{
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)
{
a=l-pr[i].r; printf("pos: %d",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'; strcpy(pr[i].r,'\0');
} 35
}
}
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);
}
}
getch();
}
OUTPUT:
RESULT:
Thus the program to implement simple code optimization techniques (Constant folding, Strength
reduction and Algebraic transformation) is executed and the –required output is verified.
36
EX.NO: 8. BACK END COMPILER FOR THE 8086
AIM:
Write a C program to 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.
ALGORITHM:
1.Give the structure declaration for a Quadruple table.
2.Open a input intermediate file in the read mode and assign to a File pointer called src.
3.Open a output machine code file in the write mode and assign to a File pointer called dest.
4.Read the input file record by record.
5.Make the Quadtable entries whenever expressions are recognized.
6.Generate the machine code for the ADD, SUB, MUL, DIV statements.
7.Then generate the code after moving the operands from the Quadtable to the appropriate registers.
8.Perform the suitable arithmetic operations on the operands and move the results to the final destination
register.
PROGRAM:
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
void main(){
int i=2,j=0,k=2,k1=0;
char ip[10],kk[10]; FILE *fp;
clrscr();
printf("\nEnter the filename of the intermediate code");
scanf("%s",&kk);
fp=fopen(kk,"r");
if(fp==NULL)
{
printf("\nError in Opening the file");
getch();
}
clrscr();
while(!feof(fp))
{
fscanf(fp,"%s\n",ip);
printf("\t\t%s\n",ip); }
rewind(fp);
printf("\n------------------------------\n");
printf("\tStatement \t\t target code\n");
printf("\n------------------------------\n");
while(!feof(fp))
{
fscanf(fp,"%s",ip);
printf("\t%s",ip);
printf("\t\tMOV %c,R%d\n\t",ip[i+k],j);
if(ip[i+1]=='+') 37
printf("\t\tADD");
else
printf("\t\tSUB");
if(islower(ip[i]))
printf("%c,R%d\n\n",ip[i+k1],j);
else printf("%c,%c\n",ip[i],ip[i+2]);
j++;
k1=2;
k=0;
}
printf("\n-------------------------------\n");
getch();
fclose(fp);
}
OUTPUT:
Enter the filename of the intermediate code: k.txt
X=a-b
Y=a-c
Z=A+B
C=A-B
C=A-B
------------------------------------------------------------
Statement target code
------------------------------------------------------------
X=a-b MOV b,R0
SUBa,R0
Y=a-c MOV a,R1
SUBc,R1
Z=A+B MOV A,R2
ADDA,B
C=A-B MOV A,R3
SUBA,B
C=A-B MOV A,R4
SUBA,B
RESULT:
Thus the program to implement back-end of the compiler for which the three address
code is given as input and the 8086 assembly language code is executed and the –required output is verified
38
EX.NO: 9. IMPLEMENTATION OF SIMPLE CODE OPTIMIZATION TECHNIQUES
AIM:
To write a C program to implement simple code optimization technique.
INTRODUCTION:
Optimization is a program transformation technique, which tries to improve the code by making it
consume less resource (i.e. CPU, memory) and deliver high speed.
In optimization, high-level general programming constructs are replaced by very efficient low level
programming codes. A code optimizing process must follow the three rules given below:
The output code must not, in any way, change the meaning of the program.
Optimization should increases the speed of the program and if possible, the program
should demand less number of resources.
Optimization should itself be fast and fast and should not delay the overall compiling
process.
Efforts for an optimized code can be made at various levels of compiling the process.
At the beginning, users can change/rearrange the code or use better algorithms to write
the code.
After generating intermediate code, the compiler can modify the intermediate code by
address calculations and improving loops.
While producing the target machine code, the compiler can make use of memoryhierarchy
and cpu registers.
Optimization can be categorized broadly into two types: Machine independent and Machine
dependent.
In this optimization, the compiler takes in the intermediate code and transforms a part of the code
that does not involve any CPU registers and/or absolute memory locations.
For example
do
{
item=10;alue=value+item;
}while(value<100)
This code involves repeated assignment of the identifier item, which if we put this way:
item=10;do
39
{
value=value+item;
}while(value<100);
Should not only save the cpu cycles, but can be used on any processor.
Machine dependent optimization is done after the target code has been generated and whenthe
code is transformed according to the target machine architecture. It involves CPU registers and may
have absolute memory references rather than relative references. Machine- dependent optimizers
put efforts to take maximum advantage of memory hierarchy.
ALGORITHM:
Before:
Using for :
#include<iostream.h>
{
int i, n; int
fact=1;
cin>>n;
for(i=n;i>=1;i--)
fact=fact *i;
return 0;
}
After: (SIMPLE CODE OPTIMIZATION TECHNIQUE)
Using do-while:
#include<iostream.h>
#include<conio.h>void
main()
clrscr();int n,f;
f=1;
do
f=f*n;n--;
}while(n>0);
OUTPUT:
41
RESULT: