Skip to content

GDB Input Files

lex.l file

%{
  #include  "y.tab.h"
  #include "tree.h"
  int number;
  char*temp;

%}

%%

begin     {return begin;}
end       {return END;}
break     {return BREAK;}
continue  {return CONTINUE;}
read      {return READ;}
write     {return WRITE;}
then      {return then;}
else      {return ELSE;}
endif     {return endif;}
if        {return IF;}
do        {return DO;}
endwhile  {return endwhile;}
while     {return WHILE;}
[0-9]+    {return NUM;}
[a-z]+    {yylval.p=createTree(-1,tINT,yytext,tVAR,NULL,NULL,NULL); return ID;}
"+"       {return PLUS;}
"-"       {return MINUS;}
"*"       {return MUL;}
"/"       {return DIV;}
"<="      {return LE;}
">="      {return GE;}
"<"       {return LT;}
">"       {return GT;}
"!="      {return NE;}
"=="      {return EQ;}
"="       {return ASSIGN;}
";"       {return EOL;}
[ \t]     {}
[' ']     {}
[()]      {return *yytext;}
[\n]      {}
.         {}


%%

int yywrap(void) {
  return 1;
}

parser.y file

%{
  #include #include //#define YYSTYPE tnode*
  #include "tree.h"
  #include "tree.c"
  extern struct tnode* idptr;
  FILE* targetFile;
  int yylex(void);
  extern FILE *yyin;
  extern char* yytext;
%}

%union{
  struct tnode* p;
}

%token NUM PLUS MINUS MUL DIV ID begin END READ WRITE EOL IF then ELSE endif WHILE DO endwhile GT LT LE GE NE EQ ASSIGN BREAK CONTINUE

%type expr Slist Stmt Breakstmt Continuestmt InputStmt OutputStmt AsgStmt Ifstmt Whilestmt ID

%left PLUS MINUS
%left MUL DIV
%nonassoc GT LT LE GE EQ NE
%%

Program : begin Slist END EOL  {fprintf(targetFile,"%d\n%d\n%d\n%d\n%d\n%d\n%d\n%d\nMOV SP, 4121\n",0,2056,0,0,0,0,1,0);
        //codeGen(targetFile,$2);
        infixtoprefix(targetFile,$2);
        printExit(targetFile);
        return 0;
        }
  | begin END EOL  {printf("Empty program\n;");return 0;}
  ;

Slist : Slist Stmt    {$$=createTree(-1,-1,NULL,tCONNECT,$1,$2,NULL);}
  | Stmt      {$$=$1;}
  ;

Stmt : InputStmt     {$$=$1;}
  | OutputStmt     {$$=$1;}
  | AsgStmt     {$$=$1;}
  | Ifstmt    {$$=$1;}
  | Whilestmt    {$$=$1;}
  | Breakstmt    {$$=$1;}
  | Continuestmt    {$$=$1;}
  ;

Breakstmt : BREAK EOL      {$$=createTree(-1,-1,NULL,tBREAK,NULL,NULL,NULL);}
  ;

Continuestmt : CONTINUE EOL    {$$=createTree(-1,-1,NULL,tCONTINUE,NULL,NULL,NULL);}
  ;
InputStmt : READ '(' ID ')' EOL  {$$=createTree(-1,-1,NULL,tREAD,$3,NULL,NULL);}
  ;

OutputStmt : WRITE '(' expr ')' EOL  {$$=createTree(-1,-1,NULL,tWRITE,$3,NULL,NULL);}
  ;

AsgStmt : ID ASSIGN expr EOL {$$ = createTree(-1,-1,NULL,tASSIGN,$1,$3,NULL);}
  ;
Ifstmt : IF '(' expr ')' then Slist ELSE Slist endif EOL  {$$=createTree(-1,-1,NULL,tIF,$3,$6,$8);}
  | IF '(' expr ')' then Slist endif EOL    {$$=createTree(-1,-1,NULL,tIF,$3,$6,NULL);}
  ;
Whilestmt : WHILE '(' expr ')' DO Slist endwhile EOL    {$$=createTree(-1,-1,NULL,tWHILE,$3,$6,NULL);}
  ;
expr : expr PLUS expr    {$$ = createTree(-1,-1,"+",tADD,$1,$3,NULL);}
   | expr MINUS expr    {$$ = createTree(-1,-1,"-",tSUB,$1,$3,NULL);}
   | expr MUL expr  {$$ = createTree(-1,-1,"*",tMUL,$1,$3,NULL);}
   | expr DIV expr  {$$ = createTree(-1,-1,"/",tDIV,$1,$3,NULL);}
   | '(' expr ')'  {$$ = $2;}
   | expr LT expr     {$$ = createTree(-1,-1,NULL,tLT,$1,$3,NULL);}
   | expr GT expr     {$$ = createTree(-1,-1,NULL,tGT,$1,$3,NULL);}
   | expr LE expr     {$$ = createTree(-1,-1,NULL,tLE,$1,$3,NULL);}
   | expr GE expr     {$$ = createTree(-1,-1,NULL,tGE,$1,$3,NULL);}
   | expr NE expr     {$$ = createTree(-1,-1,NULL,tNE,$1,$3,NULL);}
   | expr EQ expr    {$$ = createTree(-1,-1,NULL,tEQ,$1,$3,NULL);}
   | NUM      {$$ = createTree(atoi(yytext),tINT,NULL,tNUM,NULL,NULL,NULL);}
   | ID      {$$=$1;}
   ;

