Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

CS8602 Compiler Lab

Download as pdf or txt
Download as pdf or txt
You are on page 1of 34

Ex No: 1 IMPLEMENTATION OF SYMBOL TABLE

MANAGEMENT

AIM:
To write a C program to implement symbol table management.
ALGORITHM:
1. Start the program for performing Create, Search, Modify and Display option in symbol
table.
2. Define the structure of the Symbol Table.
3. Enter the choice for performing the operations in the symbol table.
4. If the entered choice is 1, create the symbol table with Label name, Address, Opcode
and Operand.
5. If the the symbol is already present, it displays error message. Otherwise create the
label and the corresponding address in the symbol table.
6. If the entered choice is 2, then search the given label is present or not. If it is present to
display the corresponding label with address. Else print the Error message.
7. If the entered choice is 3, to perform modification operation in symbol table. That is to
enter the address to be modified. Then to modify the label name and operand with their
corresponding address.
8. If the entered choice is 4, then to display all the contents present in the symbol table. If
the choice is 5, then to exit the process.

PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void create();
void search();
void modify();
void display();
struct symbol
{
char label[10],address[10],value[5];
}s[10];
struct instructions
{
char address[10],label[10],opcode[10],operand[10];
}t;
intch,n=0,i,flag=0;
char a[10];
void main()
{
char a[10];
int opt;
clrscr();

ch='y';
printf("\n Symbol Table Management");
do
{
printf("1.create\n2.search\n3.modify\n4.display\n5.exit\n");
printf("\n Enter your choice\n");
scanf("%d",&opt);
switch(opt)
{
case 1:create();
break;
case 2:search();
break;
case 3:modify();
break;
case 4:display();
break;
case 5:exit(0);
break;
}
}
while(opt<5);
getch();
}
void create()
{
printf("\nEnter the address,label,opcode,operand\n");
scanf("%s%s%s%s",&t.address,&t.label,&t.opcode,&t.operand);
if(strcmp(t.label,"_")!=0)
{
flag=0;
for(i=0;i<=n;i++)
{
if(strcmp(s[i].label,t.label)==0)
{
flag=1;
break;
}
}
if(flag==0)
{
strcpy(s[n].address,t.address);
strcpy(s[n].label,t.label);
strcpy(s[n].value,t.operand);
n++;
}
else
{
printf("\nThe label is already there");
}
}
}
void search()
{
printf("\nEnter the label");
scanf("%s",&a);
for(i=0;i<=n;i++)
{
if(strcmp(a,s[i].label)==0)
{
flag=1;
break;
}
}
if(flag==1)
{
printf("\t\tlabel\taddress\tvalue\t\n");
printf("\t\t%s\t%s\t%s\n",s[i].label,s[i].address,s[i].value);
}
else
{
printf("Not Found");
}
}
void modify()
{
char a[10];
flag=0;
printf("\nEnter the label\n");
scanf("%s",&a);
for(i=0;i<=n;i++)
{
if(strcmp(a,s[i].label)==0)
{
flag=1;
break;
}
}
if(flag==0)
{
printf("\nError");
}
else
{
printf("\nEnter the address,value\n");
scanf("%s%s",&s[i].address,&s[i].value);
}
}
void display()
{
printf("\t\tlabel\taddress\tvalue\t\t\n");
for(i=0;i<=n;i++)
{
printf("\t\t%s\t%s\t%s\t\t\n",s[i].label,s[i].address,s[i].value);
}
}
OUTPUT: Label Address Value
Implementation of symbol table L1 1000 a,b
management 1.create
1.create 2.search
2.search 3.modify
3.modify 4.display
4.display 5.exit
5.exit Enter your choice:3
Enter your choice :1 Enter the label:L1
Enter the Enter the address,value
address,label,opcode,operand 2000 A,B
1000 L1 MOV a,b 1.create
1.create 2.search
2.search 3.modify
3.modify 4.display
4.display 5.exit
5.exit Enter your choice:4
Enter your choice:1 Label address Value
Enter the L1 2000 A,B
address,label,opcode,operand 1.create
1005 L2 LAD R1,R2 2.search
1.create 3.modify
2.search 4.display
3.modify 5.exit
4.display Enter your choice:5
5.exit Exit.
Enter your choice:2
Enter the Label:L1

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:
Thus the program for implementing symbol Table Management was executed
successfully and the output was verified.
Ex No: 2 IMPLEMENTATION OF LEXICAL ANALYZER USING C

AIM:
To write a C program to implement the Lexical Analyzer which displays the output like
identifiers, keywords, operators, punctuators and Constants.

ALGORITHM:
1. Get the file name and open the file in read mode.
2. Check file not exist, if true print the error message and stop.
3. Check the end of file, if true ends the process.
4. Otherwise read the one line of text.
5. Check the token if keywords print the token and type is Keyword.
6. If identifier print the token and type is Identifier.
7. If constant print the token and type is Constant.
8. Otherwise print the token and type is Punctuator.
9. Repeat the step 3.
10. Stop the process.

PROGRAM:
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
static char op[7]={'+','-','*','<','>','='};
static char
h[13][20]={"int","char","float","long","while","main","scanf","printf","if","for","else"};
intiskeyword(char*);
intisoperator(char);
void main()
{
FILE *fp;
charfname[10],str[100],token[100];
chartokenname[100][200],tokentype[100][200];
inti,j,l,k=0;
clrscr();
printf("enter the filename:\t");
scanf("%s",fname);
fp=fopen(fname,"r");
if(fp==NULL)
{
printf("file does not exist");
exit(0);
}
while(!feof(fp))
{
fgets(str,80,fp);
i=0;
while (str[i]!='\0')
{
j=0;
if(isalpha(str[i]))
{
token[j++]=str[i++];
while ((isalpha(str[i]))||(isdigit(str[i])))
{
token[j++]=str[i++];
}
token[j]='\0';
if(iskeyword(token))
{
strcpy(tokenname[k],token);
strcpy(tokentype[k++],"keyword");
}
else
{
strcpy(tokenname[k],token);
strcpy(tokentype[k++],"identifier");
}
}
else if(isdigit(str[i]))
{
token[j++]=str[i++];
while((isdigit(str[i]))||(isdigit(str[i]=='.')))
{
token[j++]=str[i++];
}
token[j]='\0';
strcpy(tokenname[k],token);
strcpy(tokentype[k++],"constant");
}
else if(isoperator(str[i]))
{
token[j++]=str[i++];
if(isoperator(str[i]))
token[j++]=str[i++];
token[j]='\0';
strcpy(tokenname[k],token);
strcpy(tokentype[k++],"operator");
}
else if(str[i]==' ')
{
while(str[i]==' ')
i++;
}
else
{
token[j++]=str[i++];
token[j]='\0';
strcpy(tokenname[k],token);
strcpy(tokentype[k++],"punctuator");
}
}
}
printf("TOKENNAME \t TOKENTYPE\n");
for(l=0;l<k;l++)
{
printf("%s\t\t%s",tokenname[l],tokentype[l]);
printf("\n");
}
getch();
}
intiskeyword(char*token)
{
int m;
for(m=0;m<11;m++)
{
if((strcmp(token,h[m])==0))
return 1;
}
return 0;
}
intisoperator(char ch)
{
int n;
for(n=0;n<7;n++)
{
if(ch==op[n])
return 1;
}
return 0;
}
INPUT FILE:
Sum.c
int max(inta,int b);
OUTPUT:
Enter the file name:Sum.c
Token name Token type
int keyword
max identifier
( punctuator
int keyword
a identifier
, punctuator
int keyword
b identifier
) punctuator
; punctuator

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:
Thus the C Program for implementation of Lexical Analyzer was executed successfully
and the output was verified.
Ex No: 3 IMPLEMENTATION OF LEXICAL ANALYZER

USING LEX TOOL

AIM:
To write a C program to implement the Lexical Analyzer which displays the output like
identifiers, keywords, operators, punctuators and Constants. By using LEX tool.

ALGORITHM:

