-
Notifications
You must be signed in to change notification settings - Fork 0
Defining operators
The parser is extensible with different kinds of operators: prefix operators, infix operators and binary operators. Operators can be applied to numerical values only (not to string constants).
- Postfix operators are operators that succeed values. For instance the factorial operator (
a! = a*(a-1)...*2*1
). Another application for postfix operators is their use as multipliers that can be used for implementing units. - Infix operators are operators like the unary minus which serves as a sign or the logical not
"!(a<9)"
. - Binary operators can be defined in order to supplement or replace the built in binary operators they require an additional parameter, the operator priority.
Both postfix and infix operators take callback functions of type FunType1
like the following:
double MyCallback(double val)
{
return val / 1000.0;
}
For defining postfix operators and infix operators you need a valid parser instance, an identifier string, and a third parameter marking the operator as volatile (non optimizable). The last parameter is merely a hint for the parser. It is not guaranteed that optimization will take place. If a function is marked as being optimizable function calls may be replaced with a precomputed result if the parser detects that the argument is a constant. This is safe for functions as long as they always return the same result when fed with the same input parameter. (An example where optimization is not desired is a function returning random numbers). To define the operators:
// Define an infix operator
parser.DefineInfixOprt("!", MyCallback, false);
// Define a postfix operators
parser.DefinePostfixOprt("m", MyCallback, false);
muParser has 15 Built in binary operators but sometimes it might be necessary to add additional custom binary operators. Examples are shl
or shr
, the "shift left" and "shift right" operators for integer numbers. You can bind any callback of type FunType2
as a binary operator to muParserNET
. The operator can then be defined by using the functions DefineOprt
:
ParserBase::DefineOprt(string ident,
FunType2 function,
uint precedence,
OprtAssociativity associativity,
bool optimizeable);
For the definition of binary operators the following parameters are required:
-
ident: A string representing the operator identifier. By default muParser restricts the set of characters useable in operator identifiers. You can modify this set by using the function
DefineOprtChars
. -
function: The second parameter is a function pointer to a static callback function of type
FunType2
. This is the place were you have to implement your operator logic. -
precedence: An integer value determining the operator precedence. When dealing with multiple operations involving binary operators without using brackets this value determines which operator is excuted first. The binary operator with the higher precedence values is executed first. For instance: In the expression 2 + 3 * 4 the result is 14 since the multiplication has a higher precedence value than the addition. For convenience
muParserNET
defines the static classOprtPrecedence
which you can use its constants values listed here as reference when implementing custom operators:
// binary operators
LOR = 1,
LAND = 2,
LOGIC = 3, // logic operators
CMP = 4, // comparsion operators
ADD_SUB = 5, // addition
MUL_DIV = 6, // multiplication/division
POW = 7, // power operator priority (highest)
// infix operators
INFIX = 6, // Signs have a higher priority than ADD_SUB, but lower than power operator
POSTFIX = 6 // Postfix operator priority (currently unused)
-
associativity: The operator associativity determines how operators of the same precedence are grouped in the absence of parentheses. Operators can either be left or right associative. For instance consider the expression
5^4^3^2
. Depending on the operator associativity this expression could either be interpreted as5^(4^(3^2))
which correctly implements the power operator as a right associative operator or alternatively one could also evaluate:((5^4)^3)^2
The parser defines the following enumeration to represent associativity values:
enum OprtAssociativity
{
LEFT = 0, // left associative operator
RIGHT = 1, // right associative operator
NONE = 2
};
- optimizeable: This parameter determines whether the operator always returns the same result when fed with the same input. Normally this is the case so it should be true. There are very few scenarios where an operator does not always return the same values when fed with the same input (i.e. when random number generation is involved).
Finally I'd like to point out that if you encounter confilcts with built in operators or simply dont need the built in operators at all they can easily be deactivated using the EnableBuiltInOprt(bool)
function. If you call this function you must add binary operators manually. After all without any operators you won't be able to parse anything useful. User defined operators come with approximately 10% decrease in parsing speed compared to built in operators. There is no way to avoid that. They cause an overhead when calling theeir callback functions. (This is the reason why there are built in operators)
// disable all built in operators
parser.EnableBuiltInOprt(false);
- Getting started
- Setting and evaluating an expression
- Setting the expression
- Single return expression evaluation
- Multiple return expression evaluation
- Bulk mode evaluations
- Error handling
- Defining identifier charsets
- Defining parser variables
- Explicitely defining variables
- Implicit creation of new variables
- Querying parser variables
- Removing variables
- Defining constants
- Defining parser constants
- Querying parser constants
- Removing constants
- Setting custom value recognition callbacks
- Defining functions
- Defining parser functions
- Bulk mode functions
- Defining parser operators
- Unary operators
- Binary operators
- Disable built-in operators
- Localization