#include <eval_num_expr.h>
Inheritance diagram for NLMISC::CEvalNumExpr:
Definition at line 37 of file eval_num_expr.h.
Public Types | |
enum | TReturnState { NoError, UnkownValue, ValueError, UnkownFunction, FunctionError, NumberSyntaxError, UnkownOperator, MustBeOpen, MustBeClose, MustBeComa, MustBeExpression, NotUnaryOperator, MustBeEnd, MustBeDoubleQuote, DividByZero, ReturnValueCount } |
Eval return error. More... | |
Public Member Functions | |
TReturnState | evalExpression (const char *expression, double &result, int *errorIndex, uint32 userData=0) |
const char * | getErrorString (TReturnState state) const |
Get error string. | |
bool | internalCheck () |
virtual | ~CEvalNumExpr () |
Protected Member Functions | |
virtual TReturnState | evalFunction (const char *funcName, double arg0, double arg1, double &result) |
virtual TReturnState | evalFunction (const char *funcName, double arg0, double &result) |
virtual TReturnState | evalValue (const char *value, double &result, uint32 userData) |
Overridable functions. | |
Private Types | |
enum | { InternalStringLen = 32, InternalOperator = 4 } |
enum | TOperator { Not = 0, Tilde, Mul, Div, Remainder, Plus, Minus, ULeftShift, URightShift, SLeftShift, SRightShift, Inferior, InferiorEqual, Superior, SuperiorEqual, Equal, NotEqual, And, Or, Xor, LogicalAnd, LogicalOr, LogicalXor, OperatorCount, NotOperator, ExtOperator } |
enum | TReservedWord { Abs = 0, Acos, Asin, Atan, Atan2, Ceil, Cos, Cosh, Exp, Exponent, Floor, Int, Log, Log10, Mantissa, Max, Min, Pow, Rand, Round, Sin, Sinh, Sq, Sqrt, Tan, Tanh, ReservedWordCount } |
enum | TToken { Number, Function1, Function2, String, Operator, Open, Close, Coma, End } |
Implementation Expression tokens. More... | |
Private Member Functions | |
TReturnState | evalExpression (double &result, TToken &nextToken, uint32 userData) |
Evaluate an expression. | |
TReturnState | getNextToken (TToken &token) |
Internal functions Get the next token. | |
TReturnState | readDecimal (double &value) |
Read a decimal double. | |
void | readIntegerNumberDecimal (double &value) |
Read an integer. | |
Private Attributes | |
const char * | _ExprPtr |
std::string | _InternalStlString |
char | _InternalString [InternalStringLen] |
Current string. | |
const char * | _InternalStringPtr |
TOperator | _Op |
Current operator. | |
TReservedWord | _ReservedWordFound |
Reserved word. | |
TReturnState | _State |
Members. | |
double | _Value |
Current value. | |
Static Private Attributes | |
const char * | _ErrorString [ReturnValueCount] |
const TOperator | _OperatorArray [128] |
const int | _OperatorPrecedence [] |
const char * | _ReservedWord [ReservedWordCount] |
const TToken | _ReservedWordToken [ReservedWordCount] |
Static values Char to operator array. | |
const bool | _StringChar [128] |
|
Definition at line 289 of file eval_num_expr.h.
00290 { 00291 InternalStringLen = 32, 00292 InternalOperator = 4, 00293 }; |
|
Definition at line 226 of file eval_num_expr.h.
00227 { 00228 Not = 0, // ! 00229 Tilde, // ~ 00230 Mul, // * 00231 Div, // / 00232 Remainder, // % 00233 Plus, // + 00234 Minus, // - 00235 ULeftShift, // << 00236 URightShift, // >> 00237 SLeftShift, // <- 00238 SRightShift, // -> 00239 Inferior, // < 00240 InferiorEqual, // <= 00241 Superior, // > 00242 SuperiorEqual, // >= 00243 Equal, // == 00244 NotEqual, // != 00245 And, // & 00246 Or, // | 00247 Xor, // ^ 00248 LogicalAnd, // && 00249 LogicalOr, // || 00250 LogicalXor, // ^^ 00251 OperatorCount, // 00252 NotOperator, // This is not an operator 00253 ExtOperator, // This is a 2 charcters operator 00254 }; |
|
Definition at line 257 of file eval_num_expr.h. Referenced by evalExpression(), and getNextToken().
00258 { 00259 Abs = 0, 00260 Acos, 00261 Asin, 00262 Atan, 00263 Atan2, 00264 Ceil, 00265 Cos, 00266 Cosh, 00267 Exp, 00268 Exponent, 00269 Floor, 00270 Int, 00271 Log, 00272 Log10, 00273 Mantissa, 00274 Max, 00275 Min, 00276 Pow, 00277 Rand, 00278 Round, 00279 Sin, 00280 Sinh, 00281 Sq, 00282 Sqrt, 00283 Tan, 00284 Tanh, 00285 ReservedWordCount, 00286 }; |
|
Eval return error.
Definition at line 42 of file eval_num_expr.h. Referenced by evalExpression(), and getNextToken().
00043 { 00044 NoError, // No error 00045 UnkownValue, // Unkown value has been parsed 00046 ValueError, // Error during user defined value evaluation 00047 UnkownFunction, // Unkown function has been parsed 00048 FunctionError, // Error during user defined function evaluation 00049 NumberSyntaxError, // Syntax error in a number expression 00050 UnkownOperator, // Unkown operator 00051 MustBeOpen, // Should be a open parentesis 00052 MustBeClose, // Should be a close parentesis 00053 MustBeComa, // Should be a coma character 00054 MustBeExpression, // Should be an expression 00055 NotUnaryOperator, // Should not be an unary operator 00056 MustBeEnd, // Should be the end 00057 MustBeDoubleQuote, // Should be a double quote 00058 DividByZero, // Divide by zero 00059 ReturnValueCount 00060 }; |
|
Implementation Expression tokens.
Definition at line 212 of file eval_num_expr.h.
00213 { 00214 Number, // This is a number 00215 Function1, // This is a function with one argu 00216 Function2, // This is a function with two argu 00217 String, // This is a user string 00218 Operator, // This is an operator 00219 Open, // ( 00220 Close, // ) 00221 Coma, // , 00222 End, // End of string 00223 }; |
|
Definition at line 40 of file eval_num_expr.h.
00040 {} |
|
Evaluate an expression.
Definition at line 616 of file eval_num_expr.cpp. References _InternalStringPtr, _OperatorPrecedence, _ReservedWordFound, Abs, Acos, And, arg1, Asin, Atan, Atan2, Ceil, Close, Coma, Cos, Cosh, Div, DividByZero, Equal, evalExpression(), evalFunction(), evalValue(), Exponent, Floor, Function1, Function2, getNextToken(), index, Inferior, InferiorEqual, InternalOperator, InternalStringLen, Log10, LogicalAnd, LogicalOr, LogicalXor, Mantissa, Minus, Mul, MustBeClose, MustBeComa, MustBeExpression, MustBeOpen, nlstop, Not, NotEqual, NotOperator, NotUnaryOperator, Number, Open, Or, Plus, Pow, Rand, Sin, Sinh, sint, SLeftShift, Sq, Sqrt, SRightShift, Superior, SuperiorEqual, Tan, Tanh, Tilde, TReservedWord, TReturnState, uint, uint32, ULeftShift, URightShift, value, and Xor.
00617 { 00618 // Array of result 00619 00620 uint exprCount = 0; 00621 double result[InternalOperator]; 00622 vector<double> resultSup; 00623 00624 uint opCount = 0; 00625 TOperator resultOp[InternalOperator]; 00626 vector<TOperator> resultOpSup; 00627 00628 // Read a token 00629 TReturnState error = getNextToken (nextToken); 00630 if (error != NoError) 00631 return error; 00632 while (1) 00633 { 00634 // Unary opertor 00635 uint unaryOpCount = 0; 00636 TOperator resultUnaryOp[InternalOperator]; 00637 vector<TOperator> resultUnaryOpSup; 00638 00639 // Current value 00640 double value; 00641 00642 // Unary operator ? 00643 if ( (nextToken == Operator) && ( (_Op == Minus) || (_Op == Not) || (_Op == Tilde) ) ) 00644 { 00645 // Push the unary operator 00646 if (unaryOpCount<InternalOperator) 00647 resultUnaryOp[unaryOpCount] = _Op; 00648 else 00649 resultUnaryOpSup.push_back (_Op); 00650 unaryOpCount++; 00651 00652 // Read next token 00653 error = getNextToken (nextToken); 00654 if (error != NoError) 00655 return error; 00656 } 00657 00658 // Parenthesis ? 00659 if (nextToken == Open) 00660 { 00661 // Eval sub expression 00662 error = evalExpression (value, nextToken, userData); 00663 if (error == NoError) 00664 { 00665 if (nextToken != Close) 00666 return MustBeClose; 00667 } 00668 else 00669 return error; 00670 00671 // Get next token 00672 error = getNextToken (nextToken); 00673 if (error != NoError) 00674 return error; 00675 } 00676 // This is a function ? 00677 else if ( (nextToken == Function1) || (nextToken == Function2) ) 00678 { 00679 TToken backupedToken = nextToken; 00680 00681 // Get the function 00682 TReservedWord reservedWord = _ReservedWordFound; 00683 00684 // Read a token 00685 error = getNextToken (nextToken); 00686 if (error == NoError) 00687 { 00688 // Open ? 00689 if (nextToken != Open) 00690 { 00691 return MustBeOpen; 00692 } 00693 00694 // Eval an expression 00695 double arg0; 00696 error = evalExpression (arg0, nextToken, userData); 00697 if (error == NoError) 00698 { 00699 // 2 arg ? 00700 if (backupedToken == Function2) 00701 { 00702 if (nextToken == Coma) 00703 { 00704 // Second argument 00705 double arg1; 00706 error = evalExpression (arg1, nextToken, userData); 00707 if (error == NoError) 00708 { 00709 // Final with close ? 00710 if (nextToken == Close) 00711 { 00712 switch (reservedWord) 00713 { 00714 case Atan2: 00715 value = atan2 (arg0, arg1); 00716 break; 00717 case Max: 00718 value = (arg0>arg1) ? arg0 : arg1; 00719 break; 00720 case Min: 00721 value = (arg0<arg1) ? arg0 : arg1; 00722 break; 00723 case Pow: 00724 value = pow (arg0, arg1); 00725 break; 00726 case Rand: 00727 value = arg0 + (arg1-arg0) * (double)rand () / (double)(RAND_MAX+1); 00728 break; 00729 default: 00730 // Can't be hear after getToken 00731 nlstop; 00732 } 00733 } 00734 else 00735 return MustBeClose; 00736 } 00737 else 00738 return error; 00739 } 00740 else 00741 return MustBeComa; 00742 } 00743 else 00744 { 00745 if (nextToken == Close) 00746 { 00747 // Eval the function 00748 switch (reservedWord) 00749 { 00750 case Abs: 00751 value = fabs (arg0); 00752 break; 00753 case Acos: 00754 value = acos (arg0); 00755 break; 00756 case Asin: 00757 value = asin (arg0); 00758 break; 00759 case Atan: 00760 value = atan (arg0); 00761 break; 00762 case Ceil: 00763 value = ceil (arg0); 00764 break; 00765 case Cosh: 00766 value = cosh (arg0); 00767 break; 00768 case Cos: 00769 value = cos (arg0); 00770 break; 00771 case Exponent: 00772 { 00773 int exponent; 00774 frexp( arg0, &exponent); 00775 value = (double)exponent; 00776 } 00777 break; 00778 case Exp: 00779 value = exp (arg0); 00780 break; 00781 case Floor: 00782 value = floor (arg0); 00783 break; 00784 case Int: 00785 value = (double)(int)(arg0); 00786 break; 00787 case Log10: 00788 value = log10 (arg0); 00789 break; 00790 case Log: 00791 value = log (arg0); 00792 break; 00793 case Mantissa: 00794 { 00795 int exponent; 00796 value = frexp( arg0, &exponent); 00797 } 00798 break; 00799 case Round: 00800 value = floor (arg0 + 0.5); 00801 break; 00802 case Sinh: 00803 value = sinh (arg0); 00804 break; 00805 case Sin: 00806 value = sin (arg0); 00807 break; 00808 case Sqrt: 00809 value = sqrt (arg0); 00810 break; 00811 case Sq: 00812 value = arg0 * arg0; 00813 break; 00814 case Tanh: 00815 value = tanh (arg0); 00816 break; 00817 case Tan: 00818 value = tan (arg0); 00819 break; 00820 default: 00821 // Can't be hear after getToken 00822 nlstop; 00823 } 00824 } 00825 else 00826 return MustBeClose; 00827 } 00828 } 00829 else 00830 return error; 00831 } 00832 else 00833 return error; 00834 00835 // Get next token 00836 error = getNextToken (nextToken); 00837 if (error != NoError) 00838 return error; 00839 } 00840 else if (nextToken == Number) 00841 { 00842 // Save the internal value 00843 value = _Value; 00844 00845 // Get next token 00846 error = getNextToken (nextToken); 00847 if (error != NoError) 00848 return error; 00849 } 00850 else if (nextToken == String) 00851 { 00852 // Copy the string 00853 char internalString[InternalStringLen]; 00854 std::string internalStlString; 00855 const char *internalStringPtr; 00856 if (strlen (_InternalStringPtr) >= InternalStringLen-1) 00857 { 00858 internalStlString = _InternalStringPtr; 00859 internalStringPtr = internalStlString.c_str (); 00860 } 00861 else 00862 { 00863 strcpy (internalString ,_InternalStringPtr); 00864 internalStringPtr = internalString; 00865 } 00866 00867 // Read a token 00868 error = getNextToken (nextToken); 00869 if (error == NoError) 00870 { 00871 // Open ? 00872 if (nextToken == Open) 00873 { 00874 // Eval an expression 00875 double arg0; 00876 error = evalExpression (arg0, nextToken, userData); 00877 if (error == NoError) 00878 { 00879 if (nextToken == Coma) 00880 { 00881 // Second argument 00882 double arg1; 00883 error = evalExpression (arg1, nextToken, userData); 00884 if (error == NoError) 00885 { 00886 // Final with close ? 00887 if (nextToken == Close) 00888 { 00889 // Eval the function 00890 error = evalFunction (internalStringPtr, arg0, arg1, value); 00891 if (error != NoError) 00892 return error; 00893 00894 // Get next token 00895 error = getNextToken (nextToken); 00896 if (error != NoError) 00897 return error; 00898 } 00899 else 00900 return MustBeClose; 00901 } 00902 else 00903 return error; 00904 } 00905 else 00906 { 00907 if (nextToken == Close) 00908 { 00909 // Eval the function 00910 error = evalFunction (internalStringPtr, arg0, value); 00911 if (error != NoError) 00912 return error; 00913 00914 // Get next token 00915 error = getNextToken (nextToken); 00916 if (error != NoError) 00917 return error; 00918 } 00919 else 00920 return MustBeClose; 00921 } 00922 } 00923 else 00924 return error; 00925 } 00926 else 00927 { 00928 // This is a user value 00929 error = evalValue (internalStringPtr, value, userData); 00930 if (error != NoError) 00931 return error; 00932 } 00933 } 00934 else 00935 return error; 00936 } 00937 else 00938 { 00939 return MustBeExpression; 00940 } 00941 00942 // Eval unary operator 00943 sint i; 00944 for (i=unaryOpCount-1; i>=0; i--) 00945 { 00946 switch ((i<InternalOperator)?resultUnaryOp[i]:resultUnaryOpSup[i-InternalOperator]) 00947 { 00948 case Not: 00949 value = (double)(uint)((floor (value+0.5)==0.0)); 00950 break; 00951 case Tilde: 00952 value = (double)~((uint)floor (value+0.5)); 00953 break; 00954 case Minus: 00955 value = -value; 00956 break; 00957 default: 00958 // Can't be hear after getToken 00959 nlstop; 00960 } 00961 } 00962 00963 // Push the value 00964 if (exprCount < InternalOperator) 00965 result[exprCount] = value; 00966 else 00967 resultSup.push_back (value); 00968 exprCount++; 00969 00970 // Look for an operator 00971 // Operator ? 00972 if (nextToken == Operator) 00973 { 00974 // Yes, push it 00975 if (opCount < InternalOperator) 00976 resultOp[opCount] = _Op; 00977 else 00978 resultOpSup.push_back (_Op); 00979 opCount++; 00980 } 00981 else 00982 { 00983 // Exit the evaluate loop 00984 break; 00985 } 00986 00987 // Next token 00988 error = getNextToken (nextToken); 00989 } 00990 00991 // Reduce the expression 00992 uint index = 1; 00993 while (exprCount != 1) 00994 { 00995 // Reduct ? 00996 TOperator before = (((index-1)<InternalOperator)?resultOp[index-1]:resultOpSup[index-1-InternalOperator]); 00997 TOperator after = (index < opCount)?(((index)<InternalOperator)?resultOp[index]:resultOpSup[index-InternalOperator]):NotOperator; 00998 if ((index == opCount) || (_OperatorPrecedence[before] <= _OperatorPrecedence[after])) 00999 { 01000 // Eval the value 01001 double &v0 = ((index-1)<InternalOperator)?result[index-1]:resultSup[index-1-InternalOperator]; 01002 double &v1 = ((index)<InternalOperator)?result[index]:resultSup[index-InternalOperator]; 01003 01004 // Choose the operator 01005 switch (before) 01006 { 01007 case Not: 01008 case Tilde: 01009 return NotUnaryOperator; 01010 case Mul: 01011 v0 *= v1; 01012 break; 01013 case Div: 01014 if (v1 == 0) 01015 { 01016 return DividByZero; 01017 } 01018 else 01019 { 01020 v0 /= v1; 01021 } 01022 break; 01023 case Remainder: 01024 v0 = fmod (v0, v1); 01025 break; 01026 case Plus: 01027 v0 += v1; 01028 break; 01029 case Minus: 01030 v0 -= v1; 01031 break; 01032 case ULeftShift: 01033 v0 = (double)(((uint)floor (v0 + 0.5))<<((uint)floor (v1 + 0.5))); 01034 break; 01035 case URightShift: 01036 v0 = (double)(((uint)floor (v0 + 0.5))>>((uint)floor (v1 + 0.5))); 01037 break; 01038 case SLeftShift: 01039 v0 = (double)(((sint)floor (v0 + 0.5))<<((sint)floor (v1 + 0.5))); 01040 break; 01041 case SRightShift: 01042 v0 = (double)(((sint)floor (v0 + 0.5))>>((sint)floor (v1 + 0.5))); 01043 break; 01044 case Inferior: 01045 v0 = (v0<v1)?1.0:0.0; 01046 break; 01047 case InferiorEqual: 01048 v0 = (v0<=v1)?1.0:0.0; 01049 break; 01050 case Superior: 01051 v0 = (v0>v1)?1.0:0.0; 01052 break; 01053 case SuperiorEqual: 01054 v0 = (v0>=v1)?1.0:0.0; 01055 break; 01056 case Equal: 01057 v0 = (v0==v1)?1.0:0.0; 01058 break; 01059 case NotEqual: 01060 v0 = (v0!=v1)?1.0:0.0; 01061 break; 01062 case And: 01063 v0 = (double)(((uint)floor (v0 + 0.5)) & ((uint)floor (v1 + 0.5))); 01064 break; 01065 case Or: 01066 v0 = (double)(((uint)floor (v0 + 0.5)) | ((uint)floor (v1 + 0.5))); 01067 break; 01068 case Xor: 01069 v0 = (double)(((uint)floor (v0 + 0.5)) ^ ((uint)floor (v1 + 0.5))); 01070 break; 01071 case LogicalAnd: 01072 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) && (floor (v1 + 0.5) != 0.0)); 01073 break; 01074 case LogicalOr: 01075 v0 = (double)(uint)((floor (v0 + 0.5) != 0.0) || (floor (v1 + 0.5) != 0.0)); 01076 break; 01077 case LogicalXor: 01078 { 01079 bool b0 = floor (v0 + 0.5) != 0.0; 01080 bool b1 = floor (v1 + 0.5) != 0.0; 01081 v0 = (double)(uint)((b0&&!b1) || ((!b0)&&b1)); 01082 } 01083 break; 01084 default: 01085 nlstop; 01086 } 01087 01088 // Decal others values 01089 uint i = index; 01090 for (; i<exprCount-1; i++) 01091 { 01092 // Copy 01093 if (i<InternalOperator) 01094 result[i] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator]; 01095 else 01096 resultSup[i-InternalOperator] = (i+1<InternalOperator)?result[i+1]:resultSup[i+1-InternalOperator]; 01097 } 01098 exprCount--; 01099 01100 // Decal operators 01101 i = index-1; 01102 for (; i<opCount-1; i++) 01103 { 01104 // Copy 01105 if (i<InternalOperator) 01106 resultOp[i] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator]; 01107 else 01108 resultOpSup[i-InternalOperator] = (i+1<InternalOperator)?resultOp[i+1]:resultOpSup[i+1-InternalOperator]; 01109 01110 } 01111 opCount--; 01112 01113 // Last one ? 01114 if (index > 1) 01115 index--; 01116 } 01117 else 01118 index++; 01119 } 01120 01121 finalResult = result[0]; 01122 return NoError; 01123 } |
|
Evaluate a numerical expression. Doesn't allocate heap memory for common complexity expression.
expression: '-' expression | '!' expression // Returns true if a equal false, else false (logical not) | '~' expression // Returns ~ round(a) (bitwise not) | '(' expression ')' | expression operator expression | function1 '(' expression ')' | function2 '(' expression ',' expression ')' | number | constant | string // User defined value, evaluated by the evalValue() callback operator: '*' // Calculates (a * b) | '/' // Calculates (a / b) | '%' // Calculates the remainder of (a / b) | '+' // Calculates (a + b) | '-' // Calculates (a - b) | '<<' // Returns round(a) left 32 bits unsigned shift by round(b) | '>>' // Returns round(a) right 32 bits unsigned shift by round(b) | '<-' // Returns round(a) left 32 bits signed shift by round(b) | '->' // Returns round(a) right 32 bits signed shift by round(b) | '<' // Returns true if a is strictly smaller than b | '<=' // Returns true if a is smaller or equal than b | '>' // Returns true if a is strictly bigger than b | '>=' // Returns true if a is bigger or equal than b | '==' // Returns true if a equal b, else returns false (warning, performs a floating point comparison) | '!=' // Returns false if a equal b, else returns true (warning, performs a floating point comparison) | '&' // Returns round(a) & round(b) over 32 bits | '|' // Returns round(a) | round(b) over 32 bits | '^' // Returns round(a) ^ round(b) over 32 bits | '&&' // Returns true if a equal true and b equal true else returns false | '||' // Returns true if a equal true or b equal true else returns false | '^^' // Returns true if a equal true and b equal false, or, a equal false and b equal 1.0, else returns false function1: abs // Calculates the absolute value | acos // Calculates the arccosine | asin // Calculates the arcsine | atan // Calculates the arctangent | ceil // Calculates the ceiling of a value ( ceil(-1.1) = -1, ceil(1.1) = 2 ) | cos // Calculates the cosine | cosh // Calculates the hyperbolic cosine | exp // Calculates the exponential | exponent // Calculates the exponent of a floating point value | floor // Calculates the floor of a value ( floor(-1.1) = -2, floor(1.1) = 1 ) | int // Calculates the C style integer value ( int(-1.6) = -1, int(1.6) = 1 ) | log // Calculates logarithms | log10 // Calculates base-10 logarithms | mantissa // Calculates the mantissa of a floating point value | round // Calculates the nearest integer value ( round(-1.6) = -2, round(1.1) = 1 ) | sin // Calculate sines | sinh // Calculate hyperbolic sines | sq // Calculates the square | sqrt // Calculates the square root | tan // Calculates the tangent | tanh // Calculates the hyperbolic tangent | string // User defined one arg function, evaluated by the evalfunction() callback function2: max // Returns the larger of two values | min // Returns the smaller of two values | atan2 // Calculates the arctangent of arg0/arg1 | pow // Calculates a raised at the power of b | rand // Calculates a pseudo random value (arg0 <= randomValue < arg1) | string // User defined two args function, evaluated by the evalfunction() callback number: [0-9]+ // Unsigned decimal integer | "0x"[0-9a-fA-F]+ // Unsigned hexadecimal integer | "0"[0-7]+ // Unsigned octal integer | [0-9]*.[0-9]+ // Unsigned floating point value | [0-9]*.[0-9]+[eE]-?[0-9]*.[0-9]+ // Unsigned floating point value with signed exponent constant: e // 2.7182818284590452353602874713527 | pi // 3.1415926535897932384626433832795
string: [^ 0-9 Operator precedence: 0 - unary operator (-, ~, !) 1 - *, /, 2 - +, -, 3 - <<, >>, <-, -> 4 - <, <=, >, >= 5 - ==, != 6 - & 7 - | 8 - ^ 9 - && 10 - || 11 - ^^ Definition at line 586 of file eval_num_expr.cpp. References _ExprPtr, MustBeEnd, TReturnState, and uint32. Referenced by evalExpression(), and NLGEORGES::CMyEvalNumExpr::evalValue().
00588 { 00589 // Init the ptr 00590 _ExprPtr = expression; 00591 00592 TToken nextToken; 00593 TReturnState error = evalExpression (result, nextToken, userData); 00594 if (error == NoError) 00595 { 00596 // The end ? 00597 if (nextToken == End) 00598 return NoError; 00599 else 00600 { 00601 if (errorIndex) 00602 *errorIndex = _ExprPtr - expression; 00603 return MustBeEnd; 00604 } 00605 } 00606 else 00607 { 00608 if (errorIndex) 00609 *errorIndex = _ExprPtr - expression; 00610 return error; 00611 } 00612 } |
|
Definition at line 1197 of file eval_num_expr.cpp. References arg1, and UnkownFunction.
01198 { 01199 return UnkownFunction; 01200 } |
|
Eval a user defined function. Default implementation returns UnkownFunction. The user can parse the function name and fill the result double and return NoError, UnkownFunction or FunctionError. To convert double argu in boolean argu, use (round (value) != 0.0) ? true : false
Definition at line 1190 of file eval_num_expr.cpp. References UnkownFunction. Referenced by evalExpression().
01191 { 01192 return UnkownFunction; 01193 } |
|
Overridable functions. Eval a user defined value. Default implementation returns UnkownValue. The user can parse the value and fill the result double and return NoError, UnkownValue or ValueError.
Reimplemented in NLGEORGES::CMyEvalNumExpr. Definition at line 1183 of file eval_num_expr.cpp. References uint32, UnkownValue, and value. Referenced by evalExpression(), and NLGEORGES::CMyEvalNumExpr::evalValue().
01184 { 01185 return UnkownValue; 01186 } |
|
Get error string.
Definition at line 1289 of file eval_num_expr.cpp. References _ErrorString.
01290 { 01291 return _ErrorString[state]; 01292 } |
|
Internal functions Get the next token.
Definition at line 96 of file eval_num_expr.cpp. References _ExprPtr, _InternalStlString, _InternalString, _InternalStringPtr, _OperatorArray, _ReservedWord, _ReservedWordFound, _ReservedWordToken, _StringChar, And, Close, Coma, Equal, ExtOperator, Inferior, InferiorEqual, InternalStringLen, LogicalAnd, LogicalOr, LogicalXor, Minus, MustBeDoubleQuote, Not, NotEqual, NotOperator, Number, NumberSyntaxError, Open, Or, readDecimal(), ReservedWordCount, sint, size, SLeftShift, SRightShift, Superior, SuperiorEqual, TReservedWord, TReturnState, uint, uint8, ULeftShift, UnkownOperator, URightShift, and Xor. Referenced by evalExpression().
00097 { 00098 // Get the current char 00099 uint8 currentChar = *_ExprPtr; 00100 00101 // Skip space 00102 while ((currentChar!=0) && (currentChar<=0x20)) 00103 { 00104 _ExprPtr++; 00105 currentChar = *_ExprPtr; 00106 } 00107 00108 // Can be an operator ? 00109 if (currentChar <= 128) 00110 { 00111 // Get the operator 00112 _Op = _OperatorArray[currentChar]; 00113 00114 // Is an operator ? 00115 if (_Op != NotOperator) 00116 { 00117 // It is an operator 00118 token = Operator; 00119 00120 // Is a 2 characters operator ? 00121 if (_Op != ExtOperator) 00122 { 00123 // Return next character 00124 _ExprPtr++; 00125 return NoError; 00126 } 00127 else 00128 { 00129 // Have a second character ? 00130 char secondChar = *(_ExprPtr+1); 00131 00132 // What kind of 1st character 00133 switch (currentChar) 00134 { 00135 case '!': 00136 if (secondChar == '=') 00137 { 00138 _Op = NotEqual; 00139 _ExprPtr+=2; 00140 return NoError; 00141 } 00142 else 00143 { 00144 _Op = Not; 00145 _ExprPtr++; 00146 return NoError; 00147 } 00148 case '&': 00149 if (secondChar == '&') 00150 { 00151 _Op = LogicalAnd; 00152 _ExprPtr+=2; 00153 return NoError; 00154 } 00155 else 00156 { 00157 _Op = And; 00158 _ExprPtr+=1; 00159 return NoError; 00160 } 00161 case '-': 00162 if (secondChar == '>') 00163 { 00164 _Op = SRightShift; 00165 _ExprPtr+=2; 00166 return NoError; 00167 } 00168 else 00169 { 00170 _Op = Minus; 00171 _ExprPtr++; 00172 return NoError; 00173 } 00174 case '<': 00175 if (secondChar == '<') 00176 { 00177 _Op = ULeftShift; 00178 _ExprPtr+=2; 00179 return NoError; 00180 } 00181 else if (secondChar == '=') 00182 { 00183 _Op = InferiorEqual; 00184 _ExprPtr+=2; 00185 return NoError; 00186 } 00187 else if (secondChar == '-') 00188 { 00189 _Op = SLeftShift; 00190 _ExprPtr+=2; 00191 return NoError; 00192 } 00193 else 00194 { 00195 _Op = Inferior; 00196 _ExprPtr+=1; 00197 return NoError; 00198 } 00199 case '=': 00200 if (secondChar == '=') 00201 { 00202 _Op = Equal; 00203 _ExprPtr+=2; 00204 return NoError; 00205 } 00206 case '>': 00207 if (secondChar == '>') 00208 { 00209 _Op = URightShift; 00210 _ExprPtr+=2; 00211 return NoError; 00212 } 00213 else if (secondChar == '=') 00214 { 00215 _Op = SuperiorEqual; 00216 _ExprPtr+=2; 00217 return NoError; 00218 } 00219 else 00220 { 00221 _Op = Superior; 00222 _ExprPtr+=1; 00223 return NoError; 00224 } 00225 case '^': 00226 if (secondChar == '^') 00227 { 00228 _Op = LogicalXor; 00229 _ExprPtr+=2; 00230 return NoError; 00231 } 00232 else 00233 { 00234 _Op = Xor; 00235 _ExprPtr+=1; 00236 return NoError; 00237 } 00238 case '|': 00239 if (secondChar == '|') 00240 { 00241 _Op = LogicalOr; 00242 _ExprPtr+=2; 00243 return NoError; 00244 } 00245 else 00246 { 00247 _Op = Or; 00248 _ExprPtr+=1; 00249 return NoError; 00250 } 00251 } 00252 00253 // Can't found the operator 00254 return UnkownOperator; 00255 } 00256 } 00257 // Is End, '(', ')', '.' ? 00258 else if (currentChar == 0) 00259 { 00260 token = End; 00261 return NoError; 00262 } 00263 else if (currentChar == '(') 00264 { 00265 _ExprPtr++; 00266 token = Open; 00267 return NoError; 00268 } 00269 else if (currentChar == ')') 00270 { 00271 _ExprPtr++; 00272 token = Close; 00273 return NoError; 00274 } 00275 else if (currentChar == ',') 00276 { 00277 _ExprPtr++; 00278 token = Coma; 00279 return NoError; 00280 } 00281 // Is a number ? 00282 else if ((currentChar >= '0') && (currentChar <= '9') || (currentChar == '.')) 00283 { 00284 // This is a number 00285 token = Number; 00286 00287 // Have a second character ? 00288 char secondChar = *(_ExprPtr+1); 00289 00290 // Is an hexadecimal value ? 00291 if ((currentChar == '0') && (secondChar == 'x')) 00292 { 00293 // Go to the number 00294 _ExprPtr +=2; 00295 currentChar = *_ExprPtr; 00296 00297 // Registered values 00298 register double regValue = 0; 00299 if ((currentChar >= '0') && (currentChar <= '9')) 00300 { 00301 regValue += (currentChar - '0'); 00302 } 00303 else if ((currentChar >= 'a') && (currentChar <= 'f')) 00304 { 00305 regValue += (currentChar - 'a' + 10); 00306 } 00307 else if ((currentChar >= 'A') && (currentChar <= 'F')) 00308 { 00309 regValue += (currentChar - 'A' + 10); 00310 } 00311 else 00312 { 00313 // Number syntax error 00314 return NumberSyntaxError; 00315 } 00316 _ExprPtr++; 00317 currentChar = *_ExprPtr; 00318 00319 // For each values 00320 while (1) 00321 { 00322 if ((currentChar >= '0') && (currentChar <= '9')) 00323 { 00324 regValue *= 16; 00325 regValue += (currentChar - '0'); 00326 } 00327 else if ((currentChar >= 'a') && (currentChar <= 'f')) 00328 { 00329 regValue *= 16; 00330 regValue += (currentChar - 'a' + 10); 00331 } 00332 else if ((currentChar >= 'A') && (currentChar <= 'F')) 00333 { 00334 regValue *= 16; 00335 regValue += (currentChar - 'A' + 10); 00336 } 00337 else 00338 { 00339 // Stop 00340 break; 00341 } 00342 00343 // Next char 00344 _ExprPtr++; 00345 currentChar = *_ExprPtr; 00346 } 00347 00348 // Store value 00349 _Value = regValue; 00350 00351 // Number ok 00352 return NoError; 00353 } 00354 // Is an octal value ? 00355 else if ((currentChar == '0') && (secondChar >= '0') && (secondChar <= '9')) 00356 { 00357 // Go to the number 00358 _ExprPtr ++; 00359 currentChar = *_ExprPtr; 00360 00361 // Registered values 00362 register double regValue = 0; 00363 00364 // Check octal number 00365 if (currentChar > '7') 00366 return NumberSyntaxError; 00367 00368 // Read the first value 00369 regValue += (currentChar - '0'); 00370 _ExprPtr++; 00371 currentChar = *_ExprPtr; 00372 00373 // For each values 00374 while ((currentChar >= '0') && (currentChar <= '9')) 00375 { 00376 // Check octal number 00377 if (currentChar > '7') 00378 return NumberSyntaxError; 00379 00380 regValue *= 8; 00381 regValue += (currentChar - '0'); 00382 00383 // Next char 00384 _ExprPtr++; 00385 currentChar = *_ExprPtr; 00386 } 00387 00388 // Store value 00389 _Value = regValue; 00390 00391 // Number ok 00392 return NoError; 00393 } 00394 // It is a decimal value 00395 else 00396 { 00397 // Read value 00398 TReturnState state = readDecimal (_Value); 00399 if (state == NoError) 00400 { 00401 // Exponent ? 00402 currentChar = *_ExprPtr; 00403 if ( (currentChar == 'e') || (currentChar == 'E') ) 00404 { 00405 // Next char 00406 _ExprPtr++; 00407 00408 // Minus ? 00409 bool negative = false; 00410 if (*_ExprPtr == '-') 00411 { 00412 negative = true; 00413 _ExprPtr++; 00414 } 00415 00416 // Read value 00417 double exponent; 00418 state = readDecimal (exponent); 00419 if (state == NoError) 00420 { 00421 // Negative value ? 00422 if (negative) 00423 exponent = -exponent; 00424 00425 // Raise 10 at the power of 00426 _Value *= pow (10.0, exponent); 00427 } 00428 else 00429 { 00430 return state; 00431 } 00432 } 00433 00434 // Number ok 00435 return NoError; 00436 } 00437 else 00438 { 00439 return state; 00440 } 00441 } 00442 } 00443 // Is a string ? 00444 else if (currentChar == '"') 00445 { 00446 // Look for the end of the string 00447 _ExprPtr++; 00448 currentChar = *_ExprPtr; 00449 const char *start = _ExprPtr; 00450 while ( (currentChar != 0) && (currentChar != '"') ) 00451 { 00452 _ExprPtr++; 00453 currentChar = *_ExprPtr; 00454 } 00455 00456 // End reached ? 00457 if (currentChar == 0) 00458 return MustBeDoubleQuote; 00459 00460 // This is a user string, copy the string 00461 uint size = _ExprPtr - start; 00462 if (size >= (InternalStringLen-1)) 00463 { 00464 _InternalStlString.resize (size); 00465 uint i; 00466 for (i=0; i<size; i++) 00467 _InternalStlString[i] = start[i]; 00468 _InternalStringPtr = _InternalStlString.c_str (); 00469 } 00470 else 00471 { 00472 memcpy (_InternalString, start, size); 00473 _InternalString[size] = 0; 00474 _InternalStringPtr = _InternalString; 00475 } 00476 00477 // Token 00478 _ExprPtr++; 00479 token = String; 00480 return NoError; 00481 } 00482 } 00483 00484 // Read a string 00485 const char *start = _ExprPtr; 00486 while ( (currentChar >= 128) || _StringChar[currentChar] ) 00487 { 00488 _ExprPtr++; 00489 currentChar = *_ExprPtr; 00490 } 00491 00492 // Is pi ? 00493 if (((_ExprPtr - start) == 2) && (start[0] == 'p') && (start[1] == 'i')) 00494 { 00495 token = Number; 00496 _Value = 3.1415926535897932384626433832795; 00497 return NoError; 00498 } 00499 // Is e ? 00500 else if (((_ExprPtr - start) == 1) && (start[0] == 'e')) 00501 { 00502 token = Number; 00503 _Value = 2.7182818284590452353602874713527; 00504 return NoError; 00505 } 00506 00507 // This is a user string, copy the string 00508 uint size = _ExprPtr - start; 00509 if (size >= (InternalStringLen-1)) 00510 { 00511 _InternalStlString.resize (size); 00512 uint i; 00513 for (i=0; i<size; i++) 00514 _InternalStlString[i] = start[i]; 00515 _InternalStringPtr = _InternalStlString.c_str (); 00516 } 00517 else 00518 { 00519 memcpy (_InternalString, start, size); 00520 _InternalString[size] = 0; 00521 _InternalStringPtr = _InternalString; 00522 } 00523 00524 // Search for a reserved word ? 00525 uint begin = 0; 00526 uint end = ReservedWordCount-1; 00527 sint result = strcmp (_InternalStringPtr, _ReservedWord[begin]); 00528 if ( result >= 0 ) 00529 { 00530 // The first is the good ? 00531 if ( result == 0 ) 00532 { 00533 end = begin; 00534 } 00535 00536 result = strcmp (_InternalStringPtr, _ReservedWord[end]); 00537 if (result <= 0) 00538 { 00539 // The last is the good ? 00540 if ( result == 0 ) 00541 { 00542 begin = end; 00543 } 00544 00545 // While there is a middle.. 00546 while ((end - begin) > 1) 00547 { 00548 uint middle = begin + (end - begin) / 2; 00549 result = strcmp (_InternalStringPtr, _ReservedWord[middle]); 00550 if (result == 0) 00551 { 00552 begin = middle; 00553 end = middle; 00554 break; 00555 } 00556 else if (result < 0) 00557 { 00558 end = middle; 00559 } 00560 else 00561 { 00562 begin = middle; 00563 } 00564 } 00565 } 00566 00567 // Found ? 00568 if (end == begin) 00569 { 00570 // Return the token 00571 _ReservedWordFound = (TReservedWord)begin; 00572 token = _ReservedWordToken[begin]; 00573 00574 // Ok 00575 return NoError; 00576 } 00577 } 00578 00579 // Token 00580 token = String; 00581 return NoError; 00582 } |
|
Definition at line 1127 of file eval_num_expr.cpp. References _ReservedWord, nlstop, ReservedWordCount, and uint.
01128 { 01129 for (uint i=0; i<ReservedWordCount-1; i++) 01130 if (strcmp (_ReservedWord[i], _ReservedWord[i+1]) >= 0) 01131 { 01132 nlstop; 01133 return false; 01134 } 01135 return true; 01136 } |
|
Read a decimal double.
Definition at line 37 of file eval_num_expr.cpp. References _ExprPtr, NumberSyntaxError, readIntegerNumberDecimal(), and value. Referenced by getNextToken().
00038 { 00039 // Read first integer value 00040 readIntegerNumberDecimal (value); 00041 00042 // Dot ? 00043 char currentChar = *_ExprPtr; 00044 if (currentChar == '.') 00045 { 00046 // Next char 00047 _ExprPtr++; 00048 currentChar = *_ExprPtr; 00049 if (currentChar < '0' || currentChar > '9') 00050 return NumberSyntaxError; 00051 00052 // Read the decimal part 00053 const char *start = _ExprPtr; 00054 double fract; 00055 readIntegerNumberDecimal (fract); 00056 fract /= (double)pow (10 ,(_ExprPtr-start)); 00057 value += fract; 00058 } 00059 00060 return NoError; 00061 } |
|
Read an integer.
Definition at line 65 of file eval_num_expr.cpp. References _ExprPtr, and value. Referenced by readDecimal().
00066 { 00067 // Registered values 00068 register double regValue = 0; 00069 00070 // Read the first value 00071 char currentChar = *_ExprPtr; 00072 if ((currentChar >= '0') && (currentChar <= '9')) 00073 { 00074 regValue += (currentChar - '0'); 00075 _ExprPtr++; 00076 currentChar = *_ExprPtr; 00077 00078 // For each values 00079 while ((currentChar >= '0') && (currentChar <= '9')) 00080 { 00081 regValue *= 10; 00082 regValue += (currentChar - '0'); 00083 00084 // Next char 00085 _ExprPtr++; 00086 currentChar = *_ExprPtr; 00087 } 00088 } 00089 00090 // Store value 00091 value = regValue; 00092 } |
|
Initial value: { "No error", "Unkown value", "Error during user defined value evaluation", "Unkown function", "Error during user defined function evaluation", "Syntax error in a number expression", "Unkown operator", "Should be a open parentesis", "Should be a close parentesis", "Should be a coma character", "Should be an expression", "Should not be an unary operator", "Should be the end of the expression", "Should be a double quote", "Divid by zero", } Definition at line 1268 of file eval_num_expr.cpp. Referenced by getErrorString(). |
|
Definition at line 297 of file eval_num_expr.h. Referenced by evalExpression(), getNextToken(), readDecimal(), and readIntegerNumberDecimal(). |
|
Definition at line 318 of file eval_num_expr.h. Referenced by getNextToken(). |
|
Current string.
Definition at line 317 of file eval_num_expr.h. Referenced by getNextToken(). |
|
Definition at line 319 of file eval_num_expr.h. Referenced by evalExpression(), and getNextToken(). |
|
Current operator.
Definition at line 325 of file eval_num_expr.h. |
|
Initial value: { NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator, NotOperator, NotOperator, Remainder, ExtOperator, NotOperator, NotOperator, NotOperator, Mul, Plus, NotOperator, ExtOperator, NotOperator, Div, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, ExtOperator, ExtOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, NotOperator, ExtOperator, NotOperator, Tilde, NotOperator, } Definition at line 1155 of file eval_num_expr.cpp. Referenced by getNextToken(). |
|
Initial value: { 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 0xffffffff, 20, } Definition at line 1296 of file eval_num_expr.cpp. Referenced by evalExpression(). |
|
Initial value: { "abs", "acos", "asin", "atan", "atan2", "ceil", "cos", "cosh", "exp", "exponent", "floor", "int", "log", "log10", "mantissa", "max", "min", "pow", "rand", "round", "sin", "sinh", "sq", "sqrt", "tan", "tanh", } Definition at line 1204 of file eval_num_expr.cpp. Referenced by getNextToken(), and internalCheck(). |
|
Reserved word.
Definition at line 314 of file eval_num_expr.h. Referenced by evalExpression(), and getNextToken(). |
|
Initial value: { Function1, Function1, Function1, Function1, Function2, Function1, Function1, Function1, Function1, Function1, Function1, Function1, Function1, Function1, Function1, Function2, Function2, Function2, Function2, Function1, Function1, Function1, Function1, Function1, Function1, Function1, }
Definition at line 1236 of file eval_num_expr.cpp. Referenced by getNextToken(). |
|
Members.
Definition at line 296 of file eval_num_expr.h. |
|
Initial value: { false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, true, false, false, true, false, false, false, false, false, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, false, false, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, false, true, false, true, } Definition at line 1169 of file eval_num_expr.cpp. Referenced by getNextToken(). |
|
Current value.
Definition at line 322 of file eval_num_expr.h. |