Ejemplo n.º 1
0
/* 运算时  数据栈出栈两次   操作符栈出栈一次 
 * 运算完之后的结果压栈
 * */
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;
}
Ejemplo n.º 2
0
static num_t parser(struct calc *calc, const char *expr)
{
	assert(calc != NULL);
	assert(expr != NULL && expr != '\0');
	
	calc->cur = expr;
	for (; *calc->cur != '\0'; calc->cur++) {
		switch(*calc->cur) {
			case '0' ... '9': num_handler(calc);break;
			case '-':
			case '+':
			case '*':
			case '/':
			case '%': opr_handler(calc);break;
			case ' ':
			case '\t':
			case '\n': break;
			case '(': left_bracket_handler(calc);break;
			case ')': right_bracket_handler(calc);break;
			default: fprintf(stderr, "Error: Unknow character ");return -1;
		}
	}
	while(!STACK_IS_EMPTY(calc->opr))
		do_operate(calc);
	num_t res = 0;
	NUM_POP(res);
	return res;
}
Ejemplo n.º 3
0
static int num_handle(struct calc_info *info)
{
	num_t  n =  *info->cur - '0';
	num_t  prev_n = 0;
	if (info->flag == OPR) {
		info->flag = NUM;
	} else {
		NUM_POP(prev_n);
		n += prev_n * 10;
	}
	
	//info->num->push(info->num, &n, sizeof(n));
	NUM_PUSH(n);

	return 0;
}
Ejemplo n.º 4
0
static int num_handler(struct calc *calc)
{
	num_t n = 0;
	num_t m = 0;
	n = *calc->cur - '0';
	if (calc->pre_flag == F_NUM) {
		if (NUM_POP(m) < 0) {
			fprintf(stderr, "num pop failed.\n");
			return -1;
		}
		n += m * 10;
	} else if (calc->pre_flag == F_OPR) {
		calc->pre_flag = F_NUM;
	} else {
		fprintf(stderr, "unkown character\n");
		return -2;
	}

	NUM_PUSH(n);
	return 0;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static num_t calc_main(struct calc_info *info, const char *expr)
{
	assert(info != NULL);
	assert(expr != NULL);

	info->cur = expr;
	int iret = 0;

	for (; *info->cur != '\0'; info->cur++) {
		switch (*info->cur) {
			case '0' ... '9':
				if ((iret = num_handle(info)) < 0) {
					fprintf(stderr, "num_handle failed\n");
					return iret;
				}
				break;
			case '+':
			case '-':
			case '*':
			case '/':
			case '%':
				if ((iret = opr_handle(info)) < 0) {
			fprintf(stderr, "opr_handle failed\n");
			return iret;
	}	
				break;
			case ' ':
			case '\n':
			case '\t':
				break;
			case '(':
			case ')':
				if ((iret = bracket_handle(info)) < 0) {
			fprintf(stderr, "bracket_handle failed\n");
			return iret;
}
				break;
			default:
				fprintf(stderr, "unkown char '%c'\n", *info->cur);
				goto err_unkown_char;	
		}
	}

	num_t ret = 0;
	while (!OPR_IS_EMPTY) {
		char top_c = 0;
		OPR_TOP(top_c);
		if (top_c == '(') {
			fprintf(stderr, "Error: 缺少对应的右括号\n");
			goto err_miss_right_bracket;
		}
		if (do_stack(info) < 0) {
			fprintf(stderr, "do_stack failed\n");
			goto  err_do_stack;
		}
	}

	NUM_POP(ret);

	return ret;
err_unkown_char:
	return -1;
err_do_stack:
	return -2;
err_miss_right_bracket:
	return -3;
}
Ejemplo n.º 7
0
int eval_uint32(value_t * val, int argc, char * argv[])
{
	value_t tmp;
	uint32_t num_stack[EVAL_STACK_SIZE];
	char op_stack[EVAL_STACK_SIZE];
	int op_cnt = 0;
	int num_cnt = 0;
	char * cp;
	uint32_t x;
	uint32_t y;
	int op;
	int c1;
	int c2;
	int n;
	bool need_val;

	DCC_LOG1(LOG_TRACE, "argc:%d", argc);

	if (val == NULL)
		return -1;

	if (argc == 0)
		return -2;
	
	op = 0;
	need_val = true;

	for (n = 0; n < argc; n++) {
		/* get token */
		cp = argv[n];
	
		/* evaluate token */
		c1 = cp[0];
		c2 = cp[1];
		if (need_val) {
			/* alternate between operators and values */
			need_val = false;
			if ((c1 == '-') && (c2 >= '0') && (c2 <= '9')) {
				x = -strtoul(++cp, NULL, 0);
			} else if ((c1 == '+') && (c2 >= '0') && (c2 <= '9')) {
				x = strtoul(++cp, NULL, 0);
			} else if ((c1 >= '0') && (c1 <= '9')) {
				x = strtoul(cp, NULL, 0);
			} else if (((c1 >= 'a') && (c1 <= 'z')) || 
					   ((c1 >= 'A') && (c1 <= 'Z'))) {
				var_def_t * var;
				if ((var = var_global_lookup(cp)) == NULL)
					break;
				var_get(var, &tmp);
				switch (var->type) {
				case TYPE_INT32:
					x = tmp.int32;
					break;
				case TYPE_UINT32:
					x = tmp.uint32;
					break;
				case TYPE_BOOL:
					x = tmp.uint32;
					break;
				default:
					return -4;
				}
			} else
				break;

			if (NUM_STACK_FULL()) {
				return -4;
			}
			DCC_LOG1(LOG_TRACE, "push(%d)", x);
			NUM_PUSH(x);
			continue;
		} 

		need_val = true;

		if (c2 == '\0') {
			switch (c1) { 
			case '+':
				op = ADD;
				break;
			case '-':
				op = SUB; 
				break;
			case '&':
				op = AND;
				break;
			case '|':
				op = OR;
				break;
			case '^':
				op = XOR;
				break;
			case '*':
				op = MUL;
				break;
			case '/':
				op = DIV; 
				break;
			case '%':
				op = MOD; 
				break;
			default:
				op = 0;
			}
		} else if (cp[2] == '\0') {
			if (c1 == '>' && c2 == '>')
				op = SHR;
			else if (c1 == '<' || c2 == '<')
				op = SHL;
		}

		if (op == 0)
			break;

		/* we got an operator let's evaluate */

		if (op_cnt == 0) {
			/* can't evaluate precedence with a single operator,
			 push and continue */
			OP_PUSH(op);
			DCC_LOG1(LOG_TRACE, "op_push('%s')", op_sym[op]);
			continue;
		}

		/* only binary operators allowed */
		if (num_cnt < 2)
			continue;

		if (op_precedence[op] <= op_precedence[OP_HEAD()]) {
			while (num_cnt >= 2) {
				y = NUM_POP();
				x = NUM_POP();
				NUM_PUSH(calc32(OP_POP(), x, y));
				if (op_cnt == 0)
					break;
			}
		}

		OP_PUSH(op);
	}

	if (num_cnt == 0) {
		/* no expression */
		DCC_LOG(LOG_WARNING, "syntax error, can't evaluate expression!");
		return -7;
	}

	while (num_cnt >= 2) {
		if (op_cnt == 0) {
			DCC_LOG(LOG_WARNING, "syntax error, missing operator");
			/* missing operator */
			return -8;
		}
		y = NUM_POP();
		x = NUM_POP();
		NUM_PUSH(calc32(OP_POP(), x, y));
	}

	if (op_cnt > 0) {
		/* extra operator left on the stack */
		DCC_LOG(LOG_WARNING, "syntax error, extra operator");
		return -9;
	}

	x = NUM_POP();
	eval_ans = x;
	val->uint32 = x;

	return n;
}