Changeset 2111 for code/branches/objecthierarchy/src/util/ExprParser.cc
- Timestamp:
- Nov 2, 2008, 12:38:26 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/objecthierarchy/src/util/ExprParser.cc
r1894 r2111 45 45 #define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream 46 46 47 ExprParser::ExprParser(const std::string& str) 47 namespace orxonox 48 48 { 49 this->failed_ = false; 50 this->reading_stream = str.c_str(); 51 if (str.size() == 0 || *reading_stream == '\0') 52 { 53 this->failed_ = true; 54 this->result_ = 0.0; 55 } 56 else 57 { 58 this->result_ = parse_expr_8(); 59 this->remains_ = reading_stream; 49 ExprParser::ExprParser(const std::string& str) 50 { 51 this->failed_ = false; 52 this->reading_stream = str.c_str(); 53 if (str.size() == 0 || *reading_stream == '\0') 54 { 55 this->failed_ = true; 56 this->result_ = 0.0; 57 } 58 else 59 { 60 this->result_ = parse_expr_8(); 61 this->remains_ = reading_stream; 62 } 63 } 64 65 //Private functions: 66 /******************/ 67 double ExprParser::parse_argument() 68 { 69 double value = parse_expr_8(); 70 if (*reading_stream == ',') 71 { 72 ++reading_stream; 73 return value; 74 } 75 else 76 { 77 this->failed_ = true; 78 return 0; 79 } 80 } 81 82 double ExprParser::parse_last_argument() 83 { 84 double value = parse_expr_8(); 85 if (*reading_stream == ')') 86 { 87 ++reading_stream; 88 return value; 89 } 90 else 91 { 92 this->failed_ = true; 93 return 0; 94 } 95 } 96 97 double ExprParser::parse_expr_8() 98 { 99 double value = parse_expr_7(); 100 for(;;) 101 { 102 switch (op) 103 { 104 case oder: 105 value = parse_expr_7() || value; 106 break; 107 default: return value; 108 } 109 }; 110 } 111 112 113 double ExprParser::parse_expr_7() 114 { 115 double value = parse_expr_6(); 116 for(;;) 117 { 118 switch (op) 119 { 120 case und: 121 value = value && parse_expr_6(); 122 break; 123 default: return value; 124 } 125 }; 126 } 127 128 double ExprParser::parse_expr_6() 129 { 130 double value = parse_expr_5(); 131 for(;;) 132 { 133 switch (op) 134 { 135 case gleich: 136 value = (value == parse_expr_5()); 137 break; 138 case ungleich: 139 value = (value != parse_expr_5()); 140 break; 141 default: 142 return value; 143 } 144 }; 145 } 146 147 double ExprParser::parse_expr_5() 148 { 149 double value = parse_expr_4(); 150 for(;;) 151 { 152 switch (op) 153 { 154 case kleiner: 155 value = (value < parse_expr_4()); 156 break; 157 case kleinergleich: 158 value = (value <= parse_expr_4()); 159 break; 160 case groesser: 161 value = (value > parse_expr_4()); 162 break; 163 case groessergleich: 164 value = (value >= parse_expr_4()); 165 break; 166 default: 167 return value; 168 } 169 }; 170 } 171 172 double ExprParser::parse_expr_4() 173 { 174 double value = parse_expr_3(); 175 for(;;) 176 { 177 switch (op) 178 { 179 case b_plus: 180 value += parse_expr_3(); 181 break; 182 case b_minus: 183 value -= parse_expr_3(); 184 break; 185 default: 186 return value; 187 } 188 }; 189 } 190 191 double ExprParser::parse_expr_3() 192 { 193 double value = parse_expr_2(); 194 for(;;) 195 { 196 switch (op) 197 { 198 case mal: 199 value *= parse_expr_2(); 200 break; 201 case durch: 202 value /= parse_expr_2(); 203 break; 204 case modulo: 205 { 206 double temp = parse_expr_2(); 207 value = value - floor(value/temp)*temp; 208 break; 209 } 210 default: 211 return value; 212 } 213 }; 214 } 215 216 double ExprParser::parse_expr_2() 217 { 218 double value = parse_expr_1(); 219 while (*reading_stream != '\0') 220 { 221 op = parse_binary_operator(); 222 switch (op) 223 { 224 case hoch: 225 value = pow(value,parse_expr_1()); 226 break; 227 default: 228 return value; 229 } 230 }; 231 op = undef; 232 return value; 233 } 234 235 double ExprParser::parse_expr_1() 236 { 237 PARSE_BLANKS; 238 double value; 239 240 unary_operator op = parse_unary_operator(); 241 PARSE_BLANKS; 242 243 if (*reading_stream == '\0') 244 { 245 // end of string 246 this->failed_ = true; 247 return 0; 248 } 249 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46) 250 { // number 251 value = strtod(reading_stream, const_cast<char**>(&reading_stream)); 252 } 253 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 254 { // variable or function 255 char* word = new char[256]; 256 parse_word(word); 257 PARSE_BLANKS; 258 if (*reading_stream == '(') 259 { 260 ++reading_stream; 261 #define SWITCH word 262 CASE_1("sin") 263 value = sin(parse_last_argument()); 264 CASE("asin") 265 value = asin(parse_last_argument()); 266 CASE("sinh") 267 value = sinh(parse_last_argument()); 268 CASE("asinh") 269 { 270 value = parse_last_argument(); 271 value = log(sqrt(pow(value, 2) + 1) + value); 272 } 273 CASE("cos") 274 value = cos(parse_last_argument()); 275 CASE("acos") 276 value = acos(parse_last_argument()); 277 CASE("cosh") 278 value = cosh(parse_last_argument()); 279 CASE("acosh") 280 { 281 value = parse_last_argument(); 282 value = log(sqrt(pow(value, 2) - 1) + value); 283 } 284 CASE("tan") 285 value = tan(parse_last_argument()); 286 CASE("atan") 287 value = atan(parse_last_argument()); 288 CASE("atan2") 289 value = atan2(parse_argument(),parse_last_argument()); 290 CASE("tanh") 291 value = tanh(parse_last_argument()); 292 CASE("atanh") 293 { 294 value = parse_last_argument(); 295 value = 0.5*log((value + 1)/(value - 1)); 296 } 297 CASE("int") 298 value = floor(parse_last_argument()); 299 CASE("floor") 300 value = floor(parse_last_argument()); 301 CASE("ceil") 302 value = ceil(parse_last_argument()); 303 CASE("abs") 304 value = fabs(parse_last_argument()); 305 CASE("exp") 306 value = exp(parse_last_argument()); 307 CASE("log") 308 value = log10(parse_last_argument()); 309 CASE("ln") 310 value = log(parse_last_argument()); 311 CASE("sign") 312 { 313 value = parse_last_argument(); 314 value = (value>0 ? 1 : (value<0 ? -1 : 0)); 315 } 316 CASE("sqrt") 317 value = sqrt(parse_last_argument()); 318 CASE("degrees") 319 value = parse_last_argument()*180/3.1415926535897932; 320 CASE("radians") 321 value = parse_last_argument()*3.1415926535897932/180; 322 CASE("mod") 323 { 324 value = parse_argument(); 325 double value2 = parse_last_argument(); 326 value = value - floor(value/value2)*value2; 327 } 328 CASE("pow") 329 value = pow(parse_argument(),parse_last_argument()); 330 CASE("div") 331 value = floor(parse_argument()/parse_last_argument()); 332 CASE("max") 333 value = std::max(parse_argument(),parse_last_argument()); 334 CASE("min") 335 value = std::min(parse_argument(),parse_last_argument()); 336 CASE_ELSE 337 { 338 this->failed_ = true; 339 delete[] word; 340 return 0; 341 } 342 } 343 else 344 { 345 #define SWITCH word 346 CASE_1("pi") 347 value = 3.1415926535897932; 348 CASE("e") 349 value = 2.7182818284590452; 350 CASE_ELSE 351 { 352 this->failed_ = true; 353 delete[] word; 354 return 0; 355 } 356 } 357 delete[] word; 358 } 359 else if (*reading_stream == 40) 360 { // expresion in paranthesis 361 ++reading_stream; 362 value = parse_last_argument(); 363 } 364 else 365 { 366 this->failed_ = true; 367 return 0; 368 } 369 370 PARSE_BLANKS; 371 switch (op) 372 { 373 case u_nicht: return !value; 374 case u_plus: return value; 375 case u_minus: return -value; 376 default: 377 this->failed_ = true; 378 return 0; 379 } 380 } 381 382 char* ExprParser::parse_word(char* str) 383 { 384 char* word = str; 385 int counter = 0; 386 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 387 { 388 *word++ = *reading_stream++; 389 counter++; 390 if (counter > 255) 391 { 392 this->failed_ = true; 393 return '\0'; 394 } 395 }; 396 *word = '\0'; 397 return str; 398 } 399 400 ExprParser::binary_operator ExprParser::parse_binary_operator() 401 { 402 binary_operator op; 403 switch (*reading_stream) 404 { 405 case '+': op = b_plus; break; 406 case '-': op = b_minus; break; 407 case '*': op = mal; break; 408 case '/': op = durch; break; 409 case '^': op = hoch; break; 410 case '%': op = modulo; break; 411 case '&': op = und; break; 412 case '|': op = oder; break; 413 case '=': op = gleich; break; 414 case '!': op = b_nicht; break; 415 case '<': op = kleiner; break; 416 case '>': op = groesser; break; 417 default: return undef; 418 } 419 if (*++reading_stream == '=') 420 { 421 if (op > 9) 422 { 423 ++reading_stream; 424 return (binary_operator)(op + 3); 425 } 426 else 427 { 428 --reading_stream; 429 return undef; 430 } 431 } 432 else 433 return op; 434 } 435 436 ExprParser::unary_operator ExprParser::parse_unary_operator() 437 { 438 switch (*reading_stream) 439 { 440 case '!': 441 ++reading_stream; 442 return u_nicht; 443 case '+': 444 ++reading_stream; 445 return u_plus; 446 case '-': 447 ++reading_stream; 448 return u_minus; 449 default : 450 return u_plus; 451 } 60 452 } 61 453 } 62 63 //Private functions:64 /******************/65 double ExprParser::parse_argument()66 {67 double value = parse_expr_8();68 if (*reading_stream == ',')69 {70 ++reading_stream;71 return value;72 }73 else74 {75 this->failed_ = true;76 return 0;77 }78 }79 80 double ExprParser::parse_last_argument()81 {82 double value = parse_expr_8();83 if (*reading_stream == ')')84 {85 ++reading_stream;86 return value;87 }88 else89 {90 this->failed_ = true;91 return 0;92 }93 }94 95 double ExprParser::parse_expr_8()96 {97 double value = parse_expr_7();98 for(;;)99 {100 switch (op)101 {102 case oder:103 value = parse_expr_7() || value;104 break;105 default: return value;106 }107 };108 }109 110 111 double ExprParser::parse_expr_7()112 {113 double value = parse_expr_6();114 for(;;)115 {116 switch (op)117 {118 case und:119 value = value && parse_expr_6();120 break;121 default: return value;122 }123 };124 }125 126 double ExprParser::parse_expr_6()127 {128 double value = parse_expr_5();129 for(;;)130 {131 switch (op)132 {133 case gleich:134 value = (value == parse_expr_5());135 break;136 case ungleich:137 value = (value != parse_expr_5());138 break;139 default:140 return value;141 }142 };143 }144 145 double ExprParser::parse_expr_5()146 {147 double value = parse_expr_4();148 for(;;)149 {150 switch (op)151 {152 case kleiner:153 value = (value < parse_expr_4());154 break;155 case kleinergleich:156 value = (value <= parse_expr_4());157 break;158 case groesser:159 value = (value > parse_expr_4());160 break;161 case groessergleich:162 value = (value >= parse_expr_4());163 break;164 default:165 return value;166 }167 };168 }169 170 double ExprParser::parse_expr_4()171 {172 double value = parse_expr_3();173 for(;;)174 {175 switch (op)176 {177 case b_plus:178 value += parse_expr_3();179 break;180 case b_minus:181 value -= parse_expr_3();182 break;183 default:184 return value;185 }186 };187 }188 189 double ExprParser::parse_expr_3()190 {191 double value = parse_expr_2();192 for(;;)193 {194 switch (op)195 {196 case mal:197 value *= parse_expr_2();198 break;199 case durch:200 value /= parse_expr_2();201 break;202 case modulo:203 {204 double temp = parse_expr_2();205 value = value - floor(value/temp)*temp;206 break;207 }208 default:209 return value;210 }211 };212 }213 214 double ExprParser::parse_expr_2()215 {216 double value = parse_expr_1();217 while (*reading_stream != '\0')218 {219 op = parse_binary_operator();220 switch (op)221 {222 case hoch:223 value = pow(value,parse_expr_1());224 break;225 default:226 return value;227 }228 };229 op = undef;230 return value;231 }232 233 double ExprParser::parse_expr_1()234 {235 PARSE_BLANKS;236 double value;237 238 unary_operator op = parse_unary_operator();239 PARSE_BLANKS;240 241 if (*reading_stream == '\0')242 {243 // end of string244 this->failed_ = true;245 return 0;246 }247 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)248 { // number249 value = strtod(reading_stream, const_cast<char**>(&reading_stream));250 }251 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)252 { // variable or function253 char* word = new char[256];254 parse_word(word);255 PARSE_BLANKS;256 if (*reading_stream == '(')257 {258 ++reading_stream;259 #define SWITCH word260 CASE_1("sin")261 value = sin(parse_last_argument());262 CASE("asin")263 value = asin(parse_last_argument());264 CASE("sinh")265 value = sinh(parse_last_argument());266 CASE("asinh")267 {268 value = parse_last_argument();269 value = log(sqrt(pow(value, 2) + 1) + value);270 }271 CASE("cos")272 value = cos(parse_last_argument());273 CASE("acos")274 value = acos(parse_last_argument());275 CASE("cosh")276 value = cosh(parse_last_argument());277 CASE("acosh")278 {279 value = parse_last_argument();280 value = log(sqrt(pow(value, 2) - 1) + value);281 }282 CASE("tan")283 value = tan(parse_last_argument());284 CASE("atan")285 value = atan(parse_last_argument());286 CASE("atan2")287 value = atan2(parse_argument(),parse_last_argument());288 CASE("tanh")289 value = tanh(parse_last_argument());290 CASE("atanh")291 {292 value = parse_last_argument();293 value = 0.5*log((value + 1)/(value - 1));294 }295 CASE("int")296 value = floor(parse_last_argument());297 CASE("floor")298 value = floor(parse_last_argument());299 CASE("ceil")300 value = ceil(parse_last_argument());301 CASE("abs")302 value = fabs(parse_last_argument());303 CASE("exp")304 value = exp(parse_last_argument());305 CASE("log")306 value = log10(parse_last_argument());307 CASE("ln")308 value = log(parse_last_argument());309 CASE("sign")310 {311 value = parse_last_argument();312 value = (value>0 ? 1 : (value<0 ? -1 : 0));313 }314 CASE("sqrt")315 value = sqrt(parse_last_argument());316 CASE("degrees")317 value = parse_last_argument()*180/3.1415926535897932;318 CASE("radians")319 value = parse_last_argument()*3.1415926535897932/180;320 CASE("mod")321 {322 value = parse_argument();323 double value2 = parse_last_argument();324 value = value - floor(value/value2)*value2;325 }326 CASE("pow")327 value = pow(parse_argument(),parse_last_argument());328 CASE("div")329 value = floor(parse_argument()/parse_last_argument());330 CASE("max")331 value = std::max(parse_argument(),parse_last_argument());332 CASE("min")333 value = std::min(parse_argument(),parse_last_argument());334 CASE_ELSE335 {336 this->failed_ = true;337 delete[] word;338 return 0;339 }340 }341 else342 {343 #define SWITCH word344 CASE_1("pi")345 value = 3.1415926535897932;346 CASE("e")347 value = 2.7182818284590452;348 CASE_ELSE349 {350 this->failed_ = true;351 delete[] word;352 return 0;353 }354 }355 delete[] word;356 }357 else if (*reading_stream == 40)358 { // expresion in paranthesis359 ++reading_stream;360 value = parse_last_argument();361 }362 else363 {364 this->failed_ = true;365 return 0;366 }367 368 PARSE_BLANKS;369 switch (op)370 {371 case u_nicht: return !value;372 case u_plus: return value;373 case u_minus: return -value;374 default:375 this->failed_ = true;376 return 0;377 }378 }379 380 char* ExprParser::parse_word(char* str)381 {382 char* word = str;383 int counter = 0;384 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)385 {386 *word++ = *reading_stream++;387 counter++;388 if (counter > 255)389 {390 this->failed_ = true;391 return '\0';392 }393 };394 *word = '\0';395 return str;396 }397 398 ExprParser::binary_operator ExprParser::parse_binary_operator()399 {400 binary_operator op;401 switch (*reading_stream)402 {403 case '+': op = b_plus; break;404 case '-': op = b_minus; break;405 case '*': op = mal; break;406 case '/': op = durch; break;407 case '^': op = hoch; break;408 case '%': op = modulo; break;409 case '&': op = und; break;410 case '|': op = oder; break;411 case '=': op = gleich; break;412 case '!': op = b_nicht; break;413 case '<': op = kleiner; break;414 case '>': op = groesser; break;415 default: return undef;416 }417 if (*++reading_stream == '=')418 {419 if (op > 9)420 {421 ++reading_stream;422 return (binary_operator)(op + 3);423 }424 else425 {426 --reading_stream;427 return undef;428 }429 }430 else431 return op;432 }433 434 ExprParser::unary_operator ExprParser::parse_unary_operator()435 {436 switch (*reading_stream)437 {438 case '!':439 ++reading_stream;440 return u_nicht;441 case '+':442 ++reading_stream;443 return u_plus;444 case '-':445 ++reading_stream;446 return u_minus;447 default :448 return u_plus;449 }450 }
Note: See TracChangeset
for help on using the changeset viewer.