Last change
on this file since 1494 was
1494,
checked in by rgrieder, 16 years ago
|
- set the svn:eol-style property to all files so, that where ever you check out, you'll get the right line endings
(had to change every file with mixed endings to windows in order to set the property)
|
-
Property svn:eol-style set to
native
|
File size:
9.8 KB
|
Rev | Line | |
---|
[1118] | 1 | /* |
---|
| 2 | * ORXONOX - the hottest 3D action shooter ever to exist |
---|
[1494] | 3 | * > www.orxonox.net < * |
---|
[1118] | 4 | * |
---|
| 5 | * License notice: |
---|
| 6 | * |
---|
| 7 | * This program is free software; you can redistribute it and/or |
---|
| 8 | * modify it under the terms of the GNU General Public License |
---|
| 9 | * as published by the Free Software Foundation; either version 2 |
---|
| 10 | * of the License, or (at your option) any later version. |
---|
| 11 | * |
---|
| 12 | * This program is distributed in the hope that it will be useful, |
---|
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 15 | * GNU General Public License for more details. |
---|
| 16 | * |
---|
| 17 | * You should have received a copy of the GNU General Public License |
---|
| 18 | * along with this program; if not, write to the Free Software |
---|
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
---|
| 20 | * |
---|
| 21 | * Author: |
---|
| 22 | * Reto Grieder |
---|
| 23 | * Co-authors: |
---|
| 24 | * ... |
---|
| 25 | * |
---|
| 26 | */ |
---|
| 27 | |
---|
| 28 | /** |
---|
| 29 | @file |
---|
| 30 | @brief Declaration of FloatParser |
---|
| 31 | */ |
---|
[1494] | 32 | #include "ExprParser.h"#include <cmath>#include <cstring>// macros for easier if, else statements#define CASE_1(var) if (!strcmp(SWITCH,var))#define CASE(var) else if (!strcmp(SWITCH,var))#define CASE_ELSE else//! skip white spaces#define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream;ExprParser::ExprParser(const std::string& str){ this->failed_ = false; this->reading_stream = str.c_str(); if (str.size() == 0 || *reading_stream == '\0') { this->failed_ = true; this->result_ = 0.0; } else { this->result_ = parse_expr_8(); this->remains_ = reading_stream; }}//Private functions:/******************/double ExprParser::parse_argument(){ double value = parse_expr_8(); if (*reading_stream == ',') { ++reading_stream; return value; } else { this->failed_ = true; return 0; }}double ExprParser::parse_last_argument(){ double value = parse_expr_8(); if (*reading_stream == ')') { ++reading_stream; return value; } else { this->failed_ = true; return 0; }}double ExprParser::parse_expr_8(){ double value = parse_expr_7(); for(;;) { switch (op) { case oder: value = parse_expr_7() || value; break; default: return value; } };}double ExprParser::parse_expr_7(){ double value = parse_expr_6(); for(;;) { switch (op) { case und: value = value && parse_expr_6(); break; default: return value; } };}double ExprParser::parse_expr_6(){ double value = parse_expr_5(); for(;;) { switch (op) { case gleich: value = (value == parse_expr_5()); break; case ungleich: value = (value != parse_expr_5()); break; default: return value; } };}double ExprParser::parse_expr_5(){ double value = parse_expr_4(); for(;;) { switch (op) { case kleiner: value = (value < parse_expr_4()); break; case kleinergleich: value = (value <= parse_expr_4()); break; case groesser: value = (value > parse_expr_4()); break; case groessergleich: value = (value >= parse_expr_4()); break; default: return value; } };}double ExprParser::parse_expr_4(){ double value = parse_expr_3(); for(;;) { switch (op) { case b_plus: value += parse_expr_3(); break; case b_minus: value -= parse_expr_3(); break; default: return value; } };}double ExprParser::parse_expr_3(){ double value = parse_expr_2(); for(;;) { switch (op) { case mal: value *= parse_expr_2(); break; case durch: value /= parse_expr_2(); break; case modulo: { double temp = parse_expr_2(); value = value - floor(value/temp)*temp; break; } default: return value; } };}double ExprParser::parse_expr_2(){ double value = parse_expr_1(); while (*reading_stream != '\0') { op = parse_binary_operator(); switch (op) { case hoch: value = pow(value,parse_expr_1()); break; default: return value; } }; op = undef; return value;}double ExprParser::parse_expr_1(){ PARSE_BLANKS double value; unary_operator op = parse_unary_operator(); PARSE_BLANKS if (*reading_stream == '\0') { // end of string this->failed_ = true; return 0; } else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46) { // number value = strtod(reading_stream, const_cast<char**>(&reading_stream)); } else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) { // variable or function char* word = new char[256]; parse_word(word); PARSE_BLANKS if (*reading_stream == '(') { ++reading_stream;#define SWITCH word CASE_1("sin") value = sin(parse_last_argument()); CASE("asin") value = asin(parse_last_argument()); CASE("sinh") value = sinh(parse_last_argument()); CASE("asinh") { value = parse_last_argument(); value = log(sqrt(pow(value, 2) + 1) + value); } CASE("cos") value = cos(parse_last_argument()); CASE("acos") value = acos(parse_last_argument()); CASE("cosh") value = cosh(parse_last_argument()); CASE("acosh") { value = parse_last_argument(); value = log(sqrt(pow(value, 2) - 1) + value); } CASE("tan") value = tan(parse_last_argument()); CASE("atan") value = atan(parse_last_argument()); CASE("atan2") value = atan2(parse_argument(),parse_last_argument()); CASE("tanh") value = tanh(parse_last_argument()); CASE("atanh") { value = parse_last_argument(); value = 0.5*log((value + 1)/(value - 1)); } CASE("int") value = floor(parse_last_argument()); CASE("floor") value = floor(parse_last_argument()); CASE("ceil") value = ceil(parse_last_argument()); CASE("abs") value = fabs(parse_last_argument()); CASE("exp") value = exp(parse_last_argument()); CASE("log") value = log10(parse_last_argument()); CASE("ln") value = log(parse_last_argument()); CASE("sign") { value = parse_last_argument(); value = (value>0 ? 1 : (value<0 ? -1 : 0)); } CASE("sqrt") value = sqrt(parse_last_argument()); CASE("degrees") value = parse_last_argument()*180/3.1415926535897932; CASE("radians") value = parse_last_argument()*3.1415926535897932/180; CASE("mod") { value = parse_argument(); double value2 = parse_last_argument(); value = value - floor(value/value2)*value2; } CASE("pow") value = pow(parse_argument(),parse_last_argument()); CASE("div") value = floor(parse_argument()/parse_last_argument()); CASE("max") value = std::max(parse_argument(),parse_last_argument()); CASE("min") value = std::min(parse_argument(),parse_last_argument()); CASE_ELSE { this->failed_ = true; delete[] word; return 0; } } else {#define SWITCH word CASE_1("pi") value = 3.1415926535897932; CASE("e") value = 2.7182818284590452; CASE_ELSE { this->failed_ = true; delete[] word; return 0; } } delete[] word; } else if (*reading_stream == 40) { // expresion in paranthesis ++reading_stream; value = parse_last_argument(); } else { this->failed_ = true; return 0; } PARSE_BLANKS switch (op) { case u_nicht: return !value; case u_plus: return value; case u_minus: return -value; default: { this->failed_ = true; return 0; } }}char* ExprParser::parse_word(char* str){ char* word = str; int counter = 0; while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) { *word++ = *reading_stream++; counter++; if (counter > 255) { this->failed_ = true; return '\0'; } }; *word = '\0'; return str;}ExprParser::binary_operator ExprParser::parse_binary_operator(){ binary_operator op; switch (*reading_stream) { case '+': op = b_plus; break; case '-': op = b_minus; break; case '*': op = mal; break; case '/': op = durch; break; case '^': op = hoch; break; case '%': op = modulo; break; case '&': op = und; break; case '|': op = oder; break; case '=': op = gleich; break; case '!': op = b_nicht; break; case '<': op = kleiner; break; case '>': op = groesser; break; default: return undef; } if (*++reading_stream == '=') { if (op > 9) { ++reading_stream; return (binary_operator)(op + 3); } else { --reading_stream; return undef; } } else return op;}ExprParser::unary_operator ExprParser::parse_unary_operator(){ switch (*reading_stream) { case '!': ++reading_stream; return u_nicht; case '+': ++reading_stream; return u_plus; case '-': ++reading_stream; return u_minus; default : return u_plus; }} |
---|
Note: See
TracBrowser
for help on using the repository browser.