#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. |
1.3.6