/*
1、左递归可以用循环来实现,右递归可以用递归实现(也可以用循环实现,不过递归实现起来比较简单)
2、左递归实现左结合运算,右递归实现右结合运算
hdu 3624(网址: http://acm.hdu.edu.cn/showproblem.php?pid=3624 ) 的文法
exp -> addTerm | exp addOp addTerm
addOp -> + | -
addTerm -> mulTerm | addTerm mulOp mulTerm
mulOp -> * | / | %
mulTerm -> eTerm ^ mulTerm | eTerm
eTerm ->sNum | (exp)
sNum -> num | -eTerm
*/
#include <stdio.h>
#include <memory>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <cmath>
#include <set>
#include <queue>
#include <time.h>
#include <limits>
using namespace std;
#define vType long long
#define MAXLEN 2005
const int vMax = 0x7fffffff;
const int vMin = ~vMax;
#define checkVal(val) (val >= vMin && val <= vMax)
char str[MAXLEN];
int pos, cnt; //pos为当前扫描位置,cnt为已经分配的节点的数目
char ch; //ch为当前扫描的字符
struct treeNode{
char op, flag;
vType val;
treeNode* ch[2];
void setFlag(){
if((ch[0] && !ch[0]->flag) || (ch[1] && !ch[1]->flag)){
flag = false;
}
}
}mem[MAXLEN*10];
treeNode* exp();
inline bool isDigit(char ch){
return ch >= '0' && ch <= '9';
}
inline treeNode* newNode(){
mem[cnt].flag = true;
mem[cnt].op = ' '; //op为空格表示不需要运算
mem[cnt].ch[0] = mem[cnt].ch[1] = NULL;
return &mem[cnt++];
}
treeNode* getSyntaxTree(){
treeNode* tree;
pos = cnt = 0;
int i, j;
i = j = 0;
ch = '\n';
do{ //忽略空格
if(str[i] != ' ') str[j++] = str[i];
}while(str[i++]);
for(i = j = 0; str[i]; i++){ //加这一步是为了处理2000个(的变态数据
if(str[i] == '(') j++;
else if(str[i] == ')') j--;
}
if(j != 0){
tree = newNode();
tree->flag = false;
}else tree = exp();
return tree;
}
treeNode* eTerm(){
treeNode* t;
t = newNode();
ch = str[pos++];
if(ch == '('){
t = exp();
if(ch != ')') t->flag = false;
else ch = str[pos++];
}else if(isDigit(ch)){
vType a = ch - '0';
for(ch = str[pos++];isDigit(ch); ch = str[pos++]){
if(t->flag){
a = a * 10 + ch - '0';
}
if(!checkVal(a)){
t->flag = false;
}
}
t->val = a;
}else if(ch == '-'){
t->op = ch;
t->ch[0] = newNode();
t->ch[0]->val = 0;
t->ch[1] = eTerm();
t->setFlag();
}else t->flag = false;
return t;
}
treeNode* mulTerm(){
treeNode *t, *p, *r, *t0, *t1;;
r = t = eTerm();
p = NULL;
while(ch == '^'){ //循环实现右递归文法
t1 = newNode();
t1->op = ch;
t1->ch[0] = t;
t0 = eTerm();
t1->ch[1] = t0;
if(p){
p->ch[1] = t1;
}else r = t1;
p = t1;
t = t0;
}
return r;
}
treeNode* addTerm(){
treeNode *t, *p;
t = newNode();
t->ch[0] = mulTerm();
t->setFlag();
while(ch == '*' || ch == '/' || ch == '%'){
t->op = ch;
t->ch[1] = mulTerm();
t->setFlag();
p = t;
t = newNode();
t->ch[0] = p;
}
return t;
}
treeNode* exp(){
treeNode *t, *p;
t = newNode();
t->ch[0] = addTerm();
while(ch == '-' || ch == '+'){
t->op = ch;
t->ch[1] = addTerm();
p = t;
t = newNode();
t->ch[0] = p;
}
return t;
}
void cal(treeNode* root){
if(!root) return;
cal(root->ch[0]);
cal(root->ch[1]);
root->setFlag();
if(!root->flag) return;
if(root->op != ' '){
vType a = 0;
switch(root->op){
case '-':
a = root->ch[0]->val - root->ch[1]->val;
break;
case '+':
a = root->ch[0]->val + root->ch[1]->val;
break;
case '*':
a = root->ch[0]->val * root->ch[1]->val;
break;
case '/':
if(root->ch[1]->val == 0){
root->flag = false;
return;
}
a = root->ch[0]->val / root->ch[1]->val;
break;
case '%':
if(root->ch[1]->val == 0){
root->flag = 0;
return;
}
a = root->ch[0]->val % root->ch[1]->val;
break;
case '^':
if(root->ch[1]->val < 0 || (root->ch[0]->val == 0 && root->ch[1]->val == 0)){
root->flag = false;
return;
}
double b = pow((double)root->ch[0]->val, (double)root->ch[1]->val);
if(checkVal(b)) a = (vType)b;
else{
root->flag = false;
return;
}
break;
}
if(checkVal(a)){
root->val = a;
root->setFlag();
}else{
root->flag = false;
}
}else if(root->ch[0]){
root->flag = root->ch[0]->flag;
root->val = root->ch[0]->val;
}
}
int main(){
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
int i, c;
treeNode* root;
scanf("%d", &c);
getchar();
for(i = 1; i <= c; i++){
gets(str);
root = getSyntaxTree();
printf("Case %d: ", i);
cal(root);
if(root->flag){
printf("%I64d\n", root->val);
}
else printf("ERROR!\n");
}
return 0;
}