%%

yyerror(char const *s)
{
    printf("yyerror %s and %s",s,yytext);
}


int main(int argc, char*argv[]) {
  targetFile=fopen("targetFile.xsm","w");
  if(targetFile==NULL){
    printf("file error\n");
  }
  yyin=fopen(argv[1],"r");
  yyparse();
  fclose(targetFile);
  return 0;
}

infixtoprefix function

void infixtoprefix(FILE* fp, struct tnode* root){
  if(root!=NULL){
    printf("%s ",root->symbol);
    fprintf(fp,"%s ",root->symbol);
    infixtoprefix(fp,root->left);
    infixtoprefix(fp,root->right);
  }
}

input file

abc+(bcd-efg)*hij

tree.h file

This is the header file for tree.c file

#define tNUM 0
#define tVAR 1
#define tADD 2
#define tSUB 3
#define tMUL 4
#define tDIV 5
#define tREAD 6
#define tWRITE 7
#define tASSIGN 8
#define tCONNECT 9
#define tINT 10
#define tLT 11
#define tGT 12
#define tLE 13
#define tGE 14
#define tNE 15
#define tEQ 16
#define tBOOL 17
#define tWHILE 18
#define tIF 19
#define tBREAK 20
#define tCONTINUE 21
#define varLoc 4096
#define SPLoc 4121

typedef struct tnode {
  int val;                             // value of a number for NUM nodes.
  int type;                            // type of variable
  char* symbol;                        // name of a variable for ID nodes
  int nodetype;                        // information about non-leaf nodes - read/write/connector/+/* etc.
  struct tnode *left, *right, *third;  // left and right branches
} tnode;
void printExit(FILE* targetFile);
int getLabel();
int getReg();
void freeReg();
void printRead(FILE* targetFile, int varAddr);
void printWrite(FILE* targetFile, int regNum);
int getVarAddr(struct tnode* root);
int codeGen(FILE* fp, struct tnode* root);
void infixtoprefix(FILE* fp, struct tnode* root);

/*Create a node tnode*/
struct tnode* createTree(int val, int type, char* c, int nodeType, struct tnode* l, struct tnode* r, struct tnode* third);

tree.c file

This file contains the helper functions for the yacc file, like the createTree(), infixtoprefix() etc.

The yacc file imports the tree.c file and tree.h file

int reg = 0;
int label_no = 0;
int stacktop[20];  // for continue
int stackend[20];  // for break
int stack1 = -1;   // for stacktop
int stack2 = -1;   // for stackend
struct tnode* createTree(int val, int type, char* c, int nodeType, struct tnode* l, struct tnode* r, struct tnode* third) {
  switch (nodeType) {
    case tADD:
    case tSUB:
    case tMUL:
    case tDIV:
      if (l->type != r->type || l->type != tINT) {
        printf("\ntype mismatch error\n");
        exit(0);
      } else {
        type = tINT;
      }
      break;
    case tLT:
    case tGT:
    case tLE:
    case tGE:
    case tNE:
    case tEQ:
      if (l->type != r->type || l->type != tINT) {
        printf("\ntype mismatch error\n");
        exit(0);
      } else {
        type = tBOOL;
      }
      break;
    case tASSIGN:
      if (r->type != tINT || l->nodetype != tVAR) {
        printf("\ntype mismatch error\n");
        exit(0);
      }
      break;
    case tWHILE:
    case tIF:
      if (l->type != tBOOL) {
        printf("\ntype mismatch error\n");
        exit(0);
      }
      break;
  }
  struct tnode* temp;
  temp = (struct tnode*)malloc(sizeof(struct tnode));
  temp->val = val;
  temp->type = type;
  temp->symbol = c;
  temp->nodetype = nodeType;
  temp->left = l;
  temp->right = r;
  temp->third = third;
  return temp;
}

void printExit(FILE* targetFile) {
  fprintf(targetFile, "INT 10\n");
}
int getLabel() {
  int curr_label = label_no;
  label_no++;
  return curr_label;
}

int getReg() {
  int r = reg;
  reg++;
  if (r > 20) {
    printf("out of registers\n");
    exit(1);
  }
  return r;
}
void freeReg() {
  reg--;
  if (reg < 0) {
    reg = 0;
  }
}
void printRead(FILE* targetFile, int varAddr) {
  int r = getReg();
  fprintf(targetFile, "MOV R%d, \"Read\"\nPUSH R%d\nMOV R%d, -1\nPUSH R%d\nMOV R%d,%d\nPUSH R%d\nPUSH R%d\nPUSH R%d\nCALL 0\nPOP R%d\nPOP R%d\nPOP R%d\nPOP R%d\nPOP R%d\n", r, r, r, r, r, varAddr, r, r, r, r, r, r, r, r);
  freeReg();
}

