#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define STACK_INIT_SIZE 100		// 存储空间初始分配量
#define STACKINCREMENT 10		// 存储空间分配增量
typedef int Status;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW 0				// 栈分配溢出
#define OPSETSIZE 7
// 表3.1  算符间的优先关系
unsigned char Prior[7][7] = {
		{ '>', '>', '<', '<', '<', '>', '>' },
		{ '>', '>', '<', '<', '<', '>', '>' },
		{ '>', '>', '>', '>', '<', '>', '>' },
		{ '>', '>', '>', '>', '<', '>', '>' },
		{ '<', '<', '<', '<', '<', '=',	' ' },
		{ '>', '>', '>', '>', ' ', '>', '>' },
		{ '<', '<', '<', '<', '<', ' ', '=' } };

char OPSET[OPSETSIZE]= { '+', '-', '*', '/', '(', ')', '#' };

typedef int SElemType;

typedef struct {
	SElemType * base; // 在栈构造之前和销毁之后,base的值为NULL
	SElemType * top; // 栈顶指针
	int stacksize; // 当前已分配的存储空间,以元素为单位
} SqStack;

Status InitStack(SqStack &S) {
	// 构造一个空栈
	S.base = (SElemType *) malloc(STACK_INIT_SIZE * sizeof(SElemType));
	if (!S.base)
		exit(OVERFLOW); // 存储分配失败
	S.top = S.base;
	S.stacksize = STACK_INIT_SIZE;
	return OK;
}// InitStack

SElemType GetTop(SqStack S) {
	return *(S.top - 1);
}// GetTop

Status Push(SqStack &S, SElemType e) {
	// 插入元素 e 为新的栈顶元素
	if (S.top - S.base >= S.stacksize) { //栈满,追加存储空间
		S.base = (SElemType *) realloc(S.base, (S.stacksize + STACKINCREMENT)
				* sizeof(SElemType));
		if (!S.base)
			exit(OVERFLOW); // 存储分配失败
		S.top = S.base + S.stacksize;
		S.stacksize += STACKINCREMENT;
	}
	*S.top++ = e;
	return OK;
} // Push

Status Pop(SqStack &S, SElemType &e) {
	// 若栈不为空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR
	if (S.top == S.base)
		return ERROR;
	e = *--S.top;
	return OK;
} // Pop

Status StackEmpty(SqStack S) {
	// 若栈 S 为空栈,则返回 TRUE,否则返回 FALSE
	return S.top == S.base;
} // StackEmpty

void ClearStack(SqStack &S) {
	// 将栈 S 清空
	S.top = S.base;
} // ClearStack

void DestroyStack(SqStack &S) {
	// 销毁整个栈
	while (S.top != S.base) { // 释放栈中元素的空间
		free(--S.top);
	}
	S.top = S.base = NULL;
} // DestroyStack

int Operate(int a, unsigned char theta, int b) {
	switch (theta) {
	case '+':
		return a + b;
	case '-':
		return a - b;
	case '*':
		return a * b;
	case '/':
		return a / b;
	default:
		return 0;
	}
}

Status In(char Test, char* TestOp) {
	int Find = 0;
	int i;
	for (i = 0; i < OPSETSIZE; i++) {
		if (Test == TestOp[i])
			Find = 1;
	}
	return Find;
}

int ReturnOpOrd(char op, char* TestOp) {
	int i;
	for (i = 0; i < OPSETSIZE; i++) {
		if (op == TestOp[i])
			return i;
	}
	return 0;
}

char precede(char Aop, char Bop) {
	return Prior[ReturnOpOrd(Aop, OPSET)][ReturnOpOrd(Bop, OPSET)];
}

int EvaluateExpression(char* MyExpression) { // 算法3.4
	// 算术表达式求值的算符优先算法。
	// 设OPTR和OPND分别为运算符栈和运算数栈,OP为运算符集合。
	SqStack OPTR; // 运算符栈,字符元素
	SqStack OPND; // 运算数栈,实数元素
	char TempData[20];
	int Data, a, b;
	char *c, Dr[2];
	int x, theta;

	InitStack(OPTR);
	Push(OPTR, '#');
	InitStack(OPND);
	c = MyExpression;
	strcpy(TempData, "\0");
	while (*c != '#' || GetTop(OPTR) != '#') {
		if (!In(*c, OPSET)) { // 不是运算符则进栈
			Dr[0] = *c;
			Dr[1] = '\0';
			strcat(TempData, Dr);
			c++;
			if (In(*c, OPSET)) {
				Data = atoi(TempData);
				Push(OPND, Data);
				strcpy(TempData, "\0");
			}
		} else {
			switch (precede(GetTop(OPTR), *c)) {
			case '<': // 栈顶元素优先权低
				Push(OPTR, *c);
				c++;
				break;
			case '=': // 脱括号并接收下一字符
				Pop(OPTR, x);
				c++;
				break;
			case '>': // 退栈并将运算结果入栈
				Pop(OPTR, theta);
				Pop(OPND, b);
				Pop(OPND, a);
				Push(OPND, Operate(a, theta, b));
				break;
			} // switch
		}
	} // while
	return GetTop(OPND);
} // EvaluateExpression

int main(){

	char MyExpression[100];	// 获得表达式字符串
	while(gets(MyExpression) && strlen(MyExpression)){
		printf("%d\n", EvaluateExpression(MyExpression));
	}

	return 0;
}
/**************************************************************
	Problem: 2145
	User: admin
	Language: C++
	Result: Accepted
	Time:11 ms
	Memory:1040 kb
****************************************************************/