Tuesday, April 14, 2015

Intermediate code generator

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






No comments:

Post a Comment

Contributors

Translate