void printWrite(FILE* targetFile, int regNum) {
  int r = getReg();
  fprintf(targetFile, "MOV R%d, \"Write\"\nPUSH R%d\nMOV R%d, -2\nPUSH R%d\nMOV R%d,R%d\nPUSH R%d\nPUSH R%d\nPUSH R%d\nCALL 0\nPOP R%d\nPOP R%d\nPOP R%d\nPOP R%d\nPOP R%d\nBRKP\n", r, r, r, r, r, regNum, r, r, r, r, r, r, r, r);
  freeReg();
}

int getVarAddr(struct tnode* root) {
  char* symbol = root->symbol;
  int varAddr = 4096 + (symbol[0] - 'a');
  return varAddr;
}
void infixtoprefix(FILE* fp, struct tnode* root) {
  if (root != NULL) {
    printf("%s ", root->symbol);
    fprintf(fp, "%s ", root->symbol);
    infixtoprefix(fp, root->left);
    infixtoprefix(fp, root->right);
  }
}
int codeGen(FILE* fp, struct tnode* root) {
  int r, sourceReg, destReg, varAddr, label_1, label_2, label_3;
  char* symbol;
  if (root == NULL) return -1;
  switch (root->nodetype) {
    case tCONNECT:
      codeGen(fp, root->left);
      codeGen(fp, root->right);
      return -1;
    case tREAD:
      if (root->left == NULL) {
        printf("\ninvalid read stmt\n");
        exit(0);
      }
      symbol = (root->left)->symbol;
      varAddr = 4096 + (symbol[0] - 'a');
      // printf("var addr = %d\n",varAddr);
      printRead(fp, varAddr);
      return -1;
    case tNUM:
      r = getReg();
      fprintf(fp, "MOV R%d, %d\n", r, root->val);
      return r;
    case tVAR:
      r = getReg();
      symbol = root->symbol;
      varAddr = 4096 + (symbol[0] - 'a');
      fprintf(fp, "MOV R%d,[%d]\n", r, varAddr);
      return r;
    case tWRITE:
      r = codeGen(fp, root->left);
      printWrite(fp, r);
      return -1;
    case tASSIGN:
      sourceReg = getVarAddr(root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "MOV [%d],R%d\n", sourceReg, destReg);
      return -1;
    case tADD:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "ADD R%d,R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tSUB:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "SUB R%d,R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tMUL:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "MUL R%d,R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tDIV:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "DIV R%d,R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tLT:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "LT R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tGT:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "GT R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tLE:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "LE R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tGE:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "GE R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tNE:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "NE R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tBREAK:
      if (stack2 < 0) {
        printf("\ninvalid Break statement\n");
        exit(0);
      }
      fprintf(fp, "JMP L%d\n", stackend[stack2]);
      return -1;
    case tCONTINUE:
      if (stack1 < 0) {
        printf("\ninvalid continue statement\n");
        exit(0);
      }
      fprintf(fp, "JMP L%d\n", stacktop[stack1]);
      return -1;
    case tEQ:
      sourceReg = codeGen(fp, root->left);
      destReg = codeGen(fp, root->right);
      fprintf(fp, "EQ R%d, R%d\n", sourceReg, destReg);
      freeReg();
      return sourceReg;
    case tWHILE:
      label_1 = getLabel();
      label_2 = getLabel();
      fprintf(fp, "L%d:\n", label_1);  // Place the first label here.
      stack1++;
      stacktop[stack1] = label_1;
      stack2++;
      stackend[stack2] = label_2;
      sourceReg = codeGen(fp, root->left);
      fprintf(fp, "JZ R%d, L%d\n", sourceReg, label_2);
      codeGen(fp, root->right);
      fprintf(fp, "JMP L%d\n", label_1);  // return to the beginning of the loop.
      fprintf(fp, "L%d:\n", label_2);     // Place the second label here
      stack1--;
      stack2--;
      return -1;
    case tIF:
      // label_1 = getLabel();
      if (root->third != NULL)
        label_2 = getLabel();
      label_3 = getLabel();
      // fprintf (fp, "L%d:\n", label_1); // Place the first label here.
      // if
      sourceReg = codeGen(fp, root->left);
      if (root->third != NULL)
        fprintf(fp, "JZ R%d, L%d\n", sourceReg, label_2);
      else
        fprintf(fp, "JZ R%d, L%d\n", sourceReg, label_3);
      // then
      codeGen(fp, root->right);
      fprintf(fp, "JMP L%d\n", label_3);  // jump to endif.
      // else
      if (root->third != NULL) {
        fprintf(fp, "L%d:\n", label_2);  // Place the second label here
        // else
        codeGen(fp, root->third);
        fprintf(fp, "JMP L%d\n", label_3);  // jump to endif.
      }
      fprintf(fp, "L%d:\n", label_3);  // Place the third label here
      return -1;
    default:
      printf("\nsome error in codegen fn : %d\n", root->nodetype);
      exit(0);
  }
}
Back to top