Operators¶
Operators that the valid expressions can use are defined in property System.Collections.Generic.IReadOnlyList<UniversalExpressionParser.IOperatorInfo> Operators { get; } in interface UniversalExpressionParser.IExpressionLanguageProvider (an instance of this interface is passed to the parser).
The interface UniversalExpressionParser.IOperatorInfo has properties for operator name (i.e., a collection of texts that operator consists of, such as [“IS”, “NOT”, “NUL”] or [“+=”]), priority, unique Id, operator type (i.e., binary, unary prefix or unary postfix).
Two different operators can have similar names, as long as they have different operator. For example “++” can be used both as unary prefix as well as unary postfix operator.
Example of defining operators in an implementation of UniversalExpressionParser.IExpressionLanguageProvider¶
1public class TestExpressionLanguageProviderBase : ExpressionLanguageProviderBase
2{
3 //...
4 // Some other method and property implementations here
5 // ...
6 public override IReadOnlyList<IOperatorInfo> Operators { get; } = new IOperatorInfo[]
7 {
8 // The third parameter (e.g., 0) is the priority.
9 new OperatorInfo(1, new [] {"!"}, OperatorType.PrefixUnaryOperator, 0),
10 new OperatorInfo(2, new [] {"IS", "NOT", "NULL"}, OperatorType.PostfixUnaryOperator, 0),
11
12 new OperatorInfo(3, new [] {"*"}, OperatorType.BinaryOperator, 10),
13 new OperatorInfo(4, new [] {"/"}, OperatorType.BinaryOperator, 10),
14
15 new OperatorInfo(5, new [] {"+"}, OperatorType.BinaryOperator, 30),
16 new OperatorInfo(6, new [] {"-"}, OperatorType.BinaryOperator, 30),
17 }
18}
Operator expression (e.g., “a * b + c * d”) is parsed to an expression item of type UniversalExpressionParser.ExpressionItems.IOperatorExpressionItem (a subclass of UniversalExpressionParser.ExpressionItems.IComplexExpressionItem).
Click here to see the definition of UniversalExpressionParser.ExpressionItems.IOperatorExpressionItem
For example the expression “a * b + c * d”, will be parsed to an expression logically similar to “(+(a, b), +(x,d))”. This is so since the binary operator “+” has lower priority (the value of **IOperatorInfo.Priority* is larger), than the binary operator “*”.
In other words this expression will be parsed to a binary operator expression item for “+” (i.e., an instance of IOperatorExpressionItem) with Operand1 and Operand2 also being binary operator expression items of type UniversalExpressionParser.ExpressionItems.IOperatorExpressionItem for expression items “a * b” and “c * d”.
Example of considering priorities when parsing operators¶
1// The binary operator + has priority 30 and * has priority 20. Therefore,
2// in expression below, * is applied first and + is applied next.
3// The following expression is parsed to an expression equivalent to
4// "=(var y, +(x1, *(f1(x2, +(x3, 1)), x4)))"
5var y = x1 + f1(x2,x3+1)*x4;
Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult
Example of using braces to change order of application of operators¶
1// Without the braces, the expression below would be equivalent to x1+(x2*x3)-x4.
2var y1 = [x1+x2]*(x3-x4);
Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult
Example of operators with multiple parts in operator names¶
1// The expression below is similar to
2// z = !((x1 IS NOT NULL) && (x2 IS NULL);
3z = !(x1 IS NOT NULL && x2 IS NULL);
Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult
Example of two operators (e.g., postfix operators, then a binary operator) used next to each other without spaces in between¶
1// The spaces between two ++ operators, and + was omitted intentionally to show that the parser will parse the expression
2// correctly even without the space.
3// The expression below is similar to println(((x1++)++)+x2). To avoid confusion, in some cases it is better to use braces.
4println(x1+++++x2)
Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult
Example of unary prefix operator used to implement “return” statement¶
1// return has priority int.MaxValue which is greater then any other operator priority, therefore
2// the expression below is equivalent to "return (x+(2.5*x))";
3return x+2.5*y;
4
5// another example within function body
6f1(x:int, y:int) : bool
7{
8 // return has priority int.MaxValue which is greater then any other operator priority, therefore
9 // the expression below is equivalent to "return (x+(2.5*x))";
10 return f(x)+y > 10;
11}
Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult