#include #include #include "syntree.h" #include "y.tab.h" /* funkcija za prijavljivanje greske */ int yyerror(char* s) { return fprintf(stderr, "%s", s); } /* alokacija cvora */ nodeType* allocNode() { nodeType *p; /* alokacija cvora */ if ((p = malloc(sizeof(nodeType))) == NULL) yyerror("out of memory"); return p; } /* Kreiranje cvora konstante sa datom vrednoscu */ nodeType* con(int value) { nodeType* p = allocNode(); p->type = typeCon; /* Tip cvora je tip konstante */ p->con.value = value; /* Vrednost konstante je prosledjena kao parametar */ return p; } /* Kreiranje cvora promenljive sa datim celobrojnim indeksom */ nodeType *id(int i) { nodeType *p = allocNode(); p->type = typeId; /* Tip cvora je cvor promenljive */ p->id.i = i; /* indeks promenljive je dat kao parametar */ return p; } /* Kreiranje cvora binarnog operatora oper sa data dva operanda */ nodeType* binOp(int oper, nodeType* op1, nodeType* op2) { nodeType* p = allocNode(); p->type = typeOpr; /* Tip cvora je cvor operanda */ p->opr.oper = oper; /* Operator je dat kao parametar */ p->opr.nops = 2; /* Operator je binaran */ /* Alokacija niza operanada */ if ((p->opr.op = malloc(2*sizeof(nodeType*))) == NULL) yyerror("out of memory"); /* Postavljanje operanada */ p->opr.op[0] = op1; p->opr.op[1] = op2; return p; } /* Kreiranje cvora binarnog operatora oper sa data dva operanda */ nodeType* unOp(int oper, nodeType* op1) { nodeType* p = allocNode(); p->type = typeOpr; /* Tip cvora je cvor operanda */ p->opr.oper = oper; /* Operator je dat kao parametar */ p->opr.nops = 1; /* Operator je binaran */ /* Alokacija niza operanada */ if ((p->opr.op = malloc(2*sizeof(nodeType*))) == NULL) yyerror("out of memory"); /* Postavljanje operanada */ p->opr.op[0] = op1; return p; } /* Ispis cvora stabla na datom nivou nazubljivanja */ void print_(nodeType* p, int level) { /* nazubljuemo do dubine level */ int k; for (k = 0; k < level; k++) putchar(' '); /* analiziramo tip cvora */ switch(p->type) { case typeCon: /* cvor konstante */ printf("Con: %d\n", p->con.value); break; case typeId: /* cvor promenljive */ printf("Id: %c\n", 'a' + p->id.i); break; case typeOpr: /* cvor operatora */ if (p->opr.oper < 128) printf("Op %c\n", p->opr.oper); else printf("Op %d\n", p->opr.oper); /* rekurzivno ispisujemo operande na narednom nivou nazubljivanja */ for (k = 0; k < p->opr.nops; k++) print_(p->opr.op[k], level+1); break; } } /* Ispis sintaksnog stabla (korisno samo za debagovanje) */ void print(nodeType* p) { print_(p, 0); } /* brisanje drveta */ void freeNode(nodeType* n) { if (n->type == typeOpr) { int i; for (i = 0; i < n->opr.nops; i++) freeNode(n->opr.op[i]); } free(n); } /* Interpretacija stabla (za izraze to je izracunavanje vrednosti) */ /* table je tablica u kojoj se cuvaju vrednosti 26 promenljivih */ int interpret(nodeType* p, int table[]) { /* analiziramo vrstu cvora */ switch(p->type) { case typeCon: /* vrednost konstante je zapisana u njenom cvoru */ return p->con.value; case typeId: /* vrednost promenljive citamo iz date tablice */ return table[p->id.i]; case typeOpr: { if (p->opr.oper == PRINT) { /* naredba PRINT */ printf("%d\n", interpret(p->opr.op[0], table)); } else if (p->opr.oper == '=') { /* operator dodele */ /* izracunavamo vrednost desne strane dodele i postavljamo je u tablicu, na mesto promenljive sa leve strane dodele */ int d = interpret(p->opr.op[1], table); int i = p->opr.op[0]->id.i; table[i] = d; return d; } else if (p->opr.oper == ';') { interpret(p->opr.op[0], table); interpret(p->opr.op[1], table); } else if (p->opr.oper == WHILE) { while (interpret(p->opr.op[0], table)) interpret(p->opr.op[1], table); } else { /* binarni aritmeticki operatori */ /* rekurzivno izracunavamo vrednost operanada */ int l = interpret(p->opr.op[0], table); int d = interpret(p->opr.op[1], table); /* primenjujemo odgovarajuci operator */ switch(p->opr.oper) { case '+': return l + d; case '*': return l * d; case '<': return l < d; case '>': return l > d; } } } } return 0; }