// expression.cpp: Implementation of the CEXPIESSION CLASS.
//
//
#include "stdafx.h"
#include "expression.h"
#include "math.h"
Const int funlen = 17; // Function Table Length
Double Sign (double x);
Static Double (* funTable []) (double) = {
ACOS, ASIN, ATAN,
CEIL, COS, COSH, EXP,
FABS, FLOOR, LOG, LOG10,
Sin, Sinh, SQRT,
Tan, Tanh, Sign
}; // Single parameter function entry address table
Static char funnametable [] [6] = {
"ACOS", "Asin", "Atan", "CEIL", "COS", "COSH", "Exp", "Fabs",
"floor", "log", "log10", "sin", "sinh", "sqrt", "tan", "tanh", "sign"
}; // function name table
//
// cvar class
//
//
// construction / destruction
//
Cvar :: CVAR ()
{
INITVAR ();
}
Cvar :: ~ cvar ()
{
}
Void Cvar :: initvar ()
{
m_cflag = 1;
m_strname = "";
M_STRSLAVE = ""
m_dvalue = 0;
}
//
// Cvarlist Class
//
//
// construction / destruction
//
Cvarlist :: cvarlist ()
{
}
Cvarlist :: ~ cvarlist ()
{
List
For (iter = m_varlist.begin (); it! = m_varlist.end (); iter )
{
Delete (* iter);
}
m_varlist.clear ();
}
Bool Cvarlist :: Addvar (CVAR * PVAR)
{
m_varlist.insert (m_varlist.end (), pvar);
Return True;
}
//
// construction / destruction
//
CEXPIRESSION :: CEXPRESSION ()
{
m_ierrflag = 0;
m_ifunflag = 0;
m_imatchflag = 0;
m_dresult = 0;
m_bdegunit = true;
m_strexp = NULL;
STRCPY (M_STRTOKEN, "");
}
CEXPIRESSION :: ~ CEXPRESSION ()
{
}
Bool CEXPIRESSION :: Calexp ()
{
Bool ret;
m_ierrflag = 0;
m_ifunflag = 0;
m_imatchflag = 0;
m_dresult = 0;
IF (strlen (m_strexp) == 0)
{
m_ierrflag = 1; error ();
Return False;
}
Updateslavevar ();
// Take the first unit (using m_strexp)
IF (getToken () == true)
{
// Enter high priority operations
RET = Level1 (& m_dResult);
// If the advanced operation has an error (m_ierrflag is set)
IF (RET == FALSE)
{
// Print the error message
Error ();
Return False;
}
Else
Return True;
}
// Take a symbol error from the expression
m_ierrflag = 2;
Error ();
Return False;
}
Void CEXPRESSION :: Error ()
{
Switch (m_ierrflag)
{
Case 1:
Message ("Expression is empty!");
Break;
Case 2:
Message ("" Variable or function illegal or grammatic error! / N expressible! ");
Break;
Case 3:
Message ("Brand does not match!"); // "Brand does not match!"
Break;
}
}
Void CEXPID :: Message (const char * strmsg)
{
// Printf ("/ n% s / n", strmsg);
}
Bool CEXPIRESSION :: getToken ()
{
Register char * TEMP;
m_ctoketype = 0;
/ / Pointer pointing to TOKEN's first address
Temp = m_STRTOKEN;
// Skip spaces and TAB characters
While (iswhite (* m_strexp) == True)
M_STREXP ;
// The first character is operator
IF (isinstr (* m_strexp, " - * /% ^ = (),") == true)
{
m_ctoyType = Delimiter;
* TEMP = * m_strexp ;
* TEMP = 0;
Return True;
}
// The first character is an ASSCI character or Chinese characters
ELSE IF (isalpha (* m_strexp) || (* m_strexp> 127) || (* m_strexp <0))))
{
/ / Find the end of the string
While (isdelim (* m_strexp)! = true)
* TEMP = * m_strexp ;
* TEMP = 0;
IF (isfunc (m_strtoken))
{
m_ctokentype = function;
Return True;
}
/ / Search Variables, determine if the obtained symbol is a variable
String stokeen = m_strtoken;
List
For (iter = m_varlist.m_varlist.begin (); it! = m_varlist.m_varlist.end (); iter )
{
IF (* ip) -> m_strname == stokeen)
{
m_ctoke = variable;
Return True;
}
}
Return False;
}
// First character is a number
Else IF (isdigit (* m_strexp) || * m_strexp == '.')
{
//.5 Press 0.5 to process IF (* m_strexp == '.')
* TEMP = '0';
While (isdelim (* m_strexp)! = true)
* TEMP = * m_strexp ;
* TEMP = 0;
m_ctoytype = Number;
Return True;
}
// The first character is NULL
IF (* m_strexp == 0)
{
STRCPY (M_STRTOKEN, "");
// arrive at the end
Return True;
}
Return False;
}
/ / Judgment is a space or Tab
Bool Cexpression :: Iswhite (Char C)
{
IF (c == '|| c == 9)
Return True;
Return False;
}
/ / Judgment is a separator
Bool CEXPIRESSION :: Isdelim (Char C)
{
IF (Isinstr (C, " - * /% ^ = (),") == true || c == 9 || c == '/ r' || c == 0)
Return True;
Return False;
}
// Judgment is a function
Bool CEXPIRESSION :: IsFunc (const char * fname)
{
INT I;
For (i = 0; i { IF (strcmp (fname, funnametable [i]) == 0) Return True; } Return False; } / / Judgment whether C is in string S Bool CEXPIRESSION :: Isinstr (char ch, char * s) { While (* s) { IF (* s == CH) Return True; } Return False; } Double Sign (Double X) { IF (x> 0) Return X; Else Return 0; } // Assignment operation Bool CEXPIRESSION :: Level1 (Double * Result) { INT INDEX, TTOK_TYPE; CHAR TEMP_TOKEN [80]; // Variable unit, it is possible to assign a value-assigned expression operation IF (m_ctoketype == variable) { / / Reserved the unit and unit type STRCPY (TEMP_TOKEN, M_STRTOKEN); TTOK_TYPE = m_ctokeType; // If you do not get the index value of the variable in the variable table IF (GetvarIndex (M_STRTOKEN, & INDEX)! = true) { m_ierrflag = 2; Return False; } IF (gettoken ()! = TRUE) { m_ierrflag = 2; // m_ierrflag = 1; Return False; } // If the variable is tight with the '=' number, it is assigned, otherwise it is generally IF (* m_strtoken! = '=') { // Put the original unit to the expression Putback (); / / Restore the current unit variable and variable type STRCPY (m_strtoken, temp_token); m_ctokentype = ttok_type; } // If you enter the following operations ELSE { // Take the unit behind the '=' number IF (gettoken ()! = TRUE) { m_ierrflag = 2; // m_ierrflag = 1; Return False; } // Enter advanced - operation IF (level2) == true { List INT i = 0; For (iter = m_varlist.m_varlist.begin (); it! = m_varlist.m_varlist.end (); iter ) { IF (i == Index) { (* iTer) -> m_dvalue = * result; Return True; } i ; } } Else Return False; } } // The first unit is not a variable, directly enter the high priority - operation IF (level2) == true Return True; Else Return False; } // Add or subtraction Bool CEXPIRESSION :: Level2 (Double * Result) { Register char OP; // operator Double Hold = 0; // Reserved Intermediate Results / / Directly enter the high priority * /% operation, no advanced operations enter the following operations IF (level3 (result)! = TRUE) Return False; // If the next unit is While ((OP = * m_STRTOKEN) == ' ' || op == '-') { // Number of units after IF (getToken () == true) { // Operation - The expression value after the number is likely to get IF (Level3 (& Hold) == True) { // Mathematical operation, the result is directly in * result Bool Bret = Arith (OP, Result, & Hold); IF (Bret == False) Return False; } Else Return False; } Else { m_ierrflag = 2; // m_ierrflag = 1; Return False; } } Return True; } // Ride and expensive arithmetic operations Bool CEXPIRESSION :: Level3 (Double * Result) { Register char OP; // operator Double Hold = 0; // Reserved intermediate computing results / / Directly enter the high priority operation, no advanced operations enter the following operations IF (Level4 (RESULT)! = true) Return False; // If the next unit is * /% While ((OP = * m_STRTOKEN) == '*' || op == '/' || op == '%') { // A unit after acquiring operator IF (getToken () == true) { // Operate * /% expressive value, it is possible to obtain * /% IF (Level4 (& Hold) == True) { // Mathematical operation, the result is in * result Bool nret = Arith (OP, Result, & Hold); if (nret == false) Return False; } Else Return False; } Else { m_ierrflag = 2; // m_ierrflag = 1; Return False; } } Return True; } // Passenger operation Bool CEXPIRESSION :: Level4 (double * result) { Register char OP; // operator Double Hold = 0; // Reserved intermediate computing results / / Directly enter the high priority operation, no advanced operations enter the following operations IF (Level5 (Result)! = true) Return False; // If the next unit is ^ (passenger) While ((OP = * m_STRTOKEN) == '^') { IF (getToken () == true) { // A unit after acquiring operator IF (Level5 (& Hold) == True) { // After the calculation ^ The expression value is likely to get it again. Bool nret = Arith (OP, Result, & Hold); IF (NRET == FALSE) Return False; } Else Return False; } Else { m_ierrflag = 2; // m_ierrflag = 1; Return False; } } Return True; } // Single-eyed anti-vehicle Bool CEXPIRESSION :: Level5 (double * result) { Register char OP = 0; IF ((m_ctokeType == Delimiter) && * m_strtoken == ' ' || * m_strtoken == '-') { // If the expression first unit is number or - number, record the operator Op = * m_STRTOKEN; // get the next unit IF (gettoken ()! = TRUE) { m_ierrflag = 2; // m_ierrflag = 1; Return False; } } // Enter high priority operations IF (level6 (result)! = true) Return False; // Enter high priority operations IF (op) UNARY (OP, Result); Return True; }