%{
// yacc program
#include <stdio.h>
#include <stdlib.h>
%}
%token ID NUM IF THEN ELSE WHILE FOR LE GE EQ NE OR AND //value return by lex program
%right "=" /* equal to right associative*/
/* All the other are left associative and down the line precedence increases */
%left OR AND
%left '>' '<' LE GE EQ NE //relational operators
%left '+' '-'
%left '*' '/'
%right UMINUS //unary minus
%left '!'
%%
/* This is the Grammar for the language */
/* S is start and it has three possibilities FOR, WHILE, IF ELSE */
/* E is variable */
S : FOR '(' E ';'{lab1();} E {lab2();}';' E {lab3();}')' E';'{lab4(); exit(0);} //label generate for loop
| WHILE{wlab1();} '(' E ')'{wlab2();} E ';'{wlab3();} //label generated for while
| IF '(' E ')'{ilab1();} THEN E ';'{ilab2();} ELSE E ';'{ilab3();} //if else
;
/* E has following productions */
/* V is also a variable */
/* everytime number or identifier or arithmetic symbol encounters it pushes them in to stack */
/* code_assign is function is call when assignment encounters*/
/* codegen is function is call when arithmetic operation encounters */
E : V '='{push();} E{codegen_assign();}
| E '+'{push();} E{codegen();}
| E '-'{push();} E{codegen();}
| E '*'{push();} E{codegen();}
| E '/'{push();} E{codegen();}
| '(' E ')'
| '-'{push();} E{codegen_umin();} %prec UMINUS
| V
| NUM{push();}
;
V : ID {push();}
;
%%
#include "lex.yy.c"
#include<ctype.h>
char st[100][10];
int label[20];
int top=0;
char i_[2]="0"; /* for tracking count 0,1,2*/
char temp[2]="t"; /* t for three address code*/
int lno=0,ltop=0;
int lnum=0;
int start=1;
main()
{
printf("Enter the expression/program:\n");
yyparse();
}
push()
{
/* push it on the stack and increase the top count*/
strcpy(st[++top],yytext);
}
codegen()
{
strcpy(temp,"t");
strcat(temp,i_);
/* print the arithmetic expression statement*/
printf("%s = %s %s %s\n",temp,st[top-2],st[top-1],st[top]);
top-=2; /* decrement the top count by 2*/
strcpy(st[top],temp);
i_[0]++;
}
codegen_umin()
{
strcpy(temp,"t");
strcat(temp,i_);
/* print the unary minus statement*/
printf("%s = -%s\n",temp,st[top]);
top--; /* decrement the top count by 1*/
strcpy(st[top],temp);
i_[0]++;
}
codegen_assign()
{
/*print the assignment statement*/
printf("%s = %s\n",st[top-2],st[top]);
top-=2; /* decrement the top by 2*/
}
ilab1()
{
lnum++;
strcpy(temp,"t");
strcat(temp,i_); // prints negation of operands
printf("%s = not %s\n",temp,st[top]);
//checks for condition and jumps to target statement
printf("if %s goto L%d\n",temp,lnum);
i_[0]++;
label[++ltop]=lnum; //push lnum in array
}
ilab2()
{
int x;
lnum++;
x=label[ltop--];
printf("goto L%d\n",lnum); //prints jump label and target statement
printf("L%d: \n",x);
//push lnum in array
label[++ltop]=lnum;
}
ilab3()
{
int y;
y=label[ltop--];
//prints label
printf("L%d: \n",y);
}
lab1()
{
printf("L%d: \n",lno++);
}
lab2()
{
strcpy(temp,"t");
strcat(temp,i_);
printf("%s = not %s\n",temp,st[top]);
printf("if %s goto L%d\n",temp,lno);
i_[0]++;
label[++ltop]=lno;
lno++;
printf("goto L%d\n",lno);
label[++ltop]=lno;
printf("L%d: \n",++lno);
}
lab3()
{
int x;
x=label[ltop--];
printf("goto L%d \n",start);
printf("L%d: \n",x);
}
wlab1()
{
//prints while lebel 1
printf("L%d: \n",lnum++);
}
wlab2()
{
strcpy(temp,"t");
strcat(temp,i_);
printf("%s = not %s\n",temp,st[top]);
printf("if %s goto L%d\n",temp,lnum);
i_[0]++;
}
wlab3()
{
printf("goto L%d \n",start);
printf("L%d: \n",lnum);
}
lab4()
{
int x;
x=label[ltop--];
//prints goto lebel
printf("goto L%d \n",lno);
printf("L%d: \n",x);
}
/*
We save yacc code with .y extension for example "xyz.y".
save the above program.*/
/*LEX PROGRAM
*/
ALPHA [A-Za-z]
DIGIT [0-9]
%%
while return WHILE;
for return FOR;
if return IF;
then return THEN;
else return ELSE;
{ALPHA}({ALPHA}|{DIGIT})* return ID;
{DIGIT}+ {yylval=atoi(yytext); return NUM;}
"<=" return LE;
">=" return GE;
"==" return EQ;
"!=" return NE;
"||" return OR;
"&&" return AND;
[ \t] ;
\n yyterminate();
. return yytext[0];
%%
save the above program with .l extension
now to execoute the Intermediate code Generation
open your teminal and type these commands in order
lex filename.l lex.yy.c