NLMISC::CEvalNumExpr Class Reference

#include <eval_num_expr.h>

Inheritance diagram for NLMISC::CEvalNumExpr:

NLGEORGES::CMyEvalNumExpr

Detailed Description

This class preforms numerical expression parsing.

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]


Member Enumeration Documentation

anonymous enum [private]
 

Enumeration values:
InternalStringLen 
InternalOperator 

Definition at line 289 of file eval_num_expr.h.

00290         {
00291                 InternalStringLen = 32,
00292                 InternalOperator = 4,
00293         };

enum NLMISC::CEvalNumExpr::TOperator [private]
 

Enumeration values:
Not 
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 

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         };

enum NLMISC::CEvalNumExpr::TReservedWord [private]
 

Enumeration values:
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 
ReservedWordCount 

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         };

enum NLMISC::CEvalNumExpr::TReturnState
 

Eval return error.

Enumeration values:
NoError 
UnkownValue 
ValueError 
UnkownFunction 
FunctionError 
NumberSyntaxError 
UnkownOperator 
MustBeOpen 
MustBeClose 
MustBeComa 
MustBeExpression 
NotUnaryOperator 
MustBeEnd 
MustBeDoubleQuote 
DividByZero 
ReturnValueCount 

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         };

enum NLMISC::CEvalNumExpr::TToken [private]
 

Implementation Expression tokens.

Enumeration values:
Number 
Function1 
Function2 
String 
Operator 
Open 
Close 
Coma 
End 

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         };


Constructor & Destructor Documentation

virtual NLMISC::CEvalNumExpr::~CEvalNumExpr  )  [inline, virtual]
 

Definition at line 40 of file eval_num_expr.h.

00040 {}


Member Function Documentation

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::evalExpression double &  result,
TToken nextToken,
uint32  userData
[private]
 

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 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::evalExpression const char *  expression,
double &  result,
int *  errorIndex,
uint32  userData = 0
 

Evaluate a numerical expression.

Doesn't allocate heap memory for common complexity expression.

Parameters:
expression is an expression string. See the expression grammar.
result is filled with the result if the function returns "NoError".
errorIndex is a pointer on an integer value filled with the index of the parsing error in the input string if function doesn't return "NoError". This value can be NULL.
userData is a user data used by user eval function
Returns:
NoError if the expression has been parsed. Result is filled with the evaluated value.
This expression must follow the following grammar with the following evaluation priority:

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
/\*-+=<>&|\^!%~\(\)\.,\"][^ \t\n/\*-+=<>&|\^!%~\(\)\.,\"]* // Labels ($foo, #foo01, _001) | \"[]+\" // All kind of labels between double quotes "123456" "foo.foo[12]"

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 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::evalFunction const char *  funcName,
double  arg0,
double  arg1,
double &  result
[protected, virtual]
 

Definition at line 1197 of file eval_num_expr.cpp.

References arg1, and UnkownFunction.

01198 {
01199         return UnkownFunction;
01200 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::evalFunction const char *  funcName,
double  arg0,
double &  result
[protected, virtual]
 

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

Parameters:
funcName is the name of the function to evaluate.
arg0 is the first parameter passed to the function.
arg1 is the second parameter passed to the function.
result is the result to fill if the value has been succesfully parsed.
Returns:
UnkownFunction if the function doesn't exist, FunctionError if the function evaluation failed, NoError if it has been parsed.

Definition at line 1190 of file eval_num_expr.cpp.

References UnkownFunction.

Referenced by evalExpression().

01191 {
01192         return UnkownFunction;
01193 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::evalValue const char *  value,
double &  result,
uint32  userData
[protected, virtual]
 

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.

Parameters:
value is the value to parse.
result is the result to fill if the value has been succesfully parsed.
userData is a user data used by user eval function.
Returns:
UnkownValue if the value is not known, ValueError is the value evaluation failed or NoError if it has been parsed.

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 }

const char * NLMISC::CEvalNumExpr::getErrorString TReturnState  state  )  const
 

Get error string.

Definition at line 1289 of file eval_num_expr.cpp.

References _ErrorString.

01290 {
01291         return _ErrorString[state];
01292 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::getNextToken TToken token  )  [private]
 

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 }

bool NLMISC::CEvalNumExpr::internalCheck  ) 
 

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 }

CEvalNumExpr::TReturnState NLMISC::CEvalNumExpr::readDecimal double &  value  )  [private]
 

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 }

void NLMISC::CEvalNumExpr::readIntegerNumberDecimal double &  value  )  [private]
 

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 }


Field Documentation

const char * NLMISC::CEvalNumExpr::_ErrorString [static, private]
 

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().

const char* NLMISC::CEvalNumExpr::_ExprPtr [private]
 

Definition at line 297 of file eval_num_expr.h.

Referenced by evalExpression(), getNextToken(), readDecimal(), and readIntegerNumberDecimal().

std::string NLMISC::CEvalNumExpr::_InternalStlString [private]
 

Definition at line 318 of file eval_num_expr.h.

Referenced by getNextToken().

char NLMISC::CEvalNumExpr::_InternalString[InternalStringLen] [private]
 

Current string.

Definition at line 317 of file eval_num_expr.h.

Referenced by getNextToken().

const char* NLMISC::CEvalNumExpr::_InternalStringPtr [private]
 

Definition at line 319 of file eval_num_expr.h.

Referenced by evalExpression(), and getNextToken().

TOperator NLMISC::CEvalNumExpr::_Op [private]
 

Current operator.

Definition at line 325 of file eval_num_expr.h.

const CEvalNumExpr::TOperator NLMISC::CEvalNumExpr::_OperatorArray [static, private]
 

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().

const int NLMISC::CEvalNumExpr::_OperatorPrecedence [static, private]
 

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().

const char * NLMISC::CEvalNumExpr::_ReservedWord [static, private]
 

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().

TReservedWord NLMISC::CEvalNumExpr::_ReservedWordFound [private]
 

Reserved word.

Definition at line 314 of file eval_num_expr.h.

Referenced by evalExpression(), and getNextToken().

const CEvalNumExpr::TToken NLMISC::CEvalNumExpr::_ReservedWordToken [static, private]
 

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, 
}
Static values Char to operator array.

Definition at line 1236 of file eval_num_expr.cpp.

Referenced by getNextToken().

TReturnState NLMISC::CEvalNumExpr::_State [private]
 

Members.

Definition at line 296 of file eval_num_expr.h.

const bool NLMISC::CEvalNumExpr::_StringChar [static, private]
 

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().

double NLMISC::CEvalNumExpr::_Value [private]
 

Current value.

Definition at line 322 of file eval_num_expr.h.


The documentation for this class was generated from the following files:
Generated on Tue Mar 16 13:09:38 2004 for NeL by doxygen 1.3.6