Compiler Design Lab Manual
Compiler Design Lab Manual
Name : __________________________________________
Certified that this practical work entitles CS3501 – Compiler Design Laboratory is
V Semester in Department of Computer Science and Engineering during the year July-
November, 2023.
Register No.
Submitted for the Anna University B.E Degree Practical Examination held at Nellai College of
Engineering on_______________.
Aim:
Algorithm:
1. Include necessary header files, declare a symbol table to store identifiers and their
addresses.
2. Define the patterns and corresponding actions for various token types using regular
expressions.
3. Check if a filename is provided as a command-line argument (argc > 1).
4. Set yyin to the opened file for lex to read from it.
5. Call yylex to start tokenizing and processing the file.
6. After processing the input, print the contents of the symbol table.
Program:
%{
#include <stdio.h>
#include <string.h>
typedef struct {
char name[256];
void* address;
} SymbolEntry;
SymbolEntry symbolTable[MAX_SYMBOLS];
int symbolCount = 0;
1
if (symbolCount < MAX_SYMBOLS) {
strcpy(symbolTable[symbolCount].name, identifier);
symbolTable[symbolCount].address = address;
symbolCount++;
} else {
%}
%%
"auto"|"break"|"case"|"char"|"const"|"continue"|"default"|"do"|"double"|"else"|"enum"|"extern
"|"float"|"for"|"goto"|"if"|"int"|"long"|"register"|"return"|"short"|"signed"|"sizeof"|"static"|"stru
ct"|"switch"|"typedef"|"union"|"unsigned"|"void"|"volatile"|"while" {
[a-zA-Z_][a-zA-Z0-9_]* {
void* address;
addIdentifier(yytext, address);
[0-9]+ {
2
\/\/[^\n]* {
\/\*[^*]*\*+([^/*][^*]*\*+)*\/ {
[+\-*/=] {
[ \t\n] {
.{
%%
if(argc>1)
FILE *file;
file=fopen(argv[1],"r");
if(!file)
3
Output:
4
{
exit(0);
yyin=file;
yylex();
printf("\nSymbol Table:\n");
int yywrap()
return 0;
Result:
Thus the lex program was executed successfully, for recognizing patterns in C and
symbol table creation while recognizing identifiers.
5
Ex.No:2 Implement a lexical analyzer using LEX tool
Aim:
To implement a lexical analyzer using LEX tool.
Algorithm:
1. Declare and initialize the required variable.
2. If the statement starts with #.* print it as preprocessor directive.
3. Check for the given list of keywords and print them as keyword if it is encountered.
4. If the given string is ‘/*’ or ‘*/’ print it as comment line.
5. For a function, print the beginning and ending of the function block.
6. Similarly print the corresponding statements for numbers, identifiers and assignment
operators.
7. In the main function get the input file as argument and open the file in read mode.
8. Then read the file and print the corresponding lex statement given above.
LEX program:
%{
%}
identifier [a-z|A-Z]|[a-z|A-Z|0-9]*
%%
#.* {printf("\n%s is a preprocessor dir",yytext);}
int {printf("\n\t%s is a keyword",yytext);}
{identifier}\( {printf("\n\nFUNCTION\n\t%s",yytext);}
\{ {printf("\nBLOCK BEGINS");}
\} {printf("\nBLOCK ENDS");}
{identifier} {printf("\n%s is an IDENTIFIER",yytext);}
. | \n
%%
int main(int argc,char **argv)
{
if(argc>1)
{
FILE *file;
file=fopen(argv[1],"r");
6
Output:
7
if(!file)
{
printf("\n couldnot open %s\n",argv[1]);
exit(0);
}
yyin=file;
}
yylex();
printf("\n\n");
return 0;
}
int yywrap()
{
return 0;
}
Input (input.c):
#include <stdio.h>
int main()
{
int a, b, sum;
printf("Enter two integers: ");
scanf("%d %d", &a, &b);
sum = a + b;
printf("%d + %d = %d", a, b, sum);
return 0;
}
Result:
Thus the lexical analyzer was implemented successfully using LEX tool.
8
Ex.No:3a Program to recognize a valid arithmetic expression that uses operator
+,-,* and /
Aim:
To write a program to recognize a valid arithmetic expression that uses operator +,-*
and / using YACC.
Algorithm:
LEX:
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. LEX requires regular expressions to identify valid arithmetic expression token of
lexemes.
3. LEX call yywrap() function after input is over. It should return 1 when work is done
or should return 0 when more processing is required.
YACC:
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. Define tokens in the first section and also define the associativity of the operations
3. Mention the grammar productions and the action for each production.
4. Call yyparse() to initiate the parsing process.
5. yyerror() function is called when all productions in the grammar in second section
doesn't match to the input statement.
LEX program:
%{
#include<stdio.h>
#include "ex3a.tab.h"
%}
%%
[a-zA-Z][0-9a-zA-Z]* {return ID;}
[0-9]+ {return DIG;}
[\t]+ {;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap()
9
{
return 1;}
YACC program:
%{
#include<stdio.h>
%}
%token ID DIG
%left '+''-'
%left '*''/'
%right UMINUS
%%
stmt:expn ;
expn:expn'+'expn
|expn'-'expn
|expn'*'expn
|expn'/'expn
|'-'expn %prec UMINUS
|'('expn')'
|DIG
|ID
;
%%
int main()
{
printf("Enter the Expression \n");
yyparse();
printf("valid Expression \n");
return 0;
}
int yyerror()
{
printf("Invalid Expression");
exit(0);
}
10
Output:
11
Result:
Thus the program was executed successfully for recognizing a valid arithmetic
expression that uses operator ,-,* and /.
12
Ex.No:3b Program to recognize a valid variable which starts with a letter
followed by any number of letters or digits
Aim:
To write a program to recognize a valid variable which starts with a letter followed by
any number of letters or digits using YACC.
Algorithm:
LEX:
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’
2. LEX requires regular expressions or patterns to identify token of lexemes for
recognize a valid variable.
3. Lex call yywrap() function after input is over. It should return 1 when work is done or
should return 0 when more processing is required.
YACC:
1. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
2. Define tokens in the first section and also define the associativity of the operations.
3. Mention the grammar productions and the action for each production.
4. Call yyparse() to initiate the parsing process.
5. yyerror() function is called when all productions in the grammar in second section doesn't
match to the input statement.
LEX program:
%{
#include "ex3b.tab.h"
%}
%%
[a-zA-Z] {return LET;}
[0-9] {return DIG;}
. {return yytext[0];}
\n {return 0;}
%%
int yywrap() {
return 1;
}
13
Output:
14
YACC program:
%{
#include<stdio.h>
%}
%token LET DIG
%%
variable:var
;
var:var DIG
|var LET
|LET ;
%%
int main()
{
printf("Enter the variable:\n");
yyparse();
printf("Valid variable\n");
return 0;
}
int yyerror()
{
printf("Invalid variable \n");
exit(1);
}
Result:
Thus the program was implemented successfully to recognize valid variable which
starts with a letter followed by any number of letters or digits using YACC.
15
Ex.No:3c Program to recognize a valid control structures syntax of C language
(For loop, while loop, if-else, if-else-if, switch-case, etc.)
Aim:
To generate YACC specification program to recognize a valid control structures
syntax of C language (For loop, while loop, if-else, if-else-if, switch-case, etc.).
Algorithm:
LEX:
1. Define patterns and actions for tokenizing input.
2. Recognize keywords like "for," "while," "if," "else," etc., and returns corresponding
tokens like WHILE, IF, ELSE, etc.
3. Skip Whitespace characters.
YACC:
1. Define the token types using %token.
2. Set precedence and associativity rules for operators like '+', '-', '*', '/', and unary minus
('UMINUS').
3. The %start program specifies that the entry point of the grammar is the "program"
rule.
4. The grammar includes various constructs like iteration statements, if statements,
switch statements, declarations, and expressions.
5. Call yyparse() to start parsing.
6. Call the yyerror function when there is a syntax error in the input. It prints an error
message to stderr.
Program:
LEX:
%{
#include<stdio.h>
#include "ex3c.tab.h"
%}
%%
"for" { return WHILE; }
"while" { return WHILE; }
16
"if" { return IF; }
"else" { return ELSE; }
"switch" { return SWITCH; }
"case" { return CASE; }
"break" { return BREAK; }
"int" { return INT; }
[0-9]+ { yylval = atoi(yytext); return NUMBER; }
[a-zA-Z_][a-zA-Z0-9_]* { yylval = atoi(yytext); return IDENTIFIER; }
[ \t\n] ; // Skip whitespace
. { return yytext[0]; } // Return single characters as tokens
%%
int yywrap() {
return 1;
}
YACC:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern FILE *yyin;
extern int yylex();
extern void yyerror(const char*);
int yyparse();
union YYSTYPE{
int integer;
char* string;
};
%}
%token FOR WHILE IF ELSE SWITCH CASE BREAK INT NUMBER IDENTIFIER
%left '+' '-'
%left '*' '/'
%left UMINUS
%start program
17
%%
program: /* empty */
| statement
;
statement: iteration_statement
| if_statement
| if_else_statement
| if_else_if_statement
| else_if_statement
| else_if_else_if_statement
| switch_statement
| INT declaration_list ';'
| expression ';'
| BREAK ';'
;
declaration_list: IDENTIFIER
| declaration_list ',' IDENTIFIER
;
iteration_statement: WHILE '(' expression ')' statement
| FOR '(' expression ';' expression ';' expression ')' statement
;
if_statement: IF '(' expression ')' statement;
if_else_statement: IF '(' expression ')' statement ELSE statement;
if_else_if_statement: IF '(' expression ')' statement else_if_statement;
else_if_statement: ELSE IF '(' expression ')' statement;
else_if_else_if_statement: else_if_statement ELSE IF '(' expression ')' statement;
switch_statement: SWITCH '(' expression ')' '{' case_statements '}' ;
case_statements: CASE NUMBER ':' statements
| case_statements CASE NUMBER ':' statements
;
statements: statement
| statements statement
;
expression: IDENTIFIER
18
| NUMBER
| expression '+' expression
| expression '=' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression
| '(' expression ')'
;
%%
int main(int argc,char **argv)
{
if(argc>1)
{
FILE *file;
file=fopen(argv[1],"r");
if(!file)
{
printf("\n couldnot open %s\n",argv[1]);
exit(0);
}
yyin=file;
yyparse();
printf("\n\n");
return 1;
}
}
void yyerror(const char* s) {
fprintf(stderr, "Syntax error: %s\n", s);
}
Input C program:
if(i=5)
break;
else
break;
19
Output:
20
Result:
Thus the YACC program was generated successfully for recognizing a valid control
structures syntax of C language.
21
Ex.No:3d Implementation of calculator using LEX and YACC
Aim:
To implement calculator using lex and yacc.
Algorithm:
1. Start the program.
2. In the declaration part of lex, includes declaration of regular definitions as digit.
3. In the translation rules part of lex, specifies the pattern and its action that is to be
executed whenever a lexeme matched by pattern is found in the input in the
calculator.l.
4. By use of Yacc program,all the Arithmetic operations are done such as +,-,*,/,%.
5. Display error is persist.
6. Provide the input.
7. Verify the output.
8. End the program.
LEX program:
%{
#include<stdio.h>
#include "calculator.tab.h"
extern int yylval;
%}
%%
[0-9]+ { yylval=atoi(yytext);
return NUMBER;
}
[\t] ;
[\n] return 0;
. return yytext[0];
%%
YACC program:
%{
#include<stdio.h>
int flag=0;
%}
%{
22
int yylex();
void yyerror();
%}
%token NUMBER;
%left '+' '-'
%left '*' '/' '%'
%left '(' ')'
%%
ArithmeticExpression: E{ printf("\nResult=%d\n",$$);
return 0;
};
E:E '+' E{$$=$1+$3;}
|E '-' E{$$=$1-$3;}
|E'*'E{$$=$1*$3;}
|E'/'E{$$=$1/$3;}
|E'%'E{$$=$1%$3;}
|'('E')'{$$=$2;}
|NUMBER{$$=$1;}
;
%%
//driver code
void main()
{
printf("\nEnter Any Arithmetic Expression which can have operations +,-,*,/,Modulus and
Round brackets:\n");
yyparse();
if(flag==0)
printf("\nEntered arithmetic expression is Valid\n\n");
}
void yyerror()
{
printf("\nEntered arithmetic expression is Invalid\n\n");
flag=1;
}
23
Output:
24
Result:
Thus the calculator was implemented successfully using lex and yacc.
25
Ex.No:4 Generate three address code for a simple program using LEX and
YACC
Aim:
To generate three address code for a simple program using LEX and YACC.
Algorithm:
LEX:
4. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
5. LEX requires regular expressions to identify valid arithmetic expression token of
lexemes.
6. LEX call yywrap() function after input is over. It should return 1 when work is done
or should return 0 when more processing is required.
YACC:
6. Declare the required header file and variable declaration with in ‘%{‘ and ‘%}’.
7. Define tokens in the first section and also define the associativity of the operations
8. Mention the grammar productions and the action for each production.
9. Call yyparse() to initiate the parsing process.
10. yyerror() function is called when all productions in the grammar in second section
doesn't match to the input statement.
11. Make_symtab_entry() function to make the symbol table entry.
LEX program:
%{
#include<stdio.h>
#include<string.h>
#include "ex4.tab.h"
%}
%%
[ \n\t]+ ;
main {return MAIN;}
int|float|double|char {strcpy(yylval.string,yytext); return TYPE; }
[a-zA-Z][a-zA-Z0-9_]* {strcpy(yylval.string,yytext);return ID; }
[0-9]+ |
26
[0-9]+\.[0-9]+ {
yylval.dval=atof(yytext);
return NUMBER;
}
. return yytext[0];
%%
int yywrap(){
return 1;
}
YACC program:
%{
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Symbol_Table
{
char sym_name[10];
char sym_type[10];
double value;
}Sym[10];
int sym_cnt=0;
int Index=0;
int temp_var=0;
27
struct Quadruple
{
char operator[5];
char operand1[10];
char operand2[10];
char result[10];
}QUAD[25];
struct Stack
{
char *items[10];
int top;
}Stk;
%}
%union
{
int ival;
double dval;
char string[10];
}
28
body: varstmtstmtlist
;
varstmt: vardeclvarstmt|
;
vardecl:TYPEvarlist ';'
;
| ID'='NUMBER {
int i;
i=search_symbol($1);
if(i!=-1)
printf("\n Multiple Declaration of Variable");
else
make_symtab_entry($1,$<string>0,$3);
}
int i;
i=search_symbol($3);
if(i!=-1)
printf("\n Multiple Declaration of Variable");
else
29
make_symtab_entry($3,$<string>0,$5);
}
|ID { int i;
i=search_symbol($1);
if(i!=-1)
printf("\n Multiple Declaration of Variable");
else
make_symtab_entry($1,$<string>0,0);
}
;
stmtlist: stmtstmtlist|
;
int i,j;
30
i=search_symbol($1);
j=search_symbol($3);
if(i==-1 || j==-1)
printf("\n Undefined Variable");
else
addQuadruple("=","",$3,$1);
}
| ID '=' expr ';' {addQuadruple("=","",pop(),$1); }
31
sprintf(str, "%d", temp_var);
strcat(str1,str);
temp_var++;
addQuadruple("*",pop(),pop(),str1);
push(str1);
}
|expr '/' expr {
char str[5],str1[5]="t";
sprintf(str, "%d", temp_var);
strcat(str1,str);
temp_var++;
addQuadruple("/",pop(),pop(),str1);
push(str1);
|ID { int i;
i=search_symbol($1);
if(i==-1)
printf("\n Undefined Variable");
else
push($1);
}
;
32
%%
extern FILE *yyin;
int main()
{
Stk.top = -1;
yyin = fopen("input.txt","r");
yyparse();
display_sym_tab();
printf("\n\n");
display_Quadruple();
printf("\n\n");
return(0);
}
33
strcpy(Sym[sym_cnt].sym_name,sym);
strcpy(Sym[sym_cnt].sym_type,dtype);
Sym[sym_cnt].value=val;
sym_cnt++;
}
void display_sym_tab()
{
int i;
printf("\n\n The Symbol Table \n\n");
printf(" Name Type Value");
for(i=0;i<sym_cnt;i++)
printf("\n %s %s %f",Sym[i].sym_name,Sym[i].sym_type,Sym[i].value);
}
void display_Quadruple()
{
int i;
printf("\n\n The INTERMEDIATE CODE Is : \n\n");
printf("\n\n The Quadruple Table \n\n");
printf("\n Result Operator Operand1 Operand2 ");
for(i=0;i<Index;i++)
printf("\n %d %s %s %s
%s",i,QUAD[i].result,QUAD[i].operator,QUAD[i].operand1,QUAD[i].operand2);
}
int yyerror()
{
printf("\nERROR!!\n");
return(1);
}
34
Output:
35
Stk.top++;
Stk.items[Stk.top]=(char *)malloc(strlen(str)+1);
strcpy(Stk.items[Stk.top],str);
}
char * pop()
{
int i;
if(Stk.top==-1)
{
printf("\nStack Empty!! \n");
exit(0);
}
char *str=(char *)malloc(strlen(Stk.items[Stk.top])+1);;
strcpy(str,Stk.items[Stk.top]);
Stk.top--;
return(str);
}
void addQuadruple(char op[10],char op2[10],char op1[10],char res[10]){
strcpy(QUAD[Index].operator,op);
strcpy(QUAD[Index].operand2,op2);
strcpy(QUAD[Index].operand1,op1);
strcpy(QUAD[Index].result,res);
Index++;
}
Result:
Thus the three address code was generated successfully for a simple program using
LEX and YACC.
36
Ex.No:5 Implement type checking using LEX and YACC
Aim:
To implement type checking using LEX and YACC.
Algorithm:
Lex:
1. Initialize the symbol table (symbol_table) and symbol_count to keep track of
variables and their types.
2. Define token patterns using regular expressions for types, integers, identifiers, and
operators.
3. Define actions for each token pattern.
4. Define the `yywrap` function to indicate the end of input.
5. The Lex code, when executed, will tokenize the input program and perform basic type
checking by checking if identifiers are declared with valid types and printing
appropriate messages.
Yacc:
1. Define the token names and their precedence and associativity rules.
2. Define the grammar rules for the programming language, including program structure,
statements, declarations, and expressions.
3. Implement semantic actions for each grammar rule.
4. Define the `main` function to call the Yacc parser (`yyparse`) and check its return
value.
5. Define the `yyerror` function to handle parse errors by printing an error message.
6. The Yacc code, when executed, will parse the input program based on the defined
grammar rules and perform type checking. It will print messages indicating whether
the input code has valid type declarations and assignments.
Program:
Lex:
%{
#include "ex5new.tab.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int yylval;
extern FILE* yyin;
typedef struct {
37
char name[50];
int type; // 0 for integer, 1 for float
} Symbol;
Symbol symbol_table[100]; // A simple symbol table (limited to 100 entries)
int symbol_count = 0;
// Function to search for an identifier in the symbol table
int lookup(char* name, int type) {
for (int i = 0; i<symbol_count; i++) {
if (strcmp(symbol_table[i].name, name) == 0 &&symbol_table[i].type == type) {
return 1; // Identifier found
}
}
return 0; // Identifier not found
}
%}
%%
int|float {yylval = strcmp(yytext, "int") == 0 ? 0 : 1; return TYPE; }
[0-9]+ { yylval = atoi(yytext); return INTEGER; }
[a-zA-Z_][a-zA-Z0-9_]* {
if (lookup(yytext, yylval)) {
printf("Identifier '%s' has a valid type.\n", yytext);
}
return IDENTIFIER;
}
[ \t\n] ; // Ignore whitespace and newline characters
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return MULTIPLY; }
"/" { return DIVIDE; }
"=" { return ASSIGN; }
38
";" { return SEMICOLON; }
. { returnyytext[0]; }
%%
int yywrap(){
return 1;
}
YACC:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lex.yy.c"
extern char *yytext;
int yylex(void);
void yyerror(const char* s);
%}
%token TYPE INTEGER IDENTIFIER PLUS MINUS MULTIPLY DIVIDE ASSIGN
SEMICOLON
%left PLUS MINUS
%left MULTIPLY DIVIDE
%%
program : /* empty */
| program statement
;
statement : declaration SEMICOLON { printf("Declaration\n"); }
| expression SEMICOLON {printf("Expression\n"); }
| error SEMICOLON {yyerrok; printf("Syntax error\n"); }
;
declaration : TYPE IDENTIFIER {
// Add the identifier to the symbol table with the specified type
strcpy(symbol_table[symbol_count].name, yytext);
39
symbol_table[symbol_count].type = yylval;
symbol_count++;
}
;
expression : IDENTIFIER ASSIGN expression {
// Check if the identifier is declared with the correct type
if (!lookup(yytext, yylval)) {
printf("Error: Identifier '%s' is undeclared or has an incorrect type.\n", yytext);
}
}
| expression PLUS expression
| expression MINUS expression
| expression MULTIPLY expression
| expression DIVIDE expression
| INTEGER
| IDENTIFIER
| '(' expression ')'
;
%%
int main() {
if (yyparse() == 0) {
printf("Type checking successful.\n");
} else {
printf("Type checking failed.\n");
}
return 0;
}
void yyerror(const char* s) {
printf("Parse error: %s\n", s);
}
40
Output:
41
Result:
Thus the type checking was implemented successfully using lex and yacc.
42
Ex.No:6 Implement simple code optimization techniques
Aim:
Algorithm:
Program:
#include <stdio.h>
int main() {
// Given three-address code
int t1 = 5;
int t2 = 10;
int t3, t4, t5;
// Optimization Techniques
// 1. Constant Folding
t3 = t1 + t2; // Constant folding: t3 = 15
// 2. Strength Reduction
t4 = t3 << 1; // Strength reduction: t4 = t3 * 2 = t3 << 1
// 3. Algebraic Transformation
t5 = 2 * t4; // Algebraic transformation: t5 = 2 * t4
43
Output:
Original Code:
t1 = 5
t2 = 10
t3 = t1 + t2
t4 = t3 * 2
t5 = t4 + t4
Optimized Code:
t1 = 5
t2 = 10
t3 = 15
t4 = t3 << 1
t5 = 2 * t4
Result: t5 = 60
44
printf("t5 = 2 * t4\n");
return 0;
}
Result:
Thus the program for code optimization successfully exec
45
Ex.No:7 Implement back-end of the compiler for which the three address code
is given as input and the 8086 assembly language code is produced as
output
Aim:
To implement the back end of the compiler which takes the three address code and
produces the 8086 assembly language instructions that can be assembled and run using a 8086
assembler.
Algorithm:
1. Initialize variables.
a) icode: A 2D character array to store intermediate code instructions.
b) str: A character array to temporarily store each instruction.
c) opr: A character array to store the corresponding assembly operation for arithmetic
operators.
d) i: An integer variable to keep track of the current instruction index.
2. Read the intermediate code instructions one by one and store them.
3. Print a header for the target code generation section.
4. Reset the value of i to 0 to iterate through the intermediate code instructions again.
5. Enter a loop to generate target code for each intermediate code instruction
a. Copy the current intermediate code instruction to the str variable.
b. Extract the operator (e.g., +, -, *, /) from the fourth character of str and determine
the corresponding assembly operation (opr).
c. Print the assembly code for the intermediate code instruction:
Mov instruction to load a value into a temporary register.
Arithmetic operation (ADD, SUB, MUL, or DIV) using the temporary register
and the value from str.
Mov instruction to store the result back into a variable.
d. Increment i to process the next intermediate code instruction.
6. Continue the loop until "exit" is encountered.
Program:
#include<stdio.h>
#include<stdio.h>
#include<string.h>
void main()
{
char icode[10][30],str[20],opr[10];
int i=0;
46
//clrscr();
printf("\n Enter the set of intermediate code (terminated by ex):\n");
do
{
scanf("%s",icode[i]);
} while(strcmp(icode[i++],"exit")!=0);
printf("\n target code generation");
printf("\n************************");
i=0;
do
{
strcpy(str,icode[i]);
switch(str[3])
{
case '+':
strcpy(opr,"ADD");
break;
case '-':
strcpy(opr,"SUB");
break;
case '*':
strcpy(opr,"MUL");
break;
case '/':
strcpy(opr,"DIV");
break;
}
printf("\n\tMov %c,R%d",str[2],i);
printf("\n\t%s%c,R%d",opr,str[4],i);
47
Output:
Enter the set of intermediate code (terminated by ex):
d=2/3
c=4/5
a=2*e
exit
target code generation
************************
Mov 2,R0
DIV3,R0
Mov R0,d
Mov 4,R1
DIV5,R1
Mov R1,c
Mov 2,R2
MULe,R2
Mov R2,a
48
printf("\n\tMovR%d,%c",i,str[0]);
}while(strcmp(icode[++i],"exit")!=0);
//getch();
}
Result:
Thus the program was implemented to generate an assembly language code has been
successfully executed.
49