Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 2, 2008, 12:38:26 PM (16 years ago)
Author:
rgrieder
Message:

Moved all util classes and functions to orxonox namespace.
Converted all code to 4 spaces/tab in util.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/util/ExprParser.cc

    r1894 r2111  
    4545#define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream
    4646
    47 ExprParser::ExprParser(const std::string& str)
     47namespace orxonox
    4848{
    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        }
    60452    }
    61453}
    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     else
    74     {
    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     else
    89     {
    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 string
    244         this->failed_ = true;
    245         return 0;
    246     }
    247     else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)
    248     {  // number
    249         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 function
    253         char* word = new char[256];
    254         parse_word(word);
    255         PARSE_BLANKS;
    256         if (*reading_stream == '(')
    257         {
    258             ++reading_stream;
    259 #define SWITCH word
    260             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_ELSE
    335             {
    336                 this->failed_ = true;
    337                 delete[] word;
    338                 return 0;
    339             }
    340         }
    341         else
    342         {
    343 #define SWITCH word
    344             CASE_1("pi")
    345                 value = 3.1415926535897932;
    346             CASE("e")
    347                 value = 2.7182818284590452;
    348             CASE_ELSE
    349             {
    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 paranthesis
    359         ++reading_stream;
    360         value = parse_last_argument();
    361     }
    362     else
    363     {
    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         else
    425         {
    426             --reading_stream;
    427             return undef;
    428         }
    429     }
    430     else
    431         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.