0% found this document useful (0 votes)
9 views

CS3501 Compiler Design Laboratory Record

The document outlines the laboratory record for the CS3501 Compiler Design Laboratory for the academic year 2024-2025, including the vision and mission of the institute and department. It details program outcomes, specific objectives, and educational goals for students in Computer Science and Engineering. Additionally, it provides a list of experiments and sample programs related to lexical analysis and syntax validation using tools like LEX and YACC.

Uploaded by

e22cs056
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)
9 views

CS3501 Compiler Design Laboratory Record

The document outlines the laboratory record for the CS3501 Compiler Design Laboratory for the academic year 2024-2025, including the vision and mission of the institute and department. It details program outcomes, specific objectives, and educational goals for students in Computer Science and Engineering. Additionally, it provides a list of experiments and sample programs related to lexical analysis and syntax validation using tools like LEX and YACC.

Uploaded by

e22cs056
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/ 44

Pullipalayam, Morur (Po.), Sankari (Tk.), Salem (Dt.

) - 637 304

DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING

LAB RECORD

CS3501 – COMPILER DESIGN LABORATORY


ODD SEMESTER AY:2024-2025
(REGULATION-2021)

NAME OF THE STUDENT:

REGISTER NUMBER :

\ YEAR/SEM :

COURSE/BRANCH :
RECORD NOTEBOOK

REGISTER NUMBER: .……………………..…………………

Certified that this is a Bonafide record of Practical work done by Mr. /Ms. ..................................................

of the .............................Semester ................................................................................. Branch during the

Academic year …................................ in the………………………………………………………..

Laboratory.

Submitted for the University Practical Examination held on………….………….

Signature of Staff In-charge Signature of Head of Department

INTERNAL EXAMINER EXTERNAL EXAMINER


VISION AND MISSION OF THE INSTITUTE
VISION
To be an Institute of repute in the field of Engineering and Technology by implementing the best
educational practices akin to global standards for fostering domain knowledge and developing
research attitude among students to make them globally competent.

MISSION
• Achieving excellence in Teaching Learning process using state-of-the-art resources
• Extending opportunity to upgrade faculty knowledge and skills.
• Implementing the best student training practices for requirements of industrial scenario of the state
• Motivating faculty and students in research activity for real time application

VISION AND MISSION OF THE DEPARTMENT


VISION
To create the holistic environment for the development of Computer Science and Engineering Graduates
employable at the global level and to mold them through comprehensive educational programs and quality
research for developing their competency and innovation with moral values

MISSION
M1 Ensuring academic growth by way of establishing centers of excellence and promoting
collaborative learning

M2 Promoting research-based projects in the emerging areas of technology convergence for the benefit
of students and faculty

M3 Motivating the students to be successful, ethical and suitable for industry ready
Program Outcomes (POs):
PO1 Engineering knowledge: Apply the knowledge of mathematics, science, engineering
fundamentals and an engineering specialization to the solution of complex engineering problems.

PO2 Problem analysis: Identify, formulate, review research literature, and analyze complex
engineering problems reaching substantiated conclusions using first principles of mathematics, natural
sciences and engineering sciences.

PO3 Design/development of solutions: Design solutions for complex engineering problems and
design system components or processes that meet the specified needs with appropriate consideration
for the public health, safety, cultural, societal and environmental considerations.

PO4 Conduct investigations of complex problems: Use research-based knowledge and research
methods including design of experiments, analysis, and interpretation of data and synthesis of the
information to provide valid conclusions.

PO5 Modern tool usage: Create, select, apply appropriate techniques, resources, modern
engineering and IT tools including prediction and modeling to complex engineering activities with an
understanding of the limitations.

PO6 The engineer and society: Apply reasoning informed by the contextual knowledge to assess
societal, health, safety, legal, cultural issues and the consequent responsibilities relevant to the
professional engineering practice.
PO7 Environment and sustainability: Understand the impact of the professional engineering
solutions in societal, environmental contexts, demonstrate the knowledge and need for sustainable
development.

PO8 Ethics: Apply ethical principles, commit to professional ethics, responsibilities and norms of
the engineering practice.

