vet inte om lösningen blev så jättesnygg.. men det funkar bra! :)
#include <stdio.h>
enum expr_tag { IS_NULL, IS_INT, IS_NEG, IS_ADD, IS_MUL};
typedef struct expr {
int(*m_pfnFunc)(struct expr*, int wtdFlag, enum expr_tag, int iOrder );
union{
struct { int num; } integer;
struct { struct expr *negexpr; } negative;
struct { struct expr *expr1; struct expr *expr2; } add;
struct { struct expr *expr1; struct expr *expr2; } mul;
} u;
}expr;
int eval_expr(expr *pExpr){
eval_exprAux(pExpr, IS_NULL, 1);
}
int eval_exprAux(expr *pExpr, enum expr_tag last, int iOrder ){
return pExpr->m_pfnFunc(pExpr, 0, last, 1);
}
expr *allocExpr(){
return (expr*)malloc(sizeof(expr));
}
int exprOp_int(expr *pExpr, int wtdFlag, enum expr_tag last, int iOrder){
if (wtdFlag == 0){
printf("INT: %d\n", pExpr->u.integer.num);
return pExpr->u.integer.num;
}else{
printf("%d",pExpr->u.integer.num);
}
}
int exprOp_neg(expr *pExpr, int wtdFlag, enum expr_tag last, int iOrder){
if (wtdFlag == 0){
int val = -eval_exprAux(pExpr->u.negative.negexpr, IS_NEG, 1);
printf("NEG: %d\n", val);
return val;
}else{
if (iOrder == 1){
printf("-");
-print_exprAux(pExpr->u.negative.negexpr, IS_NEG, 1);
}else{
printf("(-");
-print_exprAux(pExpr->u.negative.negexpr, IS_NEG, 1);
printf(")");
}
}
}
int exprOp_add(expr *pExpr, int wtdFlag, enum expr_tag last, int iOrder){
if (wtdFlag == 0){
int val1 = eval_exprAux(pExpr->u.add.expr1, IS_ADD, 1);
int val2 = eval_exprAux(pExpr->u.add.expr2, IS_ADD, 2);
printf("ADD: %d + %d\n", val1, val2);
return val1 + val2;
}else{
switch(last){
case IS_MUL: case IS_NEG:{
printf("(");
print_exprAux(pExpr->u.add.expr1, IS_ADD, 1);
printf("+");
print_exprAux(pExpr->u.add.expr2, IS_ADD, 2);
printf(")");
break;
}
case IS_ADD: case IS_NULL:{
print_exprAux(pExpr->u.add.expr1, IS_ADD, 1);
printf("+");
print_exprAux(pExpr->u.add.expr2, IS_ADD, 2);
break;
}
}
}
}
int exprOp_mul(expr *pExpr, int wtdFlag, enum expr_tag last, int iOrder){
if (wtdFlag == 0){
int val1 = eval_exprAux(pExpr->u.mul.expr1, IS_MUL, 1);
int val2 = eval_exprAux(pExpr->u.mul.expr2, IS_MUL, 2);
printf("MUL: %d * %d\n", val1, val2);
return val1 * val2;
}else{
/*
switch (last){
case IS_NULL ||
}
int val1, val2;
printf("(");
val1 = print_exprAux(pExpr->u.mul.expr1, IS_MUL);
printf("*");
val2 = print_exprAux(pExpr->u.mul.expr2, IS_MUL);
printf(")");
*/
print_exprAux(pExpr->u.mul.expr1, IS_MUL, 1);
printf("*");
print_exprAux(pExpr->u.mul.expr2, IS_MUL, 2);
}
}
expr *create_expr_int(int(*pfnFunc)(struct expr*, int wtdFlag, enum expr_tag last, int iOrder), int value){
expr *pExpr = allocExpr();
pExpr->m_pfnFunc = pfnFunc;
pExpr->u.integer.num = value;
return pExpr;
}
expr *create_expr_neg(int(*pfnFunc)(struct expr*, int wtdFlag, enum expr_tag last, int iOrder), expr *pExpr1){
expr *pExpr = allocExpr();
pExpr->m_pfnFunc = pfnFunc;
pExpr->u.negative.negexpr = pExpr1;
return pExpr;
}
expr *create_expr_add(int(*pfnFunc)(struct expr*, int wtdFlag, enum expr_tag last, int iOrder), expr *pExpr1, expr *pExpr2){
expr *pExpr = allocExpr();
pExpr->m_pfnFunc = pfnFunc;
pExpr->u.add.expr1 = pExpr1;
pExpr->u.add.expr2 = pExpr2;
return pExpr;
}
expr *create_expr_mul(int(*pfnFunc)(struct expr*, int wtdFlag, enum expr_tag last, int iOrder), expr *pExpr1, expr *pExpr2){
expr *pExpr = allocExpr();
pExpr->m_pfnFunc = pfnFunc;
pExpr->u.mul.expr1 = pExpr1;
pExpr->u.mul.expr2 = pExpr2;
return pExpr;
}
expr *mk_int_expr(int value){
return create_expr_int(exprOp_int, value);
}
expr *mk_neg_expr(expr *pExpr){
return create_expr_neg(exprOp_neg, pExpr);
}
expr *mk_add_expr(expr *pExpr1, expr *pExpr2){
return create_expr_add(exprOp_add, pExpr1, pExpr2);
}
expr *mk_mul_expr(expr *pExpr1, expr *pExpr2){
return create_expr_mul(exprOp_mul, pExpr1, pExpr2);
}
print_expr(expr *pExpr){
print_exprAux(pExpr, IS_NULL, 1);
}
print_exprAux(expr *pExpr, enum expr_tag last, int iOrder){
return pExpr->m_pfnFunc(pExpr, 1, last, iOrder);
}
int main(){
//expr *pExpr = mk_mul_expr(mk_add_expr(mk_int_expr(2), mk_int_expr(3)), mk_int_expr(2));
//expr *pExpr = mk_add_expr(mk_int_expr(4),mk_neg_expr(mk_int_expr(2)));
//expr *pExpr = mk_mul_expr(mk_neg_expr(mk_add_expr(mk_int_expr(2), mk_int_expr(3))), mk_neg_expr(mk_int_expr(2)));
//expr *pExpr = mk_mul_expr(mk_add_expr(mk_int_expr(1), mk_int_expr(2)), mk_add_expr(mk_int_expr(3), mk_int_expr(4)));
expr *pExpr = mk_mul_expr(mk_neg_expr(mk_int_expr(2)),mk_mul_expr(mk_mul_expr(mk_add_expr(mk_int_expr(5), mk_int_expr(7)), mk_int_expr(2)), mk_neg_expr(mk_int_expr(1))));
;
printf("Calling eval_expr() on root expression\n");
printf("RESULT: %d\n", eval_expr(pExpr));
print_expr(pExpr);
printf("\n");
}