Summary

UniversalExpressionParser is a library for parsing expressions like the one demonstrated below into expression items for functions, literals, operators, etc.

 1var z = x1*y1+x2*y2;
 2
 3var matrixMultiplicationResult = [[x1_1, x1_2, x1_3], [x2_1, x2_2, x2_3]]*[[y1_1, x1_2], [y2_1, x2_2], [y3_1, x3_2]];
 4
 5println(matrixMultiplicationResult);
 6
 7[NotNull] [PublicName("Calculate")]
 8public F1(x, y) : int =>
 9{
10
11    /*This demos multiline
12    comments that can be placed anywhere*/
13    ++y /*another multiline comment*/;
14    return 1.3EXP-2.7+ ++x+y*z; // Line comments.
15}
16
17public abstract class ::metadata{description: "Demo prefix"} ::types[T1, T2, T3] Animal
18   where T1: IType1 where T2: T1, IType2 whereend
19   where T3: IType3 whereend
20{
21    public abstract Move() : void;
22}
23
24public class Dog : (Animal)
25{
26    public override Move() : void => println("Jump");
27}
  • Below is the demo code used to parse this expression:

 1using TextParser;
 2using UniversalExpressionParser.DemoExpressionLanguageProviders;
 3
 4namespace UniversalExpressionParser.Tests.Demos
 5{
 6    public class SummaryDemo
 7    {
 8        private readonly IExpressionParser _expressionParser;
 9        private readonly IExpressionLanguageProvider _nonVerboseLanguageProvider = new NonVerboseCaseSensitiveExpressionLanguageProvider();
10        private readonly IExpressionLanguageProvider _verboseLanguageProvider = new VerboseCaseInsensitiveExpressionLanguageProvider();
11        private readonly IParseExpressionOptions _parseExpressionOptions = new ParseExpressionOptions();
12
13        public SummaryDemo()
14        {
15            IExpressionLanguageProviderCache expressionLanguageProviderCache =
16                new ExpressionLanguageProviderCache(new DefaultExpressionLanguageProviderValidator());
17
18            _expressionParser = new ExpressionParser(new TextSymbolsParserFactory(), expressionLanguageProviderCache);
19
20            expressionLanguageProviderCache.RegisterExpressionLanguageProvider(_nonVerboseLanguageProvider);
21            expressionLanguageProviderCache.RegisterExpressionLanguageProvider(_verboseLanguageProvider);
22        }
23
24        public IParseExpressionResult ParseNonVerboseExpression(string expression)
25        {
26            /*
27            The same instance _expressionParser of UniversalExpressionParser.IExpressionParser can be used
28            to parse multiple expressions using different instances of UniversalExpressionParser.IExpressionLanguageProvider
29            Example:
30
31            var parsedExpression1 = _expressionParser.ParseExpression(_nonVerboseLanguageProvider.LanguageName, "var x=2*y; f1() {++x;} f1();");
32            var parsedExpression2 = _expressionParser.ParseExpression(_verboseLanguageProvider.LanguageName, "var x=2*y; f1() BEGIN ++x;END f1();");
33            */
34            return _expressionParser.ParseExpression(_nonVerboseLanguageProvider.LanguageName, expression, _parseExpressionOptions);
35        }
36    }
37}
  • Expression is parsed to an instance of UniversalExpressionParser.IParseExpressionResult by calling the method IParseExpressionResult ParseExpression(string expressionLanguageProviderName, string expressionText, IParseExpressionOptions parseExpressionOptions) in UniversalExpressionParser.IExpressionParser.

  • The interface UniversalExpressionParser.IParseExpressionResult (i.e., result of parsing the expression) has a property UniversalExpressionParser.ExpressionItems.IRooxExpressionItem RootExpressionItem { get; } that stores the root expression item of a tree structure of parsed expression items.

  • The code that evaluates the parsed expression can use the following properties in UniversalExpressionParser.ExpressionItems.IRootExpressionItem to iterate through all parsed expression items:

    • IEnumerable<IExpressionItemBase> AllItems { get; }

    • IReadOnlyList<IExpressionItemBase> Prefixes { get; }

    • IReadOnlyList<IKeywordExpressionItem> AppliedKeywords { get; }

    • IReadOnlyList<IExpressionItemBase> RegularItems { get; }

    • IReadOnlyList<IExpressionItemBase> Children { get; }

    • IReadOnlyList<IExpressionItemBase> Postfixes { get; }

    • IReadOnlyList<IExpressionItemBase> Prefixes { get; }

  • All expressions are parsed either to expressions items of type UniversalExpressionParser.ExpressionItems.IExpressionItemBase or one of its subclasses for simple expressions or to expressions items of type UniversalExpressionParser.ExpressionItems.IComplexExpressionItem (which is a sub-interface of UniversalExpressionParser.ExpressionItems.IExpressionItemBase) or one of its subclasses for expression items that consists of other expression items.

  • Some examples simple expression items are: UniversalExpressionParser.ExpressionItems.ICommaExpressionItem for commas, UniversalExpressionParser.ExpressionItems.IOpeningBraceExpressionItem and UniversalExpressionParser.ExpressionItems.IClosingBraceExpressionItem for opening and closing braces “(” and “)”

  • Some complex expression items are: UniversalExpressionParser.ExpressionItems.IBracesExpressionItem for functions like “f1 (x1, x2)”, UniversalExpressionParser.ExpressionItems.IOperatorExpressionItem for operators like the binary operator with operands “f1(x)” and “y” in “f1(x) + y”.

  • All expressions are currently parsed to one of the following expression items (or intances of other sub-interfaces of these interfaces) in namespaces UniversalExpressionParser.ExpressionItems and UniversalExpressionParser.ExpressionItems.Custom: ILiteralExpressionItem, ILiteralNameExpressionItem, IConstantTextExpressionItem, IConstantTextValueExpressionItem, INumericExpressionItem, INumericExpressionValueItem, IBracesExpressionItem, IOpeningBraceExpressionItem, IClosingBraceExpressionItem, ICommaExpressionItem, ICodeBlockExpressionItem, ICustomExpressionItem, IKeywordExpressionItem, ICodeBlockStartMarkerExpressionItem, ICodeBlockEndMarkerExpressionItem, ISeparatorCharacterExpressionItem, IOperatorExpressionItem, IOperatorInfoExpressionItem, IKeywordExpressionItem, UniversalExpressionParser.ExpressionItems.Custom.ICustomExpressionItem, IRootExpressionItem, IComplexExpressionItem, ITextExpressionItem, IExpressionItemBase. The state of this expression items can be analyzed when evaluating the parsed expression.

Click here to see the visualized instance of UniversalExpressionParser.IParseExpressionResult

  • The format of valid expressions is defined by properties and methods in interface UniversalExpressionParser.IExpressionLanguageProvider. The expression language name UniversalExpressionParser.IExpressionLanguageProvider.LanguageName of some instance UniversalExpressionParser.IExpressionLanguageProvider is passed as a parameter to method ParseExpression(…) in UniversalExpressionParser.IExpressionParser, as demonstrated in example above. Most of the properties and methods of this interface are demonstrated in examples in sections below.

  • The default abstract implementation of this interface in this package is UniversalExpressionParser.ExpressionLanguageProviderBase. In most cases, this abstract class can be extended and abstract methods and properties can be implemented, rather than providing a brand new implementation of UniversalExpressionParser.IExpressionLanguageProvider.

  • The test project UniversalExpressionParser.Tests in git repository has a number of tests for testing successful parsing, as well as tests for testing expressions that result in errors (see section Error Reporting below). These tests generate random expressions as well as generate randomly configured instances of UniversalExpressionParser.IExpressionLanguageProvider to validate parsing of thousands of all possible languages and expressions (see the test classes UniversalExpressionParser.Tests.SuccessfulParseTests.ExpressionParserSuccessfulTests and UniversalExpressionParser.Tests.ExpressionParseErrorTests.ExpressionParseErrorTests).

  • The demo expressions and tests used to parse the demo expressions in this documentation are in folder Demos in test project UniversalExpressionParser.Tests. This documentation uses implementations of UniversalExpressionParser.IExpressionLanguageProvider in project UniversalExpressionParser.DemoExpressionLanguageProviders in git repository.

  • The parsed expressions in this documentation (i.e., instances of UniversalExpressionParser.ExpressionItems.IParseExpressionResult) are visualized into xml texts, that contain values of most properties of the parsed expression. However, to make the files shorter, the visualized xml files do not include all the property values.