PO9 Individual and team work: Function effectively as an individual, as a member or leader in
diverse teams and in multidisciplinary settings.

PO10 Communication: Communicate effectively on complex engineering activities with the


engineering community with society at large being able to comprehend, write effective reports,
design documentation, make effective presentations and receive clear instructions.

PO11 Project management and finance: Demonstrate knowledge, understanding of the engineering
and management principles and apply these to one’s own work, as a member and leader in a team, to
manage projects and in multidisciplinary environments.

PO12 Life-long learning: Recognize the need, ability to engage in independent and life-long
learning in the broadest context of technological change.

Program Specific Objectives (PSOs)


PSO1 –To design and develop biomedical healthcare devices that reduces physician burnout and
enhance the quality of life for the end user by applying fundamentals of Biomedical Engineering.

PSO2 – To apply software skills in developing algorithms for solving healthcare related problems in
various fields of medical sector.

PSO3 – To adapt to emerging information and communication technologies (ICT) for current societal
and scientific issues thereby developing indigenous medical instruments that are on par with the
existing biomedical technology.

Program Educational Objective (PEOs)


PEO1 – To enable the graduates to demonstrate their skills in solving challenges in their chosen field
throughthe core foundation and knowledge acquired in engineering and biology.

PEO2 – To enable the graduates to exhibit leadership, make decisions with societal and ethical
responsibilities, function and communicate effectively in multidisciplinary settings.

PEO3 – To ensure that graduates will recognize the need for sustaining and expanding their technical
competence and engage in learning opportunities throughout their careers.
LIST OF EXPERIMENT

S.
DATE EXPERIMENT PAGE MARKS SIGNATURE
NO
NO.

Using the LEX tool, Develop a lexical analyzer to


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

2 Implement a Lexical Analyzer using LEX Tool

Generate YACC specification for a few syntactic


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

Program to recognize a valid variable which starts


3b with a letter followed by any number of letters or
digits.

3c Implementation of calculator using LEX and YACC

Generate three address code for a simple program


4
using LEX and YACC.

5 Implement type checking using Lex and Yacc.

Implement simple code optimization techniques


6 (Constant folding, Strength reduction and Algebraic
transformation)

Implement back-end of the compiler for which the


7 three address code is given as input and the 8086
assembly language code is produced as output.
Ex.No1:
Date:

Develop a lexical analyzer to recognize a few patterns in C. (Ex. identifiers, constants,


comments, operators etc.). Create a symbol table, while recognizing identifiers.

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:

#include<stdio.h>

#include<ctype.h>

#include<string.h>

int main()

FILE *fi,*fo,*fop,*fk;

int flag=0,i=1;
char c,t,a[15],ch[15],file[20];

printf("\n Enter the File Name:");

scanf("%s",&file);

fi=fopen(file,"r");

fo=fopen("inter.c","w");

fop=fopen("oper.c","r");

fk=fopen("key.c","r");

c=getc(fi);

while(!feof(fi))

if(isalpha(c)||isdigit(c)||(c=='['||c==']'||c=='.'==1))

fputc(c,fo);

else

if(c=='\n')

fprintf(fo,"\t$\t");

else fprintf(fo,"\t%c\t",c);

c=getc(fi);

fclose(fi);

fclose(fo);

fi=fopen("inter.c","r");

printf("\n Lexical Analysis");

fscanf(fi,"%s",a);
printf("\n Line: %d\n",i++);

while(!feof(fi))

if(strcmp(a,"$")==0)

printf("\n Line: %d \n",i++);

fscanf(fi,"%s",a);

fscanf(fop,"%s",ch);

while(!feof(fop))

if(strcmp(ch,a)==0)

fscanf(fop,"%s",ch);

printf("\t\t%s\t:\t%s\n",a,ch);

flag=1;

} fscanf(fop,"%s",ch);

rewind(fop);

fscanf(fk,"%s",ch);

while(!feof(fk))

if(strcmp(ch,a)==0)

fscanf(fk,"%k",ch);
printf("\t\t%s\t:\tKeyword\n",a);

flag=1;

fscanf(fk,"%s",ch);

rewind(fk);

if(flag==0)

if(isdigit(a[0]))

printf("\t\t%s\t:\tConstant\n",a);

else

printf("\t\t%s\t:\tIdentifier\n",a);

flag=0;

fscanf(fi,"%s",a); }

return 0;

Key.c

int

void

main

char

if

for
while

else

printf

scanf

FILE

Oper.c

( open para

) closepara

{ openbrace

} closebrace

< lesser

> greater

" doublequote ' singlequote

: colon

; semicolon

# preprocessor

= equal

== asign

% percentage

^ bitwise

& reference

* star

+ add

- sub

\ backslash
/ slash

input.c

#include "stdio.h"

#include "conio.h"

void main()

int a=10,b,c;

a=b*c;

getch();

Output
Enter the File Name:input.c

Lexical Analysis

Line: 1

# : preprocessor

include : Identifier

" : doublequote

stdio.h : Identifier

" : doublequote

Line: 2

# : preprocessor

include : Identifier

" : doublequote

conio.h : Identifier

" : doublequote
Line: 3

void : Keyword

main : Keyword

( : open

) : closepara

Line: 4

{ : openbrace

Line: 5

int : Keyword

a : Identifier

= : equal

10 : Constant

, : Identifier

b : Identifier

, : Identifier

c : Identifier

; : semicolon

Line: 6

a : Identifier

= : equal

b : Identifier

* : star

c : Identifier

; : semicolon

Line: 7
getch : Identifier

( : open

) : closepara

; : semicolon

Line: 8

} : closebrace

Line: 9

$ : Identifier

Result:

Thus, the above program was executed and verified


Ex.No.2:
Date:
Implement a Lexical Analyzer using Lex Tool

AIM:
To write a program for implementing a Lexical analyzer 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 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.
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 |

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)

printf("could not open the file");

exit(0);

yyin=file;
yylex();

printf("\n");

return(0);

int yywrap()

return(1);

var.c

#include<stdio.h>

int main()

int a,b,c;

a=1;

b=2;

c=a+b;

printf("Sum:%d",c);

return 0;

Output

E:\SMDD\CD>flex ex2.l

E:\SMDD\CD>gcc lex.yy.c
E:\SMDD\CD>a.exe

#include<stdio.h> is a preprocessor directive

int is a keyword

FUNCTION

main( )

BLOCK BEGINS

int is a keyword

a IDENTIFIER,

b IDENTIFIER,

c IDENTIFIER;

a IDENTIFIER

= is an ASSIGNMENT OPERATOR

1 is a NUMBER ;

b IDENTIFIER

= is an ASSIGNMENT OPERATOR

2 is a NUMBER ;

c IDENTIFIER

= is an ASSIGNMENT OPERATOR

a IDENTIFIER+

b IDENTIFIER;

FUNCTION

printf(

"Sum:%d" is a STRING,

c IDENTIFIER

)
;

return is a keyword

0 is a NUMBER ;

BLOCK ENDS

E:\SMDD\CD>

Result:

Thus, the above program was executed and verified


Ex No : 3.a)
Date:

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

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

ALGORITHM:
Step1: Start the program.
Step2: Reading an expression.
Step3: Check the validating of the given expression according to the rule using YACY.
Step4: Using expression rule print the result of the give values.
Step5: Stop the program.

PROGRAM:
%{/* This LEX program returns thetokens for the expression */
#include “y.tab.h”%}

%%
“=”{printf(“\n Operator is EQUAL”);}
“+”{printf(“\n Operator is PLUS”);}
“-” {printf(“\n Operator is MINUS”)}
“/” {printf(“\n Operator isDIVISION”);}
“*” {printf(“\n Operator isMULTIPLICATION”);}
[a-z A-Z]*[0-9]* {
printf(“\n Identifier is %s”,yytext);
return ID;
}
return yytext[0];
\n return 0;
%%
int yywrap()
{
return 1;
}

Program Name : arith_id.y

%{#include /* This YYAC program is for recognizing the Expression */%}


%%statement: A’=’E| E {
printf(“\n Valid arithmetic expression”);
$$ = $1;};
E:E’+’ID|E’-’ID|E’*’ID|E’/’ID|ID;
%%
extern FILE *yyin;
main()
{
do{yyparse();
}
while(!feof(yyin));}
yyerror(char*s)
{}

OUTPUT:
[root@localhost]# lex arith_id.1
[root@localhost]# yacc –d arith_id.y
[root@localhost]# gcc lex.yy.c y.tab.c
[root@localhost]# ./a.out
x=a+b;
Identifier is x
Operator is EQUAL
Identifier is a
Operator is PLUS
Identifier is b

Result:
Thus, the above program was executed and verified
Ex No.3.b)
Date:

Program to recognize a valid variable which starts with a letter followed by any number
of letters or digits.

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:
%{

/* This LEX program returns the tokens for the Expression */#include "y.tab.h"%}
%%
"int"{return INT;}
"float" {return FLOAT;}
"double" {return DOUBLE;}
[a-zA-Z]*[0-9]*{
printf("\n Identifier is %s",yytext);
return ID;
}
return yytext[0];
\n return 0;
int yywrap()
{
return 1;
}

Program name: variable_test.y

%{
#include
/* This YACC program is for recognising the Expression*/
%}
%token ID INT FLOAT DOUBLE
%%
D;T L;
L:L,ID|ID;
T:INT|FLOAT|DOUBLE;

%%extern FILE *yyin;

main()
{do

{
yyparse();
}
while(!feof(yyin));
}
yyerror(char*s)
{
}

Output:
[root@localhost]# lex ariable_test.I
[root@localhost]# yacc –dvariable_test.y
[root@localhost]# gcc lex.yy.c y.tab.c
[root@localhost]# ./a.ou
tint a,b;
Identifier is a
Identifier is b[root@localhost]#

Result:

Thus, the above program was executed and verified


Ex.No. 3.c)
Date:
Implement an Arithmetic Calculator using LEX and YACC

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.

i. Define the list mile as the place to start processing.

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 purse 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.
PROGRAM :

%{

/* 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;

Calc.y

%{

/* Definition section */
#include<stdio.h>

int flag=0;

%}

%token NUMBER

%left '+' '-'

%left '*' '/' '%'

%left '(' ')'

/* Rule Section */

%%

ArithmeticExpression: E{

printf("\n Result=%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;}

%%

//driver code

void main()

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

yyparse();

if(flag==0)

printf("\n Enter arithmetic expression is Valid\n\n");

void yyerror()

printf("\n Enter arithmetic expression is Invalid\n\n");

flag=1;

Output
Microsoft Windows [Version 10.0.22621.1265]
(c) Microsoft Corporation. All rights reserved.

E:\SMDD\CD>flex cal.l
E:\SMDD\CD>bison calc.y
E:\SMDD\CD>gcc lex.yy.c y.tab.c -w
E:\SMDD\CD>a.exe

Enter Any Arithmetic Expression which can have operations Addition, Subtraction,
Multiplication, Division, Modulus and Round brackets:
10+5

Result=15

Entered arithmetic expression is Valid

E:\SMDD\CD>

Result:

Thus, the above program was executed and verified


Ex. No. 4
Date:
Generate three address code for a simple program using LEX and YACC
(Implementing Three Address Code)

AIM:
To convert the given input of BNF rules into Yacc form and to generate a Abstract
Syntax Tree.

ALGORITHM:
Step 1: Start the program.
Step 2: Include the necessary header files.
Step 3: Separate the identifier and the numbers.
Step 4: Use conditions to print the keywords using the lex file.
Step 5: Create a structure and use the variables separately for operands, arguments and
results.
Step 6: Use a stack top push and pop all the contents of the input file to the output screen.
Step 7: Use the file functions to read the input from a file. Step 8: Use string functions to
operate on.
Step 9: Terminate the program

PROGRAM:
%{
#include
#include
#include “y.tab.h”
%}
%%
[0-9]+ {yylval.dval=atoi(yytext);return NUM;}
[t];
n return 0;
. {return yytext[0];}
%%
void yyerror(char *str)
{
printf(“n Invalid Character…”);
}
int main()
{
printf(“Enter Expression x => “);
yyparse();
return(0);
}

********************** threee.y ***********************


%{
#include
int yylex(void);
char p=’A’-1;
%}
%union
{
char dval;
}
%token NUM
%left ‘+’ ‘-‘
%left ‘*’ ‘/’
%nonassoc UMINUS
%type S
%type E
%%
S : E {printf(” x = %cn”,$$);}
;
E : NUM {}
| E ‘+’ E {p++;printf(“n %c = %c + %c “,p,$1,$3);$$=p;}
| E ‘-‘ E {p++;printf(“n %c = %c – %c “,p,$1,$3);$$=p;}
| E ‘*’ E {p++;printf(“n %c = %c * %c “,p,$1,$3);$$=p;}
| E ‘/’ E {p++;printf(“n %c = %c / %c “,p,$1,$3);$$=p;}
| ‘(‘E’)’ {$$=p;}
| ‘-‘ E %prec UMINUS {p++;printf(“n %c = -%c “,p,$2);$$=p;}
;
%%

OUTPUT:
[a40@localhost ~]$ lex threee.l
[a40@localhost ~]$ yacc -d threee.y
[a40@localhost ~]$ cc lex.yy.c y.tab.c -ll
[a40@localhost ~]$ ./a.out
Enter Expression x => 1+2-3*3/1+4*5
A = 1+2
B = 3*3
C = B/1
D = A-C
E = 4*5
F = D+E
X=F
[a40@localhost ~]$ ./a.out
Enter Expression x => 1+2*(3+4)/5
A = 3+4
B = 2*A
C = B/5
D = 1+C
X=D
[a40@localhost ~]$ ./a.out
Enter Expression x => 1+2*(-3+-6/1)*3
A = -3
B = -6
C = B/1
D = A+C
E = 2*D
F = E*3
G = 1+F
X=G

Result:
Thus, the above program was executed and verified.
Ex.No:5
Date:
Implement type checking using Lex and Yacc.

AIM:
To write a 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, e.g. Bottum-up, passing the resulting
types up words.
Step3: If type found correct do the operation.
Step4: Type mismatches in semantic errors will be notified.

PROGRAM:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#define SIZE 128
#define NONE -1
#define EOS '\0'
#define NUM 257
#define KEYWORD 258
#define ID 259
#define DONE 260
#define MAX 999
char lexemes[MAX];
char buffer[SIZE];
int lastchar=-1;
int lastentry=0;
int tokenval=DONE;
int lineno=1;
int lookahead;
struct entry
{
char *lexptr;
int token;
}
symtable[100];
struct entry
keywords[]={"if",KEYWORD,"else",KEYWORD,"for",KEYWORD,"int",KEYWORD,"floa
t",KEYWORD,"double",KEYWORD,"char",KEYWORD,"struct",KEYWORD,"return",KE
YWORD,0,0};
void Error_Message(char *m)
{
fprintf(stderr,"line %d, %s \n",lineno,m);
exit(1);
}
int look_up(char s[ ])
{
int k;
for(k=lastentry;k>0;k--)
if(strcmp(symtable[k].lexptr,s)==0)
return k;
return 0;
}
int insert(char s[ ],int tok)
{
int len;
len=strlen(s);
if(lastentry+1>=MAX)
Error_Message("Symbpl table is full");
if(lastchar+len+1>=MAX)
Error_Message("Lexemes array is full");
lastentry=lastentry+1;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr=&lexemes[lastchar+1];
lastchar=lastchar+len+1;
strcpy(symtable[lastentry].lexptr,s);
return lastentry;
}
/*void Initialize()
{
struct entry *ptr;
for(ptr=keywords;ptr->token;ptr+1)
insert(ptr->lexptr,ptr->token);
}*/
int lexer()
{
int t;
int val,i=0;
while(1)
{
t=getchar();
if(t==' '||t=='\t');
else
if(t=='\n')
lineno=lineno+1;
else
if(isdigit(t))
{
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;

}
else
if(isalpha(t))
{
while(isalnum(t))
{
buffer[i]=t;
t=getchar();
i=i+1;
if(i>=SIZE)
Error_Message("Compiler error");
}
buffer[i]=EOS;
if(t!=EOF)
ungetc(t,stdin);
val=look_up(buffer);
if(val==0)
val=insert(buffer,ID);
tokenval=val;
return symtable[val].token;
}
else
if(t==EOF)
return DONE;
else
{
tokenval=NONE;
return t;
}
}
}
void Match(int t)
{
if(lookahead==t)
lookahead=lexer();
else
Error_Message("Syntax error");
}
void display(int t,int tval)
{
if(t=='+'||t=='-'||t=='*'||t=='/')
printf("\nArithmetic Operator: %c",t);
else if(t==NUM)
printf("\n Number: %d",tval);
else if(t==ID)
printf("\n Identifier: %s",symtable[tval].lexptr);
else
printf("\n Token %d tokenval %d",t,tokenval);
}
void F()

{
void E();
switch(lookahead)
{
case '(' : Match('(');
E();
Match(')');
break;
case NUM : display(NUM,tokenval);
Match(NUM);
break;
case ID : display(ID,tokenval);
Match(ID);
break;
default : Error_Message("Syntax error");
}
}
void T()
{
int t;
F();
while(1)
{
switch(lookahead)
{
case '*' : t=lookahead;
Match(lookahead);
F();
display(t,NONE);
continue;
case '/' : t=lookahead;
Match(lookahead);
display(t,NONE);
continue;
default : return;
}
}
}
void E()
{
int t;
T();
while(1)
{
switch(lookahead)
{
case '+' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
case '-' : t=lookahead;
Match(lookahead);
T();
display(t,NONE);
continue;
default : return;
}
}
}
void parser()
{
lookahead=lexer();
while(lookahead!=DONE)
{
E();
Match(';');
}
}
int main()
{
char ans[10];
printf("\n Enter the expression ");
printf("And place ; at the end\n");
printf("Press Ctrl-Z to terminate\n");
parser();
return 0;
}

##Steps to compile

gcc typechecking.c

./a.out

Output

Enter the expression And place ; at the end

Press Ctrl-Z to terminate

a+b+c

Identifier: a

Identifier: b

Arithmetic Operator: +

Identifier: c

Result:

Thus, the above program was executed and verified


Ex No. 6.
Date:

Implement simple code optimization techniques (Constant folding,


Strength reduction andAlgebraic transformation)

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 so 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 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.

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

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

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++)
{ 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 Eliminationn");
for(k=0;k<z;k++) {
printf("%ct=",pr[k].l);
printf("%sn",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');
}}}
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();
}
INPUT & OUTPUT:
Enter the Number of Values:5
left: a right: 9
left: b right: c+d
left: e right: c+d
left: f right: b+e
left: r right: f
Intermediate Code
a=9
b=c+d
e=c+d
f=b+e
r=f
nAfter Dead Code Eliminationnbt=c+dnet=c+dnft=b+enrt=fnpos: 2Eliminate Common
Expression
b =c+d
b =c+d
f =b+b
r =f
Optimized Code
b=c+d
f=b+b
r=f

Result:

Thus, the above program was executed and verified


Ex. No.7
Date:
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.

AIM:
To implement the back end of a compiler which takes the three address code and
produces the 8086 assembly language instructions using a C program.

ALGORITHM:

Step 1: Start the program


Step 2: Include the necessary header files.
Step3: Declare necessary character arrays for input and output and also a structure to include
it. Step
Step4: Get the Intermediate Code as input.
Step 5: Display the options to do the various operations and use a switch case to implement
that operation.
Step 6: Terminate the program.

PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
Void main()
{
Char icode[10][30], str[20], opr[10];
int i=0;
printf(“Enter the set of intermediate code(terminated by exit):\n”);
do
{
Scanf(“%s”,icode[i]);
}while(strcmp(icode[i++],”exit”!=0);
printf(“\n target Code Generation”);
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 MOV %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();
}

OUTPUT:
Enter the set of intermediate code(terminated by exit):
a=a*b
c=f*h
g=a*h
f=Q+w
t=q-j
exit
Target Code Generation
MOV a,R0
MUL b,R0
MOV R0,a
MOV f,R1
MUL h,R1
MOV R1,c
MOV a,R2
MUL h,R2
MOV R2,g
MOV Q,R3
ADD w,R3
MOV R3,f
MOV q,R4
SUB j,R4
MOV R4,t

Result:

Thus, the above program was executed and verified

You might also like