In my users' domain it is quite legitimate for tagnames to contain spaces. But when my users try to create expressions like "blue wave * Q1 costs / 100" there is an error like "Bad expression: Didn't expect 'wave' in this place"
There are a couple of ways to deal with this
The method that place the least demand on your users is to set the 'AllowSpacesInNames' property of the parser. If you set
myParser.AllowSpacesInNames = true;
prior to parsing any user expressions, then spaces are preserved.
Alternatively, if your users surround entity names with square brackets, e.g. "[blue wave]", this will also allow spaces and other 'odd' characters in tagnames.
My application occasionally has to deal with a comma-separated list of expressions. It was fine when I was dealing with "a,b,d", but sometimes I get "a+b, max(x,y,z), if(b>5, b, 0)", and my strategy of splitting the string on commas falls over completely. The CalcEnginePlus parser deals with this situation, is there any way I can access that functionality?
We exposed this functionality through a TagExpressionSplitter type, for just this reason. This class has a handy method
SeparateExpressions(string expressionList, bool allowSpacesInNames = false)
which will return a List of the separate expressions in an otherwise nasty list of expressions like the above. The method returns the expressions as a list of strings, which you can then Parse() or handle in some other way.
I'm parsing an expression involving a tag which doesn't exist, e.g.
var myOperand = parser.Parse("bad_tag")
I would expect the Operand returned by CalcEnginePlus to have an ErrorMessage, some thing like "bad_tag doesn't exist". But it doesn't. Is this a bug?
tl;dr: Invoke the Result property before accessing ErrorMessage
More detail: Parsing an expression prepares the expression to be evaluated. Among other things, the parsing process tells the calc engine which external tags will be required.
However, the calc engine doesn't know anything about YOUR data repositories. It cannot fetch tag values. Only your application can fetch values, and only your application can make the determination that a given tag does or does not exist.
The calc engine does not make any attempt to fetch values when an expression is parsed. Instead, it allows you to parse a number of expressions, and then batch up all the required tags in one efficient request to your external repository of tag values. Then, when your application invokes the Result property, your implementation of the GetNumericValue() method should be in a position to make a very quick determination (an in-memory lookup) as to whether a given tag exists.
That is why the parse-fetch-evaluate paradigm is emphasized, and that is why the ErrorMessage property of an Operand is undetermined until the Result property has been invoked.