Flex.and.Bison.Examples/examples/example.05/astsrc.cpp
Source: Flex.and.Bison.Examples/examples/example.05/astsrc.cpp
#include "astheader.hpp"
#include<iostream>
#include<cstdlib>
#include<cstdarg>
AST *createAst(int node_type, AST *l, AST *r) {
AST *a = new AST(node_type, l, r, 0);
if(!a) {
std::cerr << "Out of space...\n";
exit(EXIT_FAILURE);
}
return a;
}
AST *createNum(double d) {
AST *n = new AST('K', d);
if(!n) {
std::cerr << "Error couldn't allocate memory..\n";
exit(EXIT_FAILURE);
}
return n;
}
double eval(AST *ast) {
if(!ast) return 0;
double v = 0;
switch(ast->node_type) {
case 'K': {
v = ast->number;
return v;
}
case '+':
v = eval(ast->left) + eval(ast->right);
break;
case '-':
v = eval(ast->left) - eval(ast->right);
break;
case '*':
v = eval(ast->left) * eval(ast->right);
break;
case '/':
v = eval(ast->left) / eval(ast->right);
break;
case '|':
v = eval(ast->left);
if(v < 0) v = -v;
break;
case 'M':
v = -eval(ast->left);
break;
default:
yyerror("Error reached invalid node type: %d \n", ast->node_type);
break;
}
return v;
}
void freeAst(AST *node) {
switch(node->node_type) {
case '+':
case '-':
case '*':
case '/':
freeAst(node->right);
case '|':
case 'M':
freeAst(node->left);
case 'K':
delete node;
break;
default:
std::cerr << "Error invalid node: " << node->node_type << "\n";
break;
}
}
void yyerror(const char *src, ...) {
va_list ap;
va_start(ap, src);
fprintf(stderr, "%d: error ", yylineno);
vfprintf(stderr, src, ap);
fprintf(stderr, "\n");
}