Jag har skrivit en datastruktur med dess funktioner för att hantera och räkna ut enkla aritmetiska uttryck. Den tar heltalskonstanter, negation, addition och multiplikation. Använder funktionspekare när jag skapar ett uttryck. Nu är problemet ett jag ska även kunna skriva ut ett uppbyggt uttryck. Jag har nästan fått det att funka. Eller rättare sagt, det fungerar, men det blir onödigt många paranteser, det är tänkt att den bara ska skriva ut de paranteser som är nödvändiga.
T.ex (2+3)*2 är bra, men inte ((2+3)*(2)).. osv
Några tips på hur jag ska lösa problemet? Jag antar att jag är tvungen att titta i förväg hur resten av deluttrycket ser ut för att veta om paranteser är nödvändigt, men då jag använder funktionspekare och inte taggar så ser jag ju inte vad ett uttryck är av för typ (INT, NEG, ADD eller MUL).
Det är en j*vla massa kod men jag hoppas nån har lust att kolla och hjälpa mej.
Koden:
#include <stdio.h>
typedef struct expr {
int(*m_pfnFunc)(struct expr*, int wtdFlag);
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){
return pExpr->m_pfnFunc(pExpr, 0);
}
expr *allocExpr(){
return (expr*)malloc(sizeof(expr));
}
int exprOp_int(expr *pExpr, int wtdFlag){
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){
if (wtdFlag == 0){
int val = -eval_expr(pExpr->u.negative.negexpr);
printf("NEG: %d\n", val);
return val;
}else{
int val;
printf("-(");
val = -print_expr(pExpr->u.negative.negexpr);
printf(")");
}
}
int exprOp_add(expr *pExpr, int wtdFlag){
if (wtdFlag == 0){
int val1 = eval_expr(pExpr->u.add.expr1);
int val2 = eval_expr(pExpr->u.add.expr2);
printf("ADD: %d + %d\n", val1, val2);
return val1 + val2;
}else{
int val1, val2;
printf("(");
val1 = print_expr(pExpr->u.add.expr1);
printf("+");
val2 = print_expr(pExpr->u.add.expr2);
printf(")");
}
}
int exprOp_mul(expr *pExpr, int wtdFlag){
if (wtdFlag == 0){
int val1 = eval_expr(pExpr->u.mul.expr1);
int val2 = eval_expr(pExpr->u.mul.expr2);
printf("MUL: %d * %d\n", val1, val2);
return val1 * val2;
}else{
int val1, val2;
printf("(");
val1 = print_expr(pExpr->u.mul.expr1);
printf("*");
val2 = print_expr(pExpr->u.mul.expr2);
printf(")");
}
}
expr *create_expr_int(int(*pfnFunc)(struct expr*, int wtdFlag), 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), 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), 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), 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){
return pExpr->m_pfnFunc(pExpr, 1);
}
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_neg_expr(mk_int_expr(2)), mk_int_expr(4));
//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)));
printf("Calling eval_expr() on root expression\n");
printf("RESULT: %d\n", eval_expr(pExpr));
print_expr(pExpr);
printf("\n");
}