1. Define the Regular Expression for identifiers, constants and white space.

2. In Rule section, rule1 defines all the keywords and its corresponding action using
yytext () function.

3. In rule 2 the identifiers followed by open parenthesis and define the action is
FUNCTION using yytext () function.

4. Define the opening and closing curly braces for the action using yytext () function of
block begins and ends respectively.

5. Define constant, identifiers, strings and their corresponding actions using yytext ()
function.
6. Define the main function, pre-processor directives and operators like arithmetic,
relational and bitwise operators and their corresponding action parts using yytext ()
function.
7. Define the rules for punctuators and display their corresponding action using yytext ()
Function.
8. Check if the number of argument is less than one, then print Error message and stop
the Process.
9. Otherwise open the file in read mode, then call the yylex () function for scanning the
given input file and to display the tokens in the form of name and type of the tokens.

PROGRAM:
%{
%}
identifier [a-z A-Z][a-z A-Z 0-9]*
constant [+-]?[0-9][0-9]*
ws[ \t\n]*
%%
#.* {printf("\n\t%s is PREPROCESSOR DIRECTIVE.",yytext);}
int|
float |
char |
double |
while |
for |
do |
if |
break |
continue |
void |
switch |
case |
long |
struct |
const|
else |
return |
printf|
scanf|
goto {printf("\n\t%s is a KEYWORD",yytext);}
\/\*.*\*\/ |
\/\/.* {printf("\n\n\t%s is a COMMENT",yytext);}
\{{printf("\n\t%s is a BLOCK BEGINS",yytext);}
\} {printf("\n\t%s is a BLOCK ENDS",yytext);}
[A-Za-z](\[0-9*\])* {printf("\n\t%s is IDENTIFIER",yytext);}
\".*\" {printf("\n\n\t%s is a STRING",yytext);}
[0-9]+ {printf("\n\t%s is NUMBER",yytext);}
\= {printf("\n\t%s is an ASSIGNMENT OPERATOR",yytext);}
\<= |
\>= |
\<|
\== |
\!= |
\>{printf("\n\t%s is a RELATIONAL OPERATOR",yytext);}
\+ |
\- |
\* |
\/ |
\% |
\^ {printf("\n\t%s is a ARITHMETIC OPERATOR",yytext);}
\, |
\. |
\; |
\: {printf("\n\t%s is a PUNCTUATOR",yytext);}
\&&|
\| |
\! {printf("\n\t%s is a LOGICAL OPERATOR",yytext);}
\({printf("\n\t%s is a OPENING PARENTHESIS",yytext);}
\) {printf("\n\t%s is a CLOSING PARENTHESIS",yytext);}
\& |
\$ {printf("\n\t%s is a SPECIAL CHARACTER",yytext);}
\.|\n;
%%
int main(intargc,char **argv)
{
if(argc>1)
{
FILE *file;
file=fopen(argv[1],"r");
if(!file)
{
printf("\nCould not open the file %s.\n",argv[1]);
exit(0);
}
yyin=file;
}
yylex();
printf("\n\n");
return 0;
}
intyywrap()
{
return 0;
}

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15
INPUT FILE:
[cse13@LinSrvr:~] $ viinput.c
INPUT.C
/* sum of n numbers */ int i, sum=0;
#include<stdio.h> for(i=0; i<=n; i++)
#include<conio.h> {
void main() sum=sum+i;
{ }
int sum(int n) printf(“The sum is %d”, sum);
{ }
OUTPUT:
[cse13@LinSrvr:~] $ lexlextool.l
[cse13@LinSrvr:~] $ cc lex.yy.c
[cse13@LinSrvr:~] $ ./a.outinput.c
/* sum of n numbers */ is a for is a KEYWORD
COMMENT ( isa OPEN PARENTHESIS
#include<stdio.h> is i is IDENTIFIER
PREPROCESSOR = is an ASSIGNMENT
DIRECTIVE OPERATOR
#include<conio.h> is 0 is a NUMBER
PREPROCESSOR ; is a PUNCTUATOR
DIRECTIVE i is IDENTIFIER
void is a KEYWORD <= is a RELATIONAL
main() is a FUNCTION OPERATOR
{ is a BLOCK BEGINS n is IDENTIFIER
int is a KEYWORD ; is a PUNCTUATOR
sum is IDENTIFIER i is IDENTIFIER
( isa OPENING + is an ARITHMETIC
PARENTHESIS OPERATOR
int is a KEYWORD + is an ARITHMETIC
n is IDENTIFIER OPERATOR
) is a CLOSE ) is a CLOSE
PARENTHESIS PARENTHESIS
{ is a BLOCK BEGINS { is a BLOCK BEGINS
int is a KEYWORD sum is IDENTIFIER
i is IDENTIFIER = is an ASSIGNMENT
, is a PUNCTUATOR OPERATOR
sum is IDENTIFIER sum is IDENTIFIER
= is an ASSIGNMENT + is an ARITHMETIC
OPERATOR OPERATOR
0 is NUMBER i is IDENTIFIER
; is a PUNCTUATOR ; is a PUNCTUATOR

RESULT:
Thus the Program for implementation of Lexical Analyzer using LEX Tool was executed
successfully and the output in the form of token name and its types was displayed.
GENERATION OF YACC TOOL SPECIFICATIONS

EX NO:4a Recognizing a valid arithmetic expression that uses operators like +,


DATE: - , * and /.

AIM:
To write a Program to recognize a valid arithmetic expression that uses operators like +, -
, * and / using LEX and YACC Tools.

ALGORITHM:
1. Define the structure of Lex program to perform the validation of arithmetic expression.
2. Declare the function y.tab.h for storing the tokens to be used in YACC program.
3. Define the regular expressions for identifiers and arithmetic operators. Define the rules
for those corresponding rules and return the tokens ad ID and KEYWORD.
4. Define YACC program, declare the tokens used in this program by using y.tab.h
function used in Lex program.
5. Write the rules / Context Free Grammar for each expression (E) and declare the
corresponding actions for each rules.
6. Define main function and get the statement to be parsed and call yyparse () function
for matching the tokens with rules.
7. While token does not having sentinel form (eof) to declare Error message. Otherwise
to print the result as the given expression is the valid arithmetic expression.

PROGRAM:
LEX PROGRAM:
%{
#include "y.tab.h"
%}
%%
printf("Enter your Arithmetic Expression:\n");
"=" {printf("\n %s is an Equal to Operator",yytext);}
"+" {printf("\n %s is an Addition Operator",yytext);}
"-" {printf("\n %s is a Subtraction Operator",yytext);}
"*" {printf("\n %s is a Multiplication Operator",yytext);}
"/" {printf("\n %s is a Division Operator",yytext);}
";" {printf("\n %s is a Puncutator",yytext);}
[a-zA-Z]*[0-9]* {printf("\n %s is an Identifier",yytext);
return ID;
}
. returnyytext[0];
\n return 0;
%%
intyywrap()
{
return 1; }
YACC PROGRAM:
%{
#include<stdio.h>
%}
%token A ID
%%
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 exp4a.l
[root@localhost ~]# yacc -d exp4a.y
[root@localhost ~]# viy.tab.h
[root@localhost ~]# viy.tab.c
[root@localhost ~]# cc lex.yy.cy.tab.c -ll -lm
[root@localhost ~]# ./a.out
c=a+b*d/s; (input to be given)
c is an Identifier
= is an Equal to Operator
a is an Identifier
+ is an Addition Operator
b is an Identifier
* is a Multiplication Operator
d is an Identifier
/ is a Division Operator
s is an Identifier
; is a Puncutator
Valid Arithmetic Expression
[root@localhost ~]# ./a.out
c=a<b/d>r; (input to be given)
c is an Identifier
= is an Equal to Operator
a is an Identifier
b is an Identifier
/ is a Division Operator
d is an Identifier
r is an Identifier
; is a Puncutator
Valid Arithmetic Expression

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:
Thus the program for recognizing valid arithmetic expression that uses operators like +, -,
*, = and / was executed successfully and the output was verified.
IMPLEMENTATION OF SIMPLE CALCULATOR USING LEX AND YACC
TOOLS

AIM:

Develop a program to implement Simple Calculator using LEX and YACC Tools.
ALGORITHM:

1. Define the Lex program and declare the function y.tab.h for storing the tokens to be
used in Yacc program.
2. Define the regular expression for numbers in the form of integer, floating point and
exponential then return their corresponding token as NUM.
3. Write the rules for trigonometric functions like SIN, COS, TAN and logarithmic
functions like LOG and nLOG to perform trigonometric calculations.
4. If memory is selected for performing their operations and return their token as MEM.
5. Define the precedence of operators and tokens used in the Yacc program.
6. If the given statement is an expression then solve that ‘expr’ by using temporary
variables.
7. Read the expression from user by using getchar () function. If the character is equal to
space then check for ‘.’ (or) digit and scan the character in yylval and return the
number and character. Otherwise print the Syntax Error.

PROGRAM:

LEX PROGRAM:

%{
#include<stdlib.h>
#include"y.tab.h"
%}
%%
(([0-9]+|[.][0-9]+)?([eE][-+][0-9]+)?) {yylval.dval=atof(yytext);return NUM;}
sin | SIN return SIN;
cos | COS return COS;
tan | TAN return TAN;
log | LOG return LOG;
ln return nLOG;
mem return MEM;
[\t];
\$ {return 0;}
\n|.return yytext[0];
%%
YACC PROGRAM:

#include<math.h>
double memvar;
%}
%union
{
double dval;
}
%token <dval>NUM
%token <dval>MEM
%token LOG nLOG SIN COS TAN
%left '-''+'
%left '*''/'
%right '^'
%left LOG nLOG SIN COS TAN
%nonassoc UMINUS
%type <dval>E
%%
S:S ST '\n'
|ST '\n'
;
ST:MEM'='E{(memvar=$3);}
|E {printf("Answer is =%g\n",$1);}
;
E:E'+'E { $$ = $1 + $3;}
|E'-'E { $$ = $1 - $3;}
|E'*'E { $$ = $1 * $3;}
|E'/'E
{
if($3==0)
{
yyerror("Divide by Zero Error");
$$=0;
}
else
$$=$1/$3;
}
|E'^'E{ $$ = pow ($1,$3);}
|'-'E %prec UMINUS { $$ = -$2;}
|'('E')'{ $$ = $2;}
|LOG E{$$=log($2)/log(10);}
|nLOG E{$$=log($2);}
|SIN E{$$=sin( $2* 22 / 7.0 / 180);}
|COS E{$$=cos( $2 * 22 / 7.0 / 180);}
|TAN E{$$=tan( $2 * 22 / 7.0 / 180);}
|NUM{ $$ = $1;}
|MEM{ $$ = $1;}
;
%%
main()
{
printf("\nEnter the Expression:\n");
yyparse();
}
int yyerror(char *err)
{
fprintf(stderr,"%s\n",err);
}

Execution Procedure:

[root@localhost ~]# lex filename.l


[root@localhost ~]# yacc -d filename.y
[root@localhost ~]# cc lex.yy.c y.tab.c
[root@localhost ~]# cc lex.yy.c y.tab.c -ll -lm
[root@localhost ~]# ./a.out

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:

Thus the program for simple calculator using LEX and YACC tools was executed
successfully and the output was verified.
Generate three address code for a simple program using LEX and YACC.

AIM:

To write a program to Generate three address code for a simple program using LEX and
YACC.

ALGORITHM:

1. Define Lex program, for writing regular expressions for identifiers and constants.
2. Define the rules for identifiers, constants and return the tokens as ID and NUM.
3. Define the rules for relational operators and return the token as RELOP.
4. Define the Yacc program for declaring the structure with member operator, argument 1,
argument 2 and result.
5. Declare the stack with item of array and top pointer.
6. Declare the tokens and operators associatively used for the program.
7. Define the production rules for the C statements like declaration statement, conditional
statement, execution statement and define the action of each rule.
8. If the statement is IF statement then creates the entry to the intermediate code table and
PUSH the current entry number.
9. If the statement is conditional statement then POP the entry.
10. If the statement is else statements then POP the entry.
11. Define the main () function. Enter the input program to be generating the intermediate
code. And the yyparse () function to match the input for corresponding rules in BNF
form.
12. If the matching is found correct to display the result in Quadruple format. Otherwise to
declare the Error message.

PROGRAM:

LEX PROGRAM:

%{
#include"y.tab.h"
#include<stdio.h>
int LineNo=1;
%}
identifier[a-zA-Z][a-zA-Z0-9]*
number[0-9]+|([0-9]*\.[0-9]+)
%%
main\(\) return MAIN;
if return IF;
else return ELSE;
int |
char |
float |
double return TYPE;
{identifier} {strcpy(yylval.var,yytext); return VAR;}
{number} {strcpy(yylval.var,yytext); return NUM;}
\< |
\> |
\<= |
\>= |
== {strcpy(yylval.var,yytext); return RELOP;}
[ \t] ;
\n LineNo++;
. return yytext[0];
%%

YACC PROGRAM:

%{
#include<string.h>
#include<stdio.h>
struct quad /* structure declaration for a quadruple*/
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD[30];
struct stack /* structure declaration for a stack required for back patching*/
{
int items[100];
int top;
}stk;
int inde,stno,tind,ind;
extern int LineNo;
%}
%union
{

char var[10];
}
%token <var> NUM VAR RELOP
%token MAIN IF ELSE TYPE
%type <var> EXPR ASSIGNMENT CONDITION IFST ELSEST
%left'-''+'
%left'*''/'
%%
PROGRAM:MAIN BLOCK
;
BLOCK:'{'CODE'}'
;
CODE: BLOCK
| STATEMENT CODE
| STATEMENT
;
STATEMENT: DECST';'
|ASSIGNMENT ';'
|CONDST
;
DECST: TYPE VARLIST
;
VARLIST: VAR','VARLIST
| VAR
;
ASSIGNMENT: VAR'='EXPR { strcpy(QUAD[inde].op,"=");
strcpy(QUAD[inde].arg1,$3);
strcpy(QUAD[inde].arg2," ");
strcpy(QUAD[inde].result,$1);
strcpy($$,QUAD[inde++].result);
}
;
EXPR: EXPR '+' EXPR {AddQuadruple("+",$1,$3,$$);}
| EXPR '-' EXPR {AddQuadruple("-",$1,$3,$$);}
| EXPR '*' EXPR {AddQuadruple("*",$1,$3,$$);}
| EXPR '/' EXPR {AddQuadruple("/",$1,$3,$$);}
| '-'EXPR {AddQuadruple("UMIN",$2," ",$$);}
| '('EXPR')' {strcpy($$,$2);}
| VAR
| NUM
;
CONDST: IFST {
ind=pop();
sprintf(QUAD[ind].result,"%d",inde);
ind=pop();
sprintf(QUAD[ind].result,"%d",inde);
}
| IFST ELSEST
;
IFST: IF'('CONDITION')'
{
strcpy(QUAD[inde].op,"==");
strcpy(QUAD[inde].arg1,$3);
strcpy(QUAD[inde].arg2,"FALSE");
strcpy(QUAD[inde].result,"-1");
push(inde);
inde++;
}
BLOCK {
strcpy(QUAD[inde].op,"GOTO");
strcpy(QUAD[inde].arg1," ");
strcpy(QUAD[inde].arg2," ");
strcpy(QUAD[inde].result,"-1");
push(inde);
inde++;
}
;
ELSEST: ELSE{
tind=pop();
ind=pop();
push(tind);
sprintf(QUAD[ind].result,"%d",inde);
}
BLOCK {
ind=pop();
sprintf(QUAD[ind].result,"%d",inde);
}
;
CONDITION: VAR RELOP VAR {
AddQuadruple($2,$1,$3,$$);
stno=inde-1;
}
| VAR
| NUM
;
%%
extern FILE *yyin;
int main(int argc,char *argv[])
{
FILE *fp;
int i;
if(argc>1)
{
fp=fopen(argv[1],"r");
if(!fp)
{
printf("\n File not found");
exit(0);
}
yyin=fp;
}
yyparse();
printf("\n\t\t--------------------------------------------------------------------------------" "\n\t\t
POSITION OPERATOR ARG1 ARG2 RESULT" "\n\t\t--------------------
------------------------------------------------------------------");
for(i=0;i<inde;i++)
{
printf("\n\t\t\t%d\t\t%s\t\t%s\t\t%s\t\t%s",i,QUAD[i].op,QUAD[i].arg1,QUAD[i].arg2,QUAD[i].
result);
}
printf("\n\t\t--------------------------------------------------------------------------------------");
printf("\n\n");
return 0;
}
void push(int data)
{
stk.top++;
if(stk.top==100)
{
printf("\n Stack Overflow");
exit(0);
}
stk.items[stk.top]=data;
}
int pop()
{
int data;
if(stk.top==-1)
{
printf("\n stack Underflow\n");
exit(0);
}
data=stk.items[stk.top--];
return data;
}
void AddQuadruple(char op[5],char arg1[10],char arg2[10],char result[10])
{
strcpy(QUAD[inde].op,op);
strcpy(QUAD[inde].arg1,arg1);
strcpy(QUAD[inde].arg2,arg2);
sprintf(result,QUAD[inde++].result);
}
yyerror()
{
printf("\n Error on Line No:%d",LineNo);
}
OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:

Thus the program for converting the BNF rules into Yacc form and implementing the
code for generation Abstract Syntax Tree was executed successfully and output was verified.
IMPLEMENTATION OF BACK END OF THE COMPILER

AIM:
To write a C program 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 and jump. Also simple addressing modes are used.

ALGORITHM:

1. Define the structure with operator argument 1, argument 2 and result.


2. Get the input file and open it in read mode.
3. Read the file content and store it in the structure.
4. Compare the operator with ‘+’, if it is equal then call the ADD() function.
5. Compare the operator with ‘-’, if it is equal then call the SUB () function.
6. Compare the operator with ‘*’, if it is equal then call the MUL () function.
7. Compare the operator with ‘/’, if it is equal then call the DIV() function.
8. Compare the operator with ‘=’, if it is equal then call the ASSIGN () function.
9. Otherwise Print the Error message.
10. Define ADD () function. Generate the register number, MOV instruction with
register and the argument 1 to be displayed. Then generate ADD instruction
with register and argument 2 to be displayed.
11. Define SUB () function. Generate the register number, MOV instruction with
register and the argument 1 to be displayed. Then generate SUB instruction
with register and argument 2 to be displayed.
12. Define MUL () function. Generate the register number, MOV instruction with
register and the argument 1 to be displayed. Then generate MUL instruction
with register and argument 2 to be displayed.
13. Define DIV () function. Generate the register number, MOV instruction with
register and the argument 1 to be displayed. Then generate DIV instruction
with register and argument 2 to be displayed.
14. Define ASSIGN () function. Generate the register number, MOV instruction
with result and register. Finally print the result as three address code and
produces the 8086 assembly language instructions.
15. The instructions can be assembled and run using a 8086 assembler. The target
assembly instructions can be simple move, add, sub, mul, div and assign.
PROGRAM:

#include<stdio.h>
#include<string.h>
#include<conio.h>

struct quad
{
char op[5];
char arg1[10];
char arg2[10];
char result[10];
}QUAD;

void add( );
void sub( );
void mul( );
void div( );
void assign( );
int tind=0, tind1=0;
FILE *fp;
void main()
{
int pos;
char fname[10], ch;
clrscr( );
printf(" Enter the file name: \n ");
scanf(" %s ", fname);
fp=fopen(fname, " r " );
while( ! feof ( fp ) )
{
fscanf(fp, "%s%s%s%s%c “,QUAD.op,QUAD.arg1,QUAD.arg2,QUAD.result );
ch=getchar( );

if(strcmp (QUAD.op, " + " ) == 0)


{
add( );
}

else if(strcmp (QUAD.op, " - " ) == 0)


{
sub( );
}
else if(strcmp (QUAD.op, " * " ) == 0)
{
mul( );
}

else if(strcmp (QUAD.op, " / " ) == 0)


{
div( );
}
else if(strcmp (QUAD.op, " = " ) == 0)
{
assign( );
}
else
printf( " Error " );
}
getch( );
}
void add( )
{
char reg[5], inst[10], inst1[10];
sprintf(reg," R%d ", tind++);
sprintf(inst," MOV %s %s ", reg, QUAD.arg1);
printf(" %s\n ", inst);
sprintf(inst1," ADD %s %s ",reg, QUAD.arg2);
printf(" %s\n ",inst1);
}
void assign( )
{
char reg1[5], inst2[10];
sprintf(reg1," R%d ",tind1++);
sprintf(inst2," MOV %s %s ",QUAD.result,reg1);
printf(" %s\n ",inst2);
}
void sub( )
{
char reg[5], inst[10], inst1[10];
sprintf(reg," R%d ",tind++);
sprintf(inst," MOV %s %s ",reg, QUAD.arg1);
printf("%s\n",inst);
sprintf(inst1," SUB %s %s ",reg, QUAD.arg2);
printf(" %s\n ",inst1);
}
void mul( )
{
char reg[5], inst[10], inst1[10];
sprintf(reg," R%d ",tind++);
sprintf(inst," MOV %s %s ",reg, QUAD.arg1);
printf(" %s\n ",inst);
sprintf(inst1," MUL %s %s ",reg, QUAD.arg2);
printf(" %s\n ",inst1);
}
void div( )
{
char reg[5], inst[10], inst1[10];
sprintf(reg," R%d ",tind++);
sprintf(inst," MOV %s %s ",reg, QUAD.arg1);
printf(" %s\n ",inst);
sprintf(inst1," DIV %s %s ",reg, QUAD.arg2);
printf(" %s\n ",inst1);
}

INPUT FILE:
+ b1 c1 t0
= t0 -1 a1
- b2 c2 t1
= t1 -1 a2
* b3 c3 t2
= t2 -1 a3
/ b4 c4 t3
= t3 -1 a4

OUTPUT:

MOV b1,R0
ADD c1,R0
MOV R0,a1

MOV b2,R0
SUB c2,R0
MOV R0,a2

MOV b3,R0
MUL c3,R0
MOV R0,a3
MOV b4,R0

DIV c4,R0
MOV R0,a4
OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:

Thus the program for implementing 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 and jump was executed successfully.
Ex.No:7 IMPLEMENTATION OF SIMPLE CODE OPTIMIZATION
TECHNIQUES (CONSTANT FOLDING METHOD)

AIM:
To write a C program to implement Code Optimization Techniques.

ALGORITHM:

1. Invoke a function getreg to determine the location L where the result of the
Computation y op z should be stored. L will usually be a register, but it could also be a
memory location. We shall describe getreg shortly.

2. Consult the address descriptor for y to determine y, (one of) the current
location(s) of y. prefer the register for y if the value of y is currently both in memory and
a register. If the value of y is not already in L, generate the instruction MOV y, L to
place a copy of y in L.

3. Generate the instruction OP z, L where z is a current location of z. Again, prefer


a register to a memory location if z is in both. Update the address descriptor of x to
indicate that x is in location L. If L is a register, update its descriptor to indicate that it
contains the value of x, and remove x from all other register descriptors.

4. If the current values of y and/or z have no next users, are not live on exit from the
block, and are in register descriptor to indicate that, after execution of x := y op z, those
registers no longer will contain y and/or z, respectively.

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

Sample input:

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

OBSERVATION 5
VIVA VOICE 5
RECORD 5
TOTAL 15

RESULT:
Thus the program for code optimization is implemented and executed
successfully, and the output is verified.

You might also like