JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
|
A simple function parser to parse (build memory tree representation) and evaluate simple mathematical expressions. More...
#include <jkqtpmathparser.h>
Classes | |
class | jkmpBinaryArithmeticNode |
This class represents a binary arithmetic operation: add (+), subtract (-), multiply (*), divide (/), a to the power of b (a^b) More... | |
class | jkmpBinaryBoolNode |
This class represents a binary boolean operation: and, or, xor, nor, nand. More... | |
class | jkmpCompareNode |
This class represents a binary compare operation: !=, ==, >=, <=, >, < More... | |
class | jkmpConstantNode |
This class represents a number, a string contant or a boolean contant (true / false ) More... | |
class | jkmpException |
error handling: exceptions of the type of this class will be thrown if an error occurs More... | |
struct | jkmpFunctionDescriptor |
description of a user registered function More... | |
class | jkmpFunctionNode |
This class represents an arbitrary function. More... | |
class | jkmpNode |
This class is the abstract base class for nodes. All allowed node types must inherit from jkmpNode. More... | |
class | jkmpNodeList |
This class represents a list of jkmpNode. More... | |
struct | jkmpResult |
result of any expression More... | |
struct | jkmpTempVariable |
This struct is for managing temporary variables. It is generally like jkmpVariable. More... | |
class | jkmpUnaryNode |
This class represents a unary operations: ! (bool negation), - (arithmetic negation) More... | |
struct | jkmpVariable |
This struct is for managing variables. Unlike jkmpResult this struct only contains pointers to the data. More... | |
class | jkmpVariableAssignNode |
This class represents a variable assignment (a = expression ) More... | |
class | jkmpVariableNode |
This class represents a variable. More... | |
Public Types | |
Abstract Syntax Tree / Memory Representation of Expressions | |
enum | jkmpResultType { jkmpDouble , jkmpString , jkmpBool } |
possible result types More... | |
enum class | jkmpLOP { LOPand ='a' , LOPor ='o' , LOPxor ='x' , LOPnor ='n' , LOPnand ='A' } |
internal names for logic operations More... | |
enum class | jkmpCOMP { equal ='=' , nequal ='!' , lesser ='<' , greater ='>' , lesserequal ='a' , greaterequal ='b' } |
jkmpCOMPdefs internal names for compare operations More... | |
typedef jkmpResult(* | jkmpEvaluateFunc) (jkmpResult *, unsigned char, JKQTPMathParser *) |
This is a function prototype for adding new mathematical functions to the parser. | |
Public Member Functions | |
JKQTPMathParser () | |
class constructor | |
virtual | ~JKQTPMathParser () |
class destructor | |
void | addFunction (const std::string &name, jkmpEvaluateFunc function) |
register a new function | |
void | addStandardFunctions () |
registers standard functions | |
void | addStandardVariables () |
registers standard variables | |
void | addVariable (const std::string &name, jkmpResult result) |
register a new internal variable of type boolean | |
void | addVariableBoolean (const std::string &name, bool *v) |
register a new external variable of type boolean | |
void | addVariableBoolean (const std::string &name, bool v) |
register a new internal variable of type boolean | |
void | addVariableDouble (const std::string &name, double *v) |
register a new external variable of type double | |
void | addVariableDouble (const std::string &name, double v) |
register a new internal variable of type double | |
void | addVariableString (const std::string &name, const std::string &v) |
register a new internal variable of type string | |
void | addVariableString (const std::string &name, std::string *v) |
register a new external variable of type string | |
void | clearFunctions () |
clears the list of internal functions | |
void | clearVariables () |
deletes all defined variables. the memory of internal variables will be released. the external memory will not be released. | |
void | deleteVariable (const std::string &name) |
delete the specified variabale and releases its internal memory. | |
jkmpResult | evaluate (const std::string &prog) |
evaluate the given expression | |
jkmpResult | evaluateFunction (const std::string &name, jkmpResult *params, unsigned char n) |
evaluates a registered function | |
bool | functionExists (const std::string &name) |
tests whether a function exists | |
std::string | getArgCVParam (const std::string &name, const std::string &defaultResult) |
return one of programs command-line arguments, or defaultResult if it is not present, used by the standard functions cmdparam and argv | |
jkmpEvaluateFunc | getFunctionDef (const std::string &name) |
returns the defining structure of the given function | |
jkmpResult | getVariable (const std::string &name) |
returns the value of the given variable | |
jkmpVariable | getVariableDef (const std::string &name) |
returns the defining structure of the given variable | |
jkmpResult | getVariableOrInvalid (const std::string &name) |
returns the value of the given variable | |
std::vector< std::pair< std::string, jkmpVariable > > | getVariables () |
returns all registered variables | |
jkmpNode * | parse (const std::string &prog) |
parses the given expression | |
void | printVariables () |
prints a list of all registered variables | |
void | setArgCV (int argc, char **argv) |
store programs command-line arguments, so they are available in the parser, used by the standard functions cmdparam and argv | |
bool | tempvariableExists (const std::string &name) |
tests whether a temporary variable exists | |
bool | variableExists (const std::string &name) |
tests whether a variable exists | |
Protected Member Functions | |
void | addTempVariable (const std::string &name, jkmpResult value) |
adds a temporary variable | |
void | setVariable (const std::string &name, jkmpResult value) |
set the defining struct of the given variable | |
void | setVariableDouble (const std::string &name, double value) |
set the defining struct of the given variable | |
Parser | |
jkmpNode * | compExpression (bool get) |
recognizes an compExpression while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
jkmpNode * | logicalExpression (bool get) |
recognizes a logicalExpression while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
jkmpNode * | logicalTerm (bool get) |
recognizes a logicalTerm while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
jkmpNode * | mathExpression (bool get) |
recognizes a mathExpression while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
jkmpNode * | mathTerm (bool get) |
recognizes a term while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
jkmpNode * | primary (bool get) |
recognizes a primary while parsing. If get ist true , this function first retrieves a new token by calling getToken() | |
Protected Attributes | |
int | argc |
storage for program argument cound, used by the standard functions cmdparam and argv | |
char ** | argv |
storage for program arguments, used by the standard functions cmdparam and argv | |
std::map< std::string, jkmpFunctionDescriptor > | functions |
map to manage all currently rtegistered functions | |
std::vector< jkmpTempVariable > | tempvariables |
vector containing all temporary variables | |
std::map< std::string, jkmpVariable > | variables |
map to manage all currently defined variables | |
Error Handling | |
typedef void(* | jkmpexceptionf) (std::string) |
type for a custom error handler. This an alternative error handling | |
jkmpexceptionf | jkmathparser_exception_function |
if this is nullptr then an exception may be thrown otherwise this should point to an error handler that will be called. | |
void | jkmpError (const std::string &st) |
function that throws an exception or calls an error handler | |
void | setException_function (jkmpexceptionf exception_function) |
activate error handling by use of an exception function | |
void | resetException_function () |
deactivate error handling by use of an exception function | |
Tokenizer | |
enum | jkmpTokenType { END , PRINT , PARAMETER_DIV , STRING_DELIM , NAME , NUMBER , PLUS , MINUS , MUL , DIV , MODULO , ASSIGN , LBRACKET , RBRACKET , POWER , FACTORIAL_LOGIC_NOT , LOGIC_NOT , LOGIC_AND , LOGIC_OR , LOGIC_XOR , LOGIC_NOR , LOGIC_NAND , LOGIC_TRUE , LOGIC_FALSE , COMP_EQUALT , COMP_UNEQUAL , COMP_GREATER , COMP_SMALLER , COMP_GEQUAL , COMP_SEQUAL } |
the possible tokens that can be recognized by the tokenizer in JKQTPMathParser::getToken() More... | |
jkmpTokenType | CurrentToken |
the current token while parsing a string | |
std::string | StringValue |
the string value of the current token (when applicable) during the parsing step | |
double | NumberValue |
the string value of the current token (when applicable) during the parsing step | |
std::istringstream * | program |
this stream is used to read in the program. An object is created and assigned (and destroyed) by the parse()-function | |
std::string | tokentostring (jkmpTokenType token) |
return the given token as human-readable string | |
std::string | currenttokentostring () |
return the current token as human-readable string | |
jkmpTokenType | getToken () |
Tokenizer: extract the next token from the input. | |
std::string | readDelim (char delimiter) |
return a delimited text, i.e. extract the texte between the delimiters "</code> in: of <code>"Hallo!" , i.e. returns Hallo! This is used to parse string constants. | |
A simple function parser to parse (build memory tree representation) and evaluate simple mathematical expressions.
This class implements a simple function parser which can parse mathematical expressions like z=a*3+2.34^2*sin(pi*sqrt(x))
. More than one expression can be separated by semicolon ';'. The result of a parse operation will be a memory structure (tree) representing the given expression. The parser can cope with constants and (user defined) variables and supports the data types number (double precision floating point), boolean (true/false) and string. It already contains a lot of fundamental mathematical functions (i.e. nearly all the functions from C StdLib).
This class provides management utilities for constants and variables. Variables can also be defined as external variables, when a pointer to corresponding memory is provided by the calling program. The parser supports a variable assign operation
which allows to define new variables during evaluation. There are some mathematical standard constants registered by calling JKQTPMathParser::addStandardVariables():
pi
= e
= sqrt2
= version
= the parser versionlog2e
= log10e
= ln2
= ln10
= h
= (planck constant)hbar
= (planck constant)epsilon0
= (electric constant)mu0
= (magnetic constant)c
= (speed of light in vacuum)ce
= (elementary charge)muB
= (Bohr magneton)muB_eV
= (Bohr magneton)muN
= (nuclear magneton)muN_eV
= (nuclear magneton)me
= (mass of electron)mp
= (mass of proton)mn
= (mass of neutron)NA
= (Avogadro constant = particles in 1 mol)kB
= (Boltzman constant)kB_eV
= (Boltzman constant)You can add user-defined contants by calling JKQTPMathParser::addVariableDouble() JKQTPMathParser::addVariableBoolean() or JKQTPMathParser::addVariableString()
this class provides a wide range of (mathematical) functions:
these functions are registered by calling JKQTPMathParser::addStandardFunctions(). you can add new functions by calling JKQTPMathParser::addFunction();
The result of calling JKQTPMathParser::parse() will be a tree-like structure in memory. The parse() function will return a pointer to the root node of this structure. All nodes inherit from jkmpNode class. To evaluate such a structure simply call jkmpNode::evaluate() of the root node. This will then return a jkmpResult structure which contains the result. This scheme allows for once parsing and multiply evaluating an expression. So if you want to define a function by an expression you can provide an external variable x as the argument and then evaluate the function for each x.
logical_expression -> logical_term | logical_expression or logical_term | logical_expression || logical_term
logical_term -> comp_expression | logical_term and comp_expression | logical_term && comp_expression
comp_expression -> math_expression | expression == math_expression | expression != math_expression | expression >= math_expression | expression <= math_expression | expression > math_expression | expression < math_expression
math_expression -> term | math_expression + math_term | math_expression - math_term
math_term -> primary | term * primary | term / primary | term ( % | mod ) primary
primary -> true | false | string_constant | NUMBER | NAME | NAME = logical_expression | + primary | - primary | ! primary | not primary | ( logical_expression ) | NAME( parameter_list ) | primary ^ primary
string_constant -> " STRING " | ' STRING '
parameter_list -> | logical_expression | logical_expression , parameter_list
In the above example we use error handling by use of exception (default behauviour).
It is also possible to change the error handling from using exceptions to calling a specific error handling function. This can be usefull in programs that don't support exceptions. To do so, use this cod:
typedef jkmpResult(* JKQTPMathParser::jkmpEvaluateFunc) (jkmpResult *, unsigned char, JKQTPMathParser *) |
This is a function prototype for adding new mathematical functions to the parser.
If you want to add more math functions (like sin, cos , abs ...) to the parser, you will have to implement it with this prototype and then register it with JKQTPMathParser::addFunction(). The first parameter points to an array containing the input parameters while the second one specifies the number of supplied parameters. The result has to be of type jkmpResult.
All error handling has to be done inside the function definition. Here is a simple example:
typedef void(* JKQTPMathParser::jkmpexceptionf) (std::string) |
type for a custom error handler. This an alternative error handling
|
strong |
|
strong |
|
protected |
the possible tokens that can be recognized by the tokenizer in JKQTPMathParser::getToken()
JKQTPMathParser::JKQTPMathParser | ( | ) |
class constructor
|
virtual |
class destructor
void JKQTPMathParser::addFunction | ( | const std::string & | name, |
jkmpEvaluateFunc | function | ||
) |
register a new function
name | name of the new function |
function | a pointer to the implementation |
void JKQTPMathParser::addStandardFunctions | ( | ) |
registers standard functions
void JKQTPMathParser::addStandardVariables | ( | ) |
registers standard variables
|
protected |
adds a temporary variable
void JKQTPMathParser::addVariable | ( | const std::string & | name, |
jkmpResult | result | ||
) |
register a new internal variable of type boolean
name | name of the new variable |
result | initial value of this variable |
void JKQTPMathParser::addVariableBoolean | ( | const std::string & | name, |
bool * | v | ||
) |
register a new external variable of type boolean
name | name of the new variable |
v | pointer to the variable memory |
void JKQTPMathParser::addVariableBoolean | ( | const std::string & | name, |
bool | v | ||
) |
register a new internal variable of type boolean
name | name of the new variable |
v | initial value of this variable |
void JKQTPMathParser::addVariableDouble | ( | const std::string & | name, |
double * | v | ||
) |
register a new external variable of type double
name | name of the new variable |
v | pointer to the variable memory |
void JKQTPMathParser::addVariableDouble | ( | const std::string & | name, |
double | v | ||
) |
register a new internal variable of type double
name | name of the new variable |
v | initial value of this variable |
void JKQTPMathParser::addVariableString | ( | const std::string & | name, |
const std::string & | v | ||
) |
register a new internal variable of type string
name | name of the new variable |
v | initial value of this variable |
void JKQTPMathParser::addVariableString | ( | const std::string & | name, |
std::string * | v | ||
) |
register a new external variable of type string
name | name of the new variable |
v | pointer to the variable memory |
void JKQTPMathParser::clearFunctions | ( | ) |
clears the list of internal functions
void JKQTPMathParser::clearVariables | ( | ) |
deletes all defined variables. the memory of internal variables will be released. the external memory will not be released.
|
protected |
recognizes an compExpression while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
|
protected |
return the current token as human-readable string
void JKQTPMathParser::deleteVariable | ( | const std::string & | name | ) |
delete the specified variabale and releases its internal memory.
jkmpResult JKQTPMathParser::evaluate | ( | const std::string & | prog | ) |
evaluate the given expression
jkmpResult JKQTPMathParser::evaluateFunction | ( | const std::string & | name, |
jkmpResult * | params, | ||
unsigned char | n | ||
) |
evaluates a registered function
name | name of the (registered function) to be evaluated |
params | array of the input parameters |
n | number of input parameters (<=8) |
bool JKQTPMathParser::functionExists | ( | const std::string & | name | ) |
tests whether a function exists
std::string JKQTPMathParser::getArgCVParam | ( | const std::string & | name, |
const std::string & | defaultResult | ||
) |
return one of programs command-line arguments, or defaultResult if it is not present, used by the standard functions cmdparam
and argv
jkmpEvaluateFunc JKQTPMathParser::getFunctionDef | ( | const std::string & | name | ) |
returns the defining structure of the given function
|
protected |
Tokenizer: extract the next token from the input.
jkmpResult JKQTPMathParser::getVariable | ( | const std::string & | name | ) |
returns the value of the given variable
jkmpVariable JKQTPMathParser::getVariableDef | ( | const std::string & | name | ) |
returns the defining structure of the given variable
jkmpResult JKQTPMathParser::getVariableOrInvalid | ( | const std::string & | name | ) |
returns the value of the given variable
std::vector< std::pair< std::string, jkmpVariable > > JKQTPMathParser::getVariables | ( | ) |
returns all registered variables
void JKQTPMathParser::jkmpError | ( | const std::string & | st | ) |
function that throws an exception or calls an error handler
|
protected |
recognizes a logicalExpression while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
|
protected |
recognizes a logicalTerm while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
|
protected |
recognizes a mathExpression while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
|
protected |
recognizes a term while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
jkmpNode * JKQTPMathParser::parse | ( | const std::string & | prog | ) |
parses the given expression
|
protected |
recognizes a primary while parsing. If get ist true
, this function first retrieves a new token by calling getToken()
void JKQTPMathParser::printVariables | ( | ) |
prints a list of all registered variables
|
protected |
return a delimited text, i.e. extract the texte between the delimiters "</code> in: of <code>"Hallo!"
, i.e. returns Hallo!
This is used to parse string constants.
This functions actually reads pascal style delimited string constants. So if you want to use the delimiter as part of the string you will have to write it as doubled character. So 'Jan''s Test'
stands for Jan's Test
.
void JKQTPMathParser::resetException_function | ( | ) |
deactivate error handling by use of an exception function
void JKQTPMathParser::setArgCV | ( | int | argc, |
char ** | argv | ||
) |
store programs command-line arguments, so they are available in the parser, used by the standard functions cmdparam
and argv
void JKQTPMathParser::setException_function | ( | jkmpexceptionf | exception_function | ) |
activate error handling by use of an exception function
|
protected |
set the defining struct of the given variable
|
protected |
set the defining struct of the given variable
bool JKQTPMathParser::tempvariableExists | ( | const std::string & | name | ) |
tests whether a temporary variable exists
|
protected |
return the given token as human-readable string
bool JKQTPMathParser::variableExists | ( | const std::string & | name | ) |
tests whether a variable exists
|
protected |
storage for program argument cound, used by the standard functions cmdparam
and argv
|
protected |
storage for program arguments, used by the standard functions cmdparam
and argv
|
protected |
the current token while parsing a string
|
protected |
map to manage all currently rtegistered functions
|
private |
if this is nullptr then an exception may be thrown otherwise this should point to an error handler that will be called.
|
protected |
the string value of the current token (when applicable) during the parsing step
|
protected |
this stream is used to read in the program. An object is created and assigned (and destroyed) by the parse()-function
|
protected |
the string value of the current token (when applicable) during the parsing step
|
protected |
vector containing all temporary variables
|
protected |
map to manage all currently defined variables