static int bracket_handle(struct calc_info *info) { assert(info != NULL); char opr = *info->cur; switch (opr) { case '(': OPR_PUSH(opr); break; case ')': { char top_c; while (1) { if (OPR_TOP(top_c) < 0) { fprintf(stderr, "Error:缺少左括号\n"); goto err_miss_left_bracket; } if (top_c == '(') { OPR_POP(top_c); goto out; } else { do_stack(info); } } } default: break; } out: return 0; err_miss_left_bracket: return -1; }
/* 运算时 数据栈出栈两次 操作符栈出栈一次 * 运算完之后的结果压栈 * */ static int do_operate(struct calc *calc) { num_t a, b; char c; if (NUM_POP(b) < 0) { fprintf(stderr,"Error: num pop failed.\n"); return -1; } if (NUM_POP(a) < 0) { fprintf(stderr,"Error: num pop failed.\n"); return -1; } if (OPR_POP(c) < 0) { fprintf(stderr,"Error: opr pop failed.\n"); return -2; } num_t res = 0; switch(c) { case '+': res = a + b; break; case '-': res = a - b; break; case '*': res = a * b; break; case '/': res = a / b; break; case '%': res = a % b; break; default : break; } #ifdef _DEBUG printf("DEBUG %d %c %d = %d\n",a, c, b, res); #endif NUM_PUSH(res); return 0; }
static int opr_advance(struct calc *calc) { char c = *calc->cur; int zero = 0; if (calc->pre_flag == F_NUM) { calc->pre_flag = F_OPR; } else if (calc->pre_flag == F_OPR) { if (c == '-') { NUM_PUSH(zero); OPR_PUSH(c); calc->pre_flag = F_OPR; return 0; } else if (c == '+') { return 0; } else if (c == '*') { if (OPR_POP(c)) { fprintf(stderr, "Error: opr pop error\n"); return -1; } c = '^'; OPR_PUSH(c); return 0; } else if (c == '/') { if (OPR_POP(c)) { fprintf(stderr, "Error: opr pop error\n"); return -1; } c = '#'; OPR_PUSH(c); return 0; } } else { fprintf(stderr, "unknow character\n"); return -2; } return 0; }
static int right_bracket_handler(struct calc *calc) { assert(calc != NULL); char c; while(1) { if (OPR_TOP(c) < 0) { fprintf(stderr, "Error: opr top failed\n"); return -1; } if (c == '(') { if (OPR_POP(c) < 0) { fprintf(stderr, "Error: opr pop failed\n"); return -1; } return 0; } if (do_operate(calc) < 0) { fprintf(stderr, "Error: do operate failed.\n"); return -1; } } return 0; }
/*出栈 1. 数字栈取两次 2. 运算符中取一次 3. 运算 4. 再把结果写入数字栈 */ static int do_stack(struct calc_info *info) { assert(info != NULL); num_t a, b, ret; char opr; if (NUM_POP(b) < 0) { fprintf(stderr, "num_pop failed\n"); goto err_num_pop; } if (NUM_POP(a) < 0) { fprintf(stderr, "num_pop failed\n"); goto err_num_pop; } if (OPR_POP(opr) < 0) { fprintf(stderr, "opr_pop failed\n"); goto err_opr_pop; } switch (opr) { case '+': ret = a + b; break; case '-': ret = a - b; break; case '*': ret = a * b; break; case '/': if (b == 0) { fprintf(stderr, "不能除0\n"); goto err_divd_zero; } ret = a / b; break; case '%': ret = a % b; break; default: fprintf(stderr,"取出不支持的运算符:'%c'\n", opr); break; } #ifdef DEBUG printf("%d %c %d = %d\n", a, opr, b, ret); #endif NUM_PUSH(ret); return 0; err_num_pop: return -1; err_opr_pop: return -2; err_divd_zero: return -3; }