uint32_t eval(int p, int q, bool *success) { if(p > q) { printf("Bad expression!\n"); *success = false; return 0; } else if(p == q) { uint32_t val; if(tokens[p].type == DINT) sscanf(tokens[p].str, "%d", &val); else if(tokens[p].type == HINT) sscanf(tokens[p].str, "%x", &val); else if(tokens[p].type == REG) val = get_register(tokens[p].str); else if(tokens[p].type == VAR) { Exp_flag = 1; val = find_var(tokens[p].str); if(val == -1) { printf("No var matched!\n"); *success = false; return 0; } } else { printf("No number matched!\n"); *success = false; return 0; } return val; } else if(check_parentheses(p, q, success) == true) { return eval(p + 1, q - 1, success); } else if(*success == true) { int op = find_dominant_operator(p, q); //printf("%d\n", op); int op_type = tokens[op].type; uint32_t val1, val2; if(op_type == NOT || op_type == DEREF) { val1 = eval(op+1, q, success); val2 = eval(op+1, q, success); } else { val1 = eval(p, op-1, success); val2 = eval(op+1, q, success); } switch(op_type) { case '+': return val1 + val2; case '-': return val1 - val2; case '*': return val1 * val2; case '/': return val1 / val2; case EQ: return val1 == val2; case UEQ: return val1 != val2; case AND: return val1 && val2; case OR: return val1 || val2; case NOT: return !val2; case DEREF: return swaddr_read(val2, 4,R_DS); default: *success = false; printf("Cannot evaluate expression!\n"); return 0; } } else { return 0; } }
bool check_legal(int p,int q) { if(tokens[p].type=='(' && tokens[q].type==')' && check_parentheses(p+1,q-1)==true) return true; else return false; }
int main() { char sz_paren[SIZE_BUF]; char garbage; int cnt_case, idx_case, dummy; dummy = scanf("%d%c", &cnt_case, &garbage); for (idx_case = 0 ; idx_case < cnt_case ; idx_case++) { char *sz_dummy = fgets(sz_paren, SIZE_BUF, stdin); bool b_legal = check_parentheses(sz_paren); if (b_legal) printf("Yes\n"); else printf("No\n"); } return 0; }
int eval(int p,int q) { int val=0; int j; if(p>q) assert(0); else if(p==q) { char *rec=NULL; char temp[5]; switch(tokens[p].type) { case NUM: return atoi(tokens[p].str);break; case HEX: return strtoll(tokens[p].str,&rec,16);break; case REG: strcpy(temp,tokens[p].str); if(!strcmp(temp,"$eax"))return cpu.eax; else if(!strcmp(temp,"$ecx")) return cpu.ecx; else if(!strcmp(temp,"$edx")) return cpu.edx; else if(!strcmp(temp,"$ebx")) return cpu.ebx; else if(!strcmp(temp,"$esp")) return cpu.esp; else if(!strcmp(temp,"$eip")) return cpu.eip; else if(!strcmp(temp,"$edi")) return cpu.edi; else if(!strcmp(temp,"$esi")) return cpu.esi; else if(!strcmp(temp,"$ebp")) return cpu.ebp; else if(!strcmp(temp,"$al")) return reg_w(R_AX); else if(!strcmp(temp,"$ah")) return reg_w(R_AH); else if(!strcmp(temp,"$bl")) return reg_w(R_BL); else if(!strcmp(temp,"bh")) return reg_w(R_BH); else if(!strcmp(temp,"cl")) return reg_w(R_CL); else if(!strcmp(temp,"ch")) return reg_w(R_CH); else if(!strcmp(temp,"$dl")) return reg_w(R_DL); else if(!strcmp(temp,"$dh")) return reg_w(R_DH); else if(!strcmp(temp,"$eflags")) return cpu.EFLAGS; else if(!strcmp(temp,"$es")) return cpu.es; else if(!strcmp(temp,"$cs")) return cpu.cs; else if(!strcmp(temp,"$ss")) return cpu.ss; else if(!strcmp(temp,"$ds")) return cpu.ds; case TOK: for(j = 0;j < nr_symtab_entry ; j++) { //if(symtab[j].st_info == 0x11) //{ if(!strcmp (&strtab[symtab[j].st_name] , tokens[p].str)) return symtab[j].st_value; //} //else if(symtab[j].st_info == 0x12) //{ // if(!strcmp (&strtab[symtab[j].st_name] , tokens[p].str)) // return symtab[j].st_value; // } } } } else if(check_parentheses(p,q)==true) return eval(p+1,q-1); else { int val1=0; int val2=0; int op=dominate_operate(p,q); if(tokens[op].type==NEG) { if(op!=0) { op--; val1=eval(p,op-1); val2=-eval(op+2,q); } else { val=-eval(op+1,q); } } else if(tokens[op].type==POINTER) { if(op!=0) { op--; val1=eval(p,op-1); val2=swaddr_read(eval(op+2,q),4); } else val=swaddr_read(eval(op+1,q),4); } else if(tokens[op].type==NOT) { if(op!=0) { op--; val1=eval(p,op-1); val2=!eval(op+2,q); } else val=!eval(op+1,q); } else if(tokens[op].type==BIT_NOT) { if(op!=0) { op--; val1=eval(p,op-1); val2=~eval(op+2,q); } else val=~eval(op+1,q); } else { val1=eval(p,op-1); val2=eval(op+1,q); switch(tokens[op].type) { case ADD: val= val1+val2; break; case SUB: val= val1-val2; break; case MUL: val= val1*val2; break; case DIV: if(val2==0) assert(0); else val= val1/val2; break; case RSHIFT: val= val1>>val2; break; case LSHIFT: val= val1<<val2; break; case LS: val= val1<val2; break; case GT: val= val1>val2; break; case GE: val= val1>=val2; break; case LE: val= val1<=val2; break; case NE: val= val1!=val2; break; case EQ: val= val1== val2; break; case BIT_AND: val= val1&val2; break; case BIT_XOR: val= val1^val2; break; case BIT_OR: val= val1|val2; break; case AND: val= val1&&val2; break; case OR: val= val1||val2; break; } } } return val; }
int eval( int p, int q ){ bool legal = true; if( p > q ){ printf("160 Bad expression!\n"); assert(0); } else if( p == q ){ /* Single token. * For now this token should be a number * Return the value of the number */ int val = -256; int i; char * reg_name[] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"}; switch ( tokens[p].type ){ case HEX: sscanf( tokens[p].str, "%x", &val ); break; case DEC: sscanf( tokens[p].str, "%d", &val ); break; case REG: for( i = 0; i < 8; i ++ ){ if( strcmp( tokens[p].str, reg_name[i] ) == 0 ){ val = cpu.gpr[i]._32; break; } } break; case SYM: val = tokens[p].addr; break; default: assert(0); } return val; } else if( check_parentheses( p, q, &legal ) == true ){ /* The expression is surrounded by a matched pair of parentheses * If that is the case, just throw away the paretheneses */ return eval( p + 1, q - 1 ); } else{ /* We should do more things here */ if( legal == false ) { printf("193 Bad expression!\n"); assert(0); } /*===============================================*/ int prior_arr[32]; // find maximum in it int locate[32]; int i, j, num; for( i = q, num = 0; i >= p; i -- ){ if( prior[ tokens[i].type ] > -3 ){ if( tokens[i].type == RPA ){ for( j = i - 1; check_parentheses( j, i, &legal ) == false; j -- ); i = j; } else{ prior_arr[num] = prior[ tokens[i].type ]; locate[num] = i; num ++; } } } for( i = 0, j = 0; i < num; i ++ ){ j = ( prior_arr[i] > prior_arr[j] ) ? i : j; } int op = locate[j]; /*===============================================*/ int val2 = eval( op + 1, q ); switch( tokens[op].type ){ case ADD: return eval( p, op - 1 ) + val2; break; case SUB: return eval( p, op - 1 ) - val2; break; case MUL: return eval( p, op - 1 ) * val2; break; case DIV: return eval( p, op - 1 ) / val2; break; case EQ: return (eval( p, op - 1 ) == val2); break; case NEQ: return (eval( p, op - 1 ) != val2); break; case AND: return (eval( p, op - 1 ) && val2); break; case OR: return (eval( p, op - 1 ) || val2); break; /*===============================================*/ case NOT: return !(val2); break; case NEG: return -1 * val2; break; case PTR: return swaddr_read( val2, 4 ); break; default: assert(0); } } }
uint32_t eval(int p,int q) { expr_ok=true; int dominant=0; //printf("%d %d\n",p,q); if(p>q){ printf("This is a bad expression\n"); expr_ok=false; return 0; } else if(p==q){ if(tokens[p].type==NUMBER) return atoi(tokens[p].str); else if(tokens[p].type==HEX) { char *hexnum=tokens[p].str+2; uint32_t sum=0,temp=0; int i; for(i=0;hexnum[i]!='\0';i++) { if(hexnum[i]>='0' && hexnum[i]<='9') temp=hexnum[i]-'0'; else if(hexnum[i]>='a' && hexnum[i]<='f') temp=hexnum[i]-'a'+10; sum=sum*16+temp; } return sum; } /*************** VAR NOT DONE **********************/ else if(tokens[p].type==VAR) { uint32_t addr=0; addr=find_addr(tokens[p].str,&is_obj); if(!is_obj) printf("NO SUCH OBJECT!\n"); return addr; //printf("test %2x\n",addr); } /*************** VAR NOT DONE **********************/ else if(tokens[p].type==REG) { reg_right=true; if(strcmp(tokens[p].str,"$eax")==0) return cpu.eax; else if(strcmp(tokens[p].str,"$ecx")==0) return cpu.ecx; else if(strcmp(tokens[p].str,"$edx")==0) return cpu.edx; else if(strcmp(tokens[p].str,"$ebx")==0) return cpu.ebx; else if(strcmp(tokens[p].str,"$esp")==0) return cpu.esp; else if(strcmp(tokens[p].str,"$ebp")==0) return cpu.ebp; else if(strcmp(tokens[p].str,"$esi")==0) return cpu.esi; else if(strcmp(tokens[p].str,"$edi")==0) return cpu.edi; else if(strcmp(tokens[p].str,"$eip")==0) return cpu.eip; else { printf("NO SUCH REGISTER!\n"); expr_ok=false; reg_right=false; return 0; } } else if(tokens[p].type==SREG) { if(strcmp(tokens[p].str,"$ES")==0) return cpu.sreg[0].Sreg; else if(strcmp(tokens[p].str,"$CS")==0) return cpu.sreg[1].Sreg; else if(strcmp(tokens[p].str,"$SS")==0) return cpu.sreg[2].Sreg; else if(strcmp(tokens[p].str,"$DS")==0) return cpu.sreg[3].Sreg; else { printf("A Bad expression!\n"); expr_ok=false; return 0; } } else if(tokens[p].type==EFLAGS) { if(strcmp(tokens[p].str,"$OF")==0) return cpu.OF; else if(strcmp(tokens[p].str,"$SF")==0) return cpu.SF; else if(strcmp(tokens[p].str,"$ZF")==0) return cpu.ZF; else if(strcmp(tokens[p].str,"$AF")==0) return cpu.AF; else if(strcmp(tokens[p].str,"$PF")==0) return cpu.PF; else if(strcmp(tokens[p].str,"$CF")==0) return cpu.CF; } else { printf("A Bad expression!\n"); expr_ok=false; return 0; } } bool check=check_parentheses(p,q); if(!check) { printf("The parentheses not match!\n"); expr_ok=false; return 0; } else if(check) { bool legal; legal=check_legal(p,q); if(legal) return eval(p+1,q-1); else { dominant=find_domiop(p,q); if(tokens[dominant].type==LOGNOT) { int val3=eval(dominant+1,q); return !val3; } else if(tokens[dominant].type==DEREF) { int val4=eval(dominant+1,q); uint32_t value=swaddr_read(val4,4,3); return value; } else { int val1=eval(p,dominant-1); if(expr_ok==false) return 0; int val2=eval(dominant+1,q); if(expr_ok==false) return 0; switch(tokens[dominant].type) { case '+':return val1+val2; case '-':return val1-val2; case '*':return val1*val2; case '/':return val1/val2; case EQ:return val1==val2; case NEQ:return val1!=val2; case LOGAND:return val1&&val2; case LOGOR:return val1||val2; default: assert(0); } } } } return 0; }
uint32_t eval(int p, int q) { if (!valid) return 0; #ifdef DDEBUG printf("p=%d\tq=%d\n",p,q); #endif if (p>q){ /* Bad expression */ //Assert(p<q,"Bad expression"); printf(RED"Bad expression.\n"NONE); valid=false; return 0; } else if (p==q){ /*Single token *For now this token should be a number. *Return the value of the number. */ int num=0; if (tokens[p].type==DEC){ num=atoi(tokens[p].str); //printf("%d:%d\t%s\n",p,num,tokens[p].str); }else if (tokens[p].type==HEX){ sscanf(tokens[p].str,"%x",&num); }else{ //tokens[nr_token].type=DEC; char *s=tokens[p].str; //int reg; if (strcmp(s,"$eax")==0) num=cpu.eax; else if (strcmp(s,"$ebx")==0) num=cpu.ebx; else if (strcmp(s,"$ecx")==0) num=cpu.ecx; else if (strcmp(s,"$edx")==0) num=cpu.edx; else if (strcmp(s,"$esp")==0) num=cpu.esp; else if (strcmp(s,"$ebp")==0) num=cpu.ebp; else if (strcmp(s,"$esi")==0) num=cpu.esi; else if (strcmp(s,"$edi")==0) num=cpu.edi; else if (strcmp(s,"$eip")==0) num=cpu.eip; else if (strcmp(s,"$ax") ==0) num=cpu.gpr[0]._16; else if (strcmp(s,"$cx") ==0) num=cpu.gpr[1]._16; else if (strcmp(s,"$dx") ==0) num=cpu.gpr[2]._16; else if (strcmp(s,"$bx") ==0) num=cpu.gpr[3]._16; else if (strcmp(s,"$sp") ==0) num=cpu.gpr[4]._16; else if (strcmp(s,"$bp") ==0) num=cpu.gpr[5]._16; else if (strcmp(s,"$si") ==0) num=cpu.gpr[6]._16; else if (strcmp(s,"$di") ==0) num=cpu.gpr[7]._16; else if (strcmp(s,"$al") ==0) num=cpu.gpr[0]._8[0]; else if (strcmp(s,"$cl") ==0) num=cpu.gpr[1]._8[0]; else if (strcmp(s,"$dl") ==0) num=cpu.gpr[2]._8[0]; else if (strcmp(s,"$bl") ==0) num=cpu.gpr[3]._8[0]; else if (strcmp(s,"$ah") ==0) num=cpu.gpr[4]._8[1]; else if (strcmp(s,"$ch") ==0) num=cpu.gpr[5]._8[1]; else if (strcmp(s,"$dh") ==0) num=cpu.gpr[6]._8[1]; else if (strcmp(s,"$bh") ==0) num=cpu.gpr[7]._8[1]; else{ printf(RED"Invaild Expression!\nNot a number.\n"NONE); //assert(0); valid=false; return 0; } } return num; } else if (check_parentheses(p,q)==true){ //printf("ok\n"); if (!valid)return 0; return eval(p+1,q-1); } else{ int op=0;bool is_binary=true; op=locate_domin(p,q,&is_binary); uint32_t val1=0; uint32_t val2=eval(op+1,q); if (is_binary){ val1=eval(p,op-1); } //printf("v1:%d\tv2:%d\n",val1,val2); switch (tokens[op].type){ case '+':return val1+val2; case '-':return val1-val2; case '*':return val1*val2; case '/':if (val2==0) {printf(RED"Devided by zero!\n"NONE);valid=false;return 0;} return val1/val2; case '%':return val1%val2; case '!':return !val2; case '&':return val1&val2; case '|':return val1|val2; case '^':return val1^val2; case '~':return ~val2; case POINT:return swaddr_read(val2, 4, R_DS); case NEG:return -val2; case AND:return val1&&val2; case OR :return val1||val2; case EQ :return val1==val2; case NEQ:return val1!=val2; } } return 0; }
int eval(int p, int q) { if(p > q) { printf("Error:bad expersion!\n"); return 0; } else if(p == q) { if(tokens[q].type == IDENTIFIER || tokens[q].type == REG) { if(tokens[q].type == IDENTIFIER) { int tmpAddr = addrOfIdentify(tokens[q].str) ; if(tmpAddr != -1) return tmpAddr; if(tokens[q].str[0] == '0' && tokens[q].str[1] == 'x') { int i = strlen(tokens[q].str) - 1; int tmp16 = 1; int tmpResult = 0; for( ; i > 1; i--) { char c = tokens[q].str[i]; if(c >= '0' && c <= '9') c = c- '0'; if(c >= 'a' && c <= 'f') c = c - 'a' + 10; if(c >= 'A' && c <= 'F') c = c -'A' + 10; tmpResult = tmpResult + c * tmp16; tmp16 *= 16; } return tmpResult; } return atoi(tokens[q].str); } else { return intFromReg(tokens[q].str + 1); } } else { printf("Error:while p == q, result should be a number\n"); return 0; } } else if(check_parentheses(p, q)) { return eval(p + 1, q - 1); } else { //we should do more here int opPosi = -1; int var1; int var2; opPosi = posiOfDomiOper(p, q); //printf("opPosi:%d\n", opPosi); if(opPosi == -1) { var1 = p; var2 = p; printf("Error : dominant operator find error\n"); } else if(opPosi == p) { var2 = eval(opPosi + 1, q); var1 = var2; //printf("var2:%d\n", var2); } else { var1 = eval(p, opPosi - 1); var2 = eval(opPosi + 1, q); } //printf("opPosi: %d, var1:%d, vqr2 :%d", opPosi, var1, var2); switch(tokens[opPosi].type) { case '+': return var1 + var2; case '-': return var1 - var2; case '*': return var1 * var2; case '/': return var1 / var2; case EQ: return var1 == var2; case UEQ: return var1 != var2; case AND: return var1 && var2; case OR: return var1 || var2; case GREATER: return var1 > var2; case LOWER: return var1 < var2; case GEQ: return var1 >= var2; case LEQ: return var1 <= var2; case ADDR: return hwaddr_read(var2, 1); } return 0; } }
uint32_t eval(uint32_t p,uint32_t q){ // Log("%d %d\n",p,q); assert(p<=q); if (p==q) { //解析数字 uint32_t n; if(tokens[q].type == INT_16) sscanf(tokens[q].str,"%x",&n); else if (tokens[q].type == INT_10) { sscanf(tokens[q].str,"%d",&n); }else{ int i=0;int flag=-1; for (; i < 8; i++) { if (strcmp(*(regsl+i),tokens[q].str)==0) { flag = 1; break; } } if (flag) { //找到 switch(i){ case 0:return cpu.eax; case 1:return cpu.ecx; case 2:return cpu.edx; case 3:return cpu.ebx; case 4:return cpu.esp; case 5:return cpu.ebp; case 6:return cpu.esi; case 7:return cpu.edi; } }else { panic("reg can not find error"); } } return n; }else if(check_parentheses(p,q) == true){ //判断括号 return eval(p+1,q-1); }else if (tokens[p].type =='!') { return !eval(++p,q); }else if (tokens[p].type == DEREF) { return swaddr_read(eval(++p,q),4); }else{ //递归计算 uint32_t op = getOp(p,q); //获取dominat operator uint32_t val1 = eval(p,op-1); uint32_t val2 = eval(op+1,q); // printf("\n%u %c %u\n",val1,tokens[op].type,val2); switch(tokens[op].type){ case '+':return val1+val2; case '-':return val1-val2; case '*':return val1*val2; case '/':return val1/val2; case EQ:return val1==val2; case NEQ:return val1!=val2; case AND:return val1&&val2; case OR:return val1||val2; default: assert(0); } } }
static int eval(int p,int q,bool *success){ if(p > q) { /* Bad expression */ *success=false; return 0; } else if(p == q) { /* Single token. * * For now this token should be a number. * * Return the value of the number. * */ switch(tokens[p].type){ case NUM: return atoi(tokens[p].str);break; case HEX: return strtoull(tokens[p].str, NULL, 16); case REG: if (!strcmp(tokens[p].str, "$eax")) return cpu.eax; else if (!strcmp(tokens[p].str, "$ecx")) return cpu.ecx; else if (!strcmp(tokens[p].str, "$edx")) return cpu.edx; else if (!strcmp(tokens[p].str, "$ebx")) return cpu.ebx; else if (!strcmp(tokens[p].str, "$esp")) return cpu.esp; else if (!strcmp(tokens[p].str, "$ebp")) return cpu.ebp; else if (!strcmp(tokens[p].str, "$esi")) return cpu.esi; else if (!strcmp(tokens[p].str, "$edi")) return cpu.edi; else if (!strcmp(tokens[p].str, "$eip")) return cpu.eip; /* else if (!strcmp(temp, "$ax")) return reg_w(R_AX); else if (!strcmp(temp, "$al")) return reg_b(R_AL); else if (!strcmp(temp, "$ah")) return reg_b(R_AH); else if (!strcmp(temp, "$cx")) return reg_w(R_CX); else if (!strcmp(temp, "$cl")) return reg_b(R_CL); else if (!strcmp(temp, "$ch")) return reg_b(R_CH); else if (!strcmp(temp, "$dx")) return reg_w(R_DX); else if (!strcmp(temp, "$dl")) return reg_b(R_DL); else if (!strcmp(temp, "$dh")) return reg_b(R_DH); else if (!strcmp(temp, "$bx")) return reg_w(R_BX); else if (!strcmp(temp, "$bl")) return reg_b(R_BL); else if (!strcmp(temp, "$bh")) return reg_b(R_BH); */ default: *success=false; return 0; } } else if(check_parentheses(p, q,success) == true) { /* The expression is surrounded by a matched pair of parentheses. * * If that is the case, just throw away the parentheses. * */ return eval(p + 1, q - 1,success); } else { int op = find_op(p, q);//找到优先级最高的操作符 int eval2 = eval(op + 1, q,success); switch (tokens[op].type) { case NOT: return !eval2; case NEG: return -eval2; case BIT_NOT: return ~eval2; case POINTER: return swaddr_read(eval2, 4); //how long? default: assert(op != p); } int eval1 = eval(p, op - 1,success); switch(tokens[op].type) { case ADD: return eval1 + eval2; case SUB: return eval1 - eval2; case MUL: return eval1 * eval2; case DIV: return eval1 / eval2; case MOD: return eval1 % eval2; case AND: return eval1 && eval2; case OR: return eval1 || eval2; case BIT_OR: return eval1 | eval2; case BIT_XOR: return eval1 ^ eval2; case BIT_AND: return eval1 & eval2; case EQ: return eval1 == eval2; case NE: return eval1 != eval2; case LE: return eval1 <= eval2; case LS: return eval1 < eval2; case GE: return eval1 >= eval2; case GT: return eval1 > eval2; case RSHIFT: return eval1 >> eval2; case LSHIFT: return eval1 << eval2; default: assert(0); } exit(1); } return 0; /* We should do more things here. */ }