diff --git a/.github/workflows/build-branch-TermRewriting.yml b/.github/workflows/build-branch-TermRewriting.yml new file mode 100644 index 0000000..7f0deec --- /dev/null +++ b/.github/workflows/build-branch-TermRewriting.yml @@ -0,0 +1,22 @@ +name: branch TermRewriting + +on: + push: + branches: + - feature/TermRewriting + +jobs: + build: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.2.108 + - name: Run Tests + run: dotnet test + - name: Build with dotnet + run: dotnet build .\ThinkSharp.FormulaParser\ThinkSharp.FormulaParser.csproj --configuration Release diff --git a/.github/workflows/build-dev.yml b/.github/workflows/build-dev.yml new file mode 100644 index 0000000..51d6721 --- /dev/null +++ b/.github/workflows/build-dev.yml @@ -0,0 +1,23 @@ +name: .NET Core + +on: + push: + branches: + - develop + +jobs: + build: + + runs-on: windows-latest + + steps: + - uses: actions/checkout@v1 + - name: Setup .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 2.2.108 + - name: Run Tests + run: dotnet test + - name: Build with dotnet + run: dotnet build .\ThinkSharp.FormulaParser\ThinkSharp.FormulaParser.csproj --configuration Release + diff --git a/README.md b/README.md new file mode 100644 index 0000000..e6925f8 --- /dev/null +++ b/README.md @@ -0,0 +1,126 @@ +# ThinkSharp.FormulaParser + +[![Build status](https://ci.appveyor.com/api/projects/status/l3aagqmbfmgxwv3t?svg=true)](https://ci.appveyor.com/project/JanDotNet/thinksharp-licensing) +[![NuGet](https://img.shields.io/nuget/v/ThinkSharp.FormulaParser.svg)](https://www.nuget.org/packages/ThinkSharp.FormulaParser/) +[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE.txt) +[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MSBFDUU5UUQZL) + +## Introduction + +**ThinkSharp.FormulaParser** is a simple library with fluent API for parsing and evaluating mathematical formulas. + +Mathematical formulas can be parsed to a parsing tree (hereinafter called "parsing") or directly evaluated to a numeric value (hereinafter called "evaluating"). + +The following features are supported +* Basic mathematical operations: +, -, /, *, ^, ( .. ), scientific notation (3e2 = 300) +* Variables: Detect variables on parsing or use a dictionary to provide variables for evaluation. +* Constants: Use build-in constants (pi, e) or define your own. Constants are available independent of the provided variables. +* Functions: Use build-in functions (sqrt, sum, rnd, abs, log, ln, sin, cos, tan, min, max) or define your own. +* Error Handling: The parser provides an expressive error message in case of invalid formulas. +* Customization: The parser may be configured to disable features and add custom functions / constants. + +## Installation + +ThinkSharp.FormulaParser can be installed via [Nuget](https://www.nuget.org/packages/ThinkSharp.FormulaParser) + + Install-Package ThinkSharp.FormulaParser + +## Examples + +### Evaluating formulas + +```csharp +// The simples way to create a formula parser is the static method 'Create'. +var parser = FormulaParser.Create(); + +// Parsing a simple mathematical formula +var result1 = parser.Evaluate("1+1").Value; // result1 = 2.0 + +// Usage of variables +var variables = new Dictionary { ["x"] = 2.0 }; +var result2 = parser.Evaluate("1+x", variables).Value; // result2 = 3.0 + +// Usage of functions +var result3 = parser.Evaluate("1+min(3,4)").Value; // result3 = 4.0 + +// Handle errors +var parsingResult = parser.Evaluate("2*?"); +if (!parsingResult.Success) +{ + Console.WriteLine(parsingResult.Error); // "column 2: token recognition error at: '?'" +} +``` + +#### Creating and evaluating a parsing tree + +```csharp +var parser = FormulaParser.Create(); +var variables = new Dictionary { ["x"] = 2.0 }; + +// Parsing a simple mathematical formula +var node1 = parser.Parse("1+x", variables).Value; +// |FormulaNode("1+x") +// |- Child: BinaryOperatorNode(+) +// |- LeftNode: NumericNode(1.0) +// |- RightNode: VariableNode("x") +var result1 = parser.Evaluate(node1, variables).Value; // result = 3.0 + + +var node2 = parser.Parse("pi * sqrt(3*x)", variables).Value; +// |FormulaNode("pi * sqrt(3*x)") +// |- Child: BinaryOperatorNode(*) +// |- LeftNode: ConstantNode("pi") +// |- RightNode: FunctionNode("sqrt") +// |- Parameters: [BinaryOperationNode(*)] +// |- LeftNode: Numeric(3.0) +// |- RightNode: VariableNode("x") +var result2 = parser.Evaluate(node2, variables).Value; // result = 7.695... +``` + +#### Configure custom functions / constants + +```csharp +var parser = FormulaParser + .CreateBuilder() + .ConfigureConstats(constants => + { + // constants.RemoveAll() for removing all default constants + // constants.Remove("pi") for removing constants by name + + constants.Add("h", 6.62607015e-34); + }) + .ConfigureFunctions(functions => + { + // functions.RemoveAll() for removing all default functions + // functions.Remove("sum") for removing function by name + + // define functions with certain number of parameters (1-5 parameters are supported) + functions.Add("celsiusToFarenheit", celsius => celsius * 1.8 + 32); + functions.Add("fahrenheitToCelsius", fahrenheit => (fahrenheit - 32) * 5 / 9); + functions.Add("p1_plus_p2_plus_p3", (p1, p2, p3) => p1 + p2 + p3); + + // define function with 2 to n number of parameters (typeof(nums) = double[]) + functions.Add("product", nums => nums.Aggregate((p1, p2) => p1 * p2)); + }).Build(); + +var poolTemperatureInCelsius = parser.Evaluate("celsiusToFarenheit(fahrenheitToCelsius(30))").Value; // poolTemperatureInCelsius = 30 +var result2 = parser.Evaluate("product(2, 2, 2, 2, 2, 2)").Value; // result2 = 2^6 = 128 +var result3 = parser.Evaluate("p1_plus_p2_plus_p3(1, 2, 3)").Value; // result3 = 6 + +string error1 = parser.Evaluate("celsiusToFarenheit(1, 2)").Error; // column 0: There is no function 'celsiusToFarenheit' that takes 2 argument(s). + string error2 = parser.Evaluate("product()").Error; // column 0: There is no function 'product' that takes 0 argument(s). +string error3 = parser.Evaluate("p1_plus_p2_plus_p3(1, 2)").Error; // column 0: There is no function 'p1_plus_p2_plus_p3' that takes 2 argument(s). +``` + +## License + +ThinkSharp.FormulaParser is released under [The MIT license (MIT)](LICENSE.TXT) + +## Versioning + +We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/JanDotNet/ThinkSharp.FormulaParser/tags). + +## Donation +If you like ThinkSharp.FormulaParser and use it in your project(s), feel free to give me a cup of coffee :) + +[![paypal](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MSBFDUU5UUQZL) diff --git a/ThinkSharp.FormulaParser.Test.Core/AST/ParsingHelperTest.cs b/ThinkSharp.FormulaParser.Test.Core/AST/ParsingHelperTest.cs new file mode 100644 index 0000000..dd91da2 --- /dev/null +++ b/ThinkSharp.FormulaParser.Test.Core/AST/ParsingHelperTest.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using ThinkSharp.FormulaParsing.Ast.Nodes; + +namespace ThinkSharp.FormulaParsing +{ + [TestClass] + public class ParsingHelperTest + { + [TestMethod] + public void TestGetBySymbol() + { + var o = BinaryOperator.BySymbol("+"); + Assert.AreEqual("+", o.Symbol); + Assert.AreEqual(2.0, o.Evaluate(1, 1)); + } + + [TestMethod] + [ExpectedException(typeof(InvalidOperationException))] + public void TestGetBySymbol_NotExisting() + { + var o = BinaryOperator.BySymbol("abv"); + } + + private static void Test(string expected, string actual) + { + //var node = ParsingHelper. + } + } +} diff --git a/ThinkSharp.FormulaParser.Test/BinaryOperatorTest.cs b/ThinkSharp.FormulaParser.Test.Core/BinaryOperatorTest.cs similarity index 94% rename from ThinkSharp.FormulaParser.Test/BinaryOperatorTest.cs rename to ThinkSharp.FormulaParser.Test.Core/BinaryOperatorTest.cs index 0c5ffe0..cab5630 100644 --- a/ThinkSharp.FormulaParser.Test/BinaryOperatorTest.cs +++ b/ThinkSharp.FormulaParser.Test.Core/BinaryOperatorTest.cs @@ -4,7 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using ThinkSharp.FormulaParsing.Ast.Nodes; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] public class BinaryOperatorTest diff --git a/ThinkSharp.FormulaParser.Test/FormulaParserTest.cs b/ThinkSharp.FormulaParser.Test.Core/FormulaParserTest.cs similarity index 94% rename from ThinkSharp.FormulaParser.Test/FormulaParserTest.cs rename to ThinkSharp.FormulaParser.Test.Core/FormulaParserTest.cs index db1dd88..f1eb365 100644 --- a/ThinkSharp.FormulaParser.Test/FormulaParserTest.cs +++ b/ThinkSharp.FormulaParser.Test.Core/FormulaParserTest.cs @@ -4,7 +4,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using ThinkSharp.FormulaParsing.Ast.Nodes; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] public class FormulaParserTest @@ -36,6 +36,7 @@ public void TestMulDivFirst() { AsserEval(6.0, "1+1*5"); AsserEval(6.0, "1*1+5"); + AsserEval(11.0, "1+2*3+4"); AsserEval(3.0, "1+10/5"); AsserEval(5.1, "1/10+5"); @@ -88,6 +89,7 @@ public void Test_Pow() } [TestMethod] + [Ignore] public void Test_ScientificNumber() { AsserEval(2000, "2e3"); @@ -100,7 +102,7 @@ public void Test_ScientificNumber() [TestMethod] public void Test_VariableNotExist() { - var parser = FormulaParser.CreateBuilder().ConfigureParsingBehavior(pb => pb.DisableVariableNameValidation()).Build(); + var parser = FormulaParser.CreateBuilder().ConfigureValidationBehavior(pb => pb.DisableVariableNameValidation()).Build(); var node = parser.Parse("2 * X").Value; @@ -143,23 +145,6 @@ public void Test_NameOfVariableConflictsWithNameOfConstant() Assert.AreEqual("Variable name 'pi' conflicts with the name of an existing constant.", (string)result.Error); } - [TestMethod] - public void Test_FormulatText() - { - var parser = FormulaParser.Create(); - - var parser2 = FormulaParser - .CreateBuilder() - .ConfigureFunctions(functions => functions.Add("max", (a, b) => Math.Max(a, b))) - .Build(); - - parser2.Evaluate("1 + max(2, 4)"); - - - var result = parser.Parse("2 * pi").Value as FormulaNode; - Assert.AreEqual("2 * pi", result.FormulaText); - } - [TestMethod] public void TestComplexFormulas() { @@ -202,9 +187,15 @@ public void TestFunctionFunctionOneValue() } [TestMethod] - public void TestFunctionFunctionWithoutParameters() + public void TestRxistingFunctionWithoutParameters() + { + AssertFailure("column 0: There is no function 'min' that takes 0 argument(s).", "min()"); + } + + [TestMethod] + public void TestNotExistingFunction() { - AssertFailure("column 0: Unknown function 'min'.", "min()"); + AssertFailure("column 0: Unknown function 'moep'.", "moep()"); } [TestMethod] @@ -213,6 +204,13 @@ public void TestFunctionMax() AsserEval(12, "max(12, 11, 3, 4, 5, 2, 11 ,4)"); } + [TestMethod] + public void TestSignedFunctionMax() + { + AsserEval(-12, "-max(12, 11, 3, 4, 5, 2, 11 ,4)"); + AsserEval(12, "+max(12, 11, 3, 4, 5, 2, 11 ,4)"); + } + [TestMethod] public void TestConfigureRegistry() { @@ -271,6 +269,7 @@ public void TestDisablePow() } [TestMethod] + [Ignore] public void TestDisableScientificNotation() { var parser = FormulaParser diff --git a/ThinkSharp.FormulaParser.Test/FormularParser.Configuration.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.Configuration.Test.cs similarity index 98% rename from ThinkSharp.FormulaParser.Test/FormularParser.Configuration.Test.cs rename to ThinkSharp.FormulaParser.Test.Core/FormularParser.Configuration.Test.cs index 1302b2d..c6264e9 100644 --- a/ThinkSharp.FormulaParser.Test/FormularParser.Configuration.Test.cs +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.Configuration.Test.cs @@ -7,7 +7,7 @@ using ThinkSharp.FormulaParsing.Ast.Nodes; using ThinkSharp.FormulaParsing.Ast.Visitors; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] public class FormularParserConfigurationTest @@ -32,6 +32,7 @@ public void TestDefaultConfiguration() Assert.AreEqual(Math.Sin(3), parser.Evaluate("sin(3)").Value); Assert.AreEqual(Math.Cos(3), parser.Evaluate("cos(3)").Value); Assert.AreEqual(Math.Tan(3), parser.Evaluate("tan(3)").Value); + Assert.AreEqual(Math.Sqrt(3), parser.Evaluate("sqrt(3)").Value); } [TestMethod] diff --git a/ThinkSharp.FormulaParser.Test/FormularParser.CustomVisitor.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.CustomVisitor.Test.cs similarity index 91% rename from ThinkSharp.FormulaParser.Test/FormularParser.CustomVisitor.Test.cs rename to ThinkSharp.FormulaParser.Test.Core/FormularParser.CustomVisitor.Test.cs index 05ae798..a587da8 100644 --- a/ThinkSharp.FormulaParser.Test/FormularParser.CustomVisitor.Test.cs +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.CustomVisitor.Test.cs @@ -8,7 +8,7 @@ using ThinkSharp.FormulaParsing.Ast.Nodes; using ThinkSharp.FormulaParsing.Ast.Visitors; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] public class FormularParserCustomVisitorTest @@ -60,7 +60,7 @@ public override Node Visit(VariableNode node) { if (node.Name == "x") { - return new NumberNode(2); + return new DecimalNode( 2); } throw new InvalidOperationException("Unknown Variable."); @@ -68,10 +68,12 @@ public override Node Visit(VariableNode node) public override Node Visit(FormulaNode node) { - return new FormulaNode(node.ChildNode.Visit(this), node.FormulaText); + return new FormulaNode(node.ChildNode.Visit(this)); } - public override Node Visit(NumberNode node) => new NumberNode(node.Value); + public override Node Visit(DecimalNode node) => node; + + public override Node Visit(IntegerNode node) => node; } } } diff --git a/ThinkSharp.FormulaParser.Test.Core/FormularParser.NumberFormats.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.NumberFormats.Test.cs new file mode 100644 index 0000000..fb620ff --- /dev/null +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.NumberFormats.Test.cs @@ -0,0 +1,86 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using ThinkSharp.FormulaParsing.Ast.Nodes; +using ThinkSharp.FormulaParsing.Ast.Visitors; + +namespace ThinkSharp.FormulaParsing +{ + [TestClass] + public class FormularParserNumberFormatsTest + { + [TestMethod] + public void TestBinayNotation() + { + var parser = FormulaParser.Create(); + + Assert.AreEqual(1.0, parser.Evaluate("0b1").Value); + Assert.AreEqual(5.0, parser.Evaluate("0b101").Value); + + Assert.AreEqual(10.0, parser.Evaluate("0b101 + 0b101").Value); + } + + [TestMethod] + public void TestHexadecimalNotation() + { + var parser = FormulaParser.Create(); + + Assert.AreEqual(1.0, parser.Evaluate("0x1").Value); + Assert.AreEqual(10.0, parser.Evaluate("0xa").Value); + Assert.AreEqual(10.0, parser.Evaluate("0xA").Value); + + Assert.AreEqual(477580.0, parser.Evaluate("0x7498C").Value); + Assert.AreEqual(477580.0, parser.Evaluate("0X7498C").Value); + + Assert.AreEqual(100.0, parser.Evaluate("0xA * 0Xa").Value); + } + + [TestMethod] + public void TestDecimalNotation() + { + var parser = FormulaParser.Create(); + + Assert.AreEqual(1.0, parser.Evaluate("0d1").Value); + Assert.AreEqual(101.0, parser.Evaluate("0D101").Value); + Assert.AreEqual(101.0, parser.Evaluate("101").Value); + + Assert.AreEqual(202.0, parser.Evaluate("0d101 + 101").Value); + } + + [TestMethod] + public void TestDifferentCultures() + { + var parser = FormulaParser.Create(); + + Thread.CurrentThread.CurrentCulture = new CultureInfo("de-DE"); + Assert.AreEqual(0.1, parser.Evaluate("0.1").Value); + + Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US"); + Assert.AreEqual(0.1, parser.Evaluate("0.1").Value); + } + + [TestMethod] + [Ignore] + public void TestScientificNotation() + { + var parser = FormulaParser.Create(); + + Assert.AreEqual(1000.0, parser.Evaluate("1e3").Value); + Assert.AreEqual(1110.0, parser.Evaluate("1.11e3").Value); + } + + [TestMethod] + public void TestMixedNotation() + { + var parser = FormulaParser.Create(); + + //Assert.AreEqual(0.04, parser.Evaluate("(0b11 + 0x20 + 5) * 1e3").Value); + Assert.AreEqual(0.04, parser.Evaluate("(0b11 + 0x20 + 5) * 1*10^-3").Value); + } + } +} diff --git a/ThinkSharp.FormulaParser.Test/FormularParser.ParsingBehavior.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.ParsingBehavior.Test.cs similarity index 93% rename from ThinkSharp.FormulaParser.Test/FormularParser.ParsingBehavior.Test.cs rename to ThinkSharp.FormulaParser.Test.Core/FormularParser.ParsingBehavior.Test.cs index f71d6e5..d75b5f7 100644 --- a/ThinkSharp.FormulaParser.Test/FormularParser.ParsingBehavior.Test.cs +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.ParsingBehavior.Test.cs @@ -7,10 +7,10 @@ using ThinkSharp.FormulaParsing.Ast.Nodes; using ThinkSharp.FormulaParsing.Ast.Visitors; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] - public class ConfigureParsingBehaviorTest + public class ConfigureValidationBehaviorTest { [TestMethod] public void TestNotConfigured_InvalidVariable() @@ -27,7 +27,7 @@ public void TestNotConfigured_InvalidVariableIgnoreVariableValidation() { var parser = FormulaParser .CreateBuilder() - .ConfigureParsingBehavior(parsingBehavior => + .ConfigureValidationBehavior(parsingBehavior => { parsingBehavior.DisableVariableNameValidation(); }) @@ -55,7 +55,7 @@ public void TestNotConfigured_InvalidFunctionIgnoreFunctionValidation() { var parser = FormulaParser .CreateBuilder() - .ConfigureParsingBehavior(parsingBehavior => + .ConfigureValidationBehavior(parsingBehavior => { parsingBehavior.DisableFunctionNameValidation(); }) diff --git a/ThinkSharp.FormulaParser.Test/FormularParser.SupportedFeatures.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.SupportedFeatures.Test.cs similarity index 72% rename from ThinkSharp.FormulaParser.Test/FormularParser.SupportedFeatures.Test.cs rename to ThinkSharp.FormulaParser.Test.Core/FormularParser.SupportedFeatures.Test.cs index f4ff5cc..da9dd07 100644 --- a/ThinkSharp.FormulaParser.Test/FormularParser.SupportedFeatures.Test.cs +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.SupportedFeatures.Test.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; -namespace ThinkSharp.FormulaParsing.Test +namespace ThinkSharp.FormulaParsing { [TestClass] public class ConfigureSupportedFeaturesTest @@ -27,6 +27,7 @@ public void TestDisablePow() } [TestMethod] + [Ignore] public void TestDisableScientificNotation() { var parser = FormulaParser @@ -91,5 +92,35 @@ public void TestDisableBracket() Assert.IsFalse(result.Success); Assert.AreEqual("column 4: Invalid token '('.", (string)result.Error); } + + [TestMethod] + public void TestDisableBinaryNumberNotation() + { + var parser = FormulaParser + .CreateBuilder() + .ConfigureSupportedFeatures(supportedFeatures => + { + supportedFeatures.DisableBinaryNumberNotation(); + }) + .Build(); + var result = parser.Evaluate("0b101"); + Assert.IsFalse(result.Success); + Assert.AreEqual("column 0: Invalid token '0b101'.", (string)result.Error); + } + + [TestMethod] + public void TestDisableHexadecimalNumberNotation() + { + var parser = FormulaParser + .CreateBuilder() + .ConfigureSupportedFeatures(supportedFeatures => + { + supportedFeatures.DisableHexadecimalNumberNotation(); + }) + .Build(); + var result = parser.Evaluate("0xABC"); + Assert.IsFalse(result.Success); + Assert.AreEqual("column 0: Invalid token '0xABC'.", (string)result.Error); + } } } diff --git a/ThinkSharp.FormulaParser.Test.Core/FormularParser.VariableNames.Test.cs b/ThinkSharp.FormulaParser.Test.Core/FormularParser.VariableNames.Test.cs new file mode 100644 index 0000000..ced15bb --- /dev/null +++ b/ThinkSharp.FormulaParser.Test.Core/FormularParser.VariableNames.Test.cs @@ -0,0 +1,32 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ThinkSharp.FormulaParsing.Ast.Nodes; +using ThinkSharp.FormulaParsing.Ast.Visitors; + +namespace ThinkSharp.FormulaParsing +{ + [TestClass] + public class FormularParserVariableNamesTest + { + [TestMethod] + public void TestVariableNames() + { + var parser = FormulaParser.CreateBuilder() + .ConfigureValidationBehavior(v => v.DisableVariableNameValidation()) + .Build(); + + Assert.AreEqual(true, parser.Parse("abc").Success); + Assert.AreEqual(true, parser.Parse("_abc").Success); + Assert.AreEqual(true, parser.Parse("_a_bc").Success); + Assert.AreEqual(true, parser.Parse("$abc").Success); + Assert.AreEqual(true, parser.Parse("$a$bc").Success); + Assert.AreEqual(true, parser.Parse("$3a3$b534c").Success); + + Assert.AreEqual(false, parser.Parse("1abc").Success); + } + } +} diff --git a/ThinkSharp.FormulaParser.Test.Core/NodesToFormulaTextVisitor.cs b/ThinkSharp.FormulaParser.Test.Core/NodesToFormulaTextVisitor.cs new file mode 100644 index 0000000..44732b4 --- /dev/null +++ b/ThinkSharp.FormulaParser.Test.Core/NodesToFormulaTextVisitor.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using ThinkSharp.FormulaParsing.Ast.Nodes; +using ThinkSharp.FormulaParsing.Ast.Visitors; + +namespace ThinkSharp.FormulaParsing +{ + public class NodesToFormulaTextVisitor : INodeVisitor + { + public string Visit(FormulaNode node) + { + return node.ChildNode.Visit(this); + } + + public string Visit(BracketedNode node) => $"({node.ChildNode.Visit(this)})"; + + public string Visit(DecimalNode node) => node.Value.ToString("0.00", CultureInfo.InvariantCulture); + + public string Visit(VariableNode node) => node.Name; + + public string Visit(ConstantNode node) => node.Name; + + public string Visit(BinaryOperatorNode node) => $"{node.LeftNode.Visit(this)}{node.BinaryOperator.Symbol}{node.RightNode.Visit(this)}"; + + public string Visit(PowerNode node) => $"{node.BaseNode.Visit(this)}^{node.ExponentNode.Visit(this)}"; + + public string Visit(SignedNode node) => (node.Sign == Sign.Minus ? "-" : "") + node.Node.Visit(this); + + public string Visit(FunctionNode node) => $"{node.FunctionName}({string.Join(", ", node.Parameters.Select(p => p.Visit(this)))})"; + + public string Visit(IntegerNode node) => node.Value.ToString(); + } +} diff --git a/ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.Core.csproj b/ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.csproj similarity index 51% rename from ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.Core.csproj rename to ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.csproj index 12c1dd4..4648127 100644 --- a/ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.Core.csproj +++ b/ThinkSharp.FormulaParser.Test.Core/ThinkSharp.FormulaParser.Test.csproj @@ -1,25 +1,24 @@  - netcoreapp2.0 + net7.0 false + true ThinkSharp.FormulaParser.Test.Core - ThinkSharp.FormulaParsing.Test + ThinkSharp.FormulaParsing - - - + + + - - diff --git a/ThinkSharp.FormulaParser.Test.Net461/Properties/AssemblyInfo.cs b/ThinkSharp.FormulaParser.Test.Net461/Properties/AssemblyInfo.cs deleted file mode 100644 index 8eb43f5..0000000 --- a/ThinkSharp.FormulaParser.Test.Net461/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("ThinkSharp.FormulaParser.Test")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("ThinkSharp.FormulaParser")] -[assembly: AssemblyCopyright("Copyright © 2019 Jan-Niklas Schäfer")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -[assembly: ComVisible(false)] - -[assembly: Guid("3bc319a0-e6a2-4667-a7e8-8c283acda823")] - -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ThinkSharp.FormulaParser.Test.Net461/ThinkSharp.FormulaParser.Test.Net461.csproj b/ThinkSharp.FormulaParser.Test.Net461/ThinkSharp.FormulaParser.Test.Net461.csproj deleted file mode 100644 index 9cfbf5f..0000000 --- a/ThinkSharp.FormulaParser.Test.Net461/ThinkSharp.FormulaParser.Test.Net461.csproj +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - Debug - AnyCPU - {3BC319A0-E6A2-4667-A7E8-8C283ACDA823} - Library - Properties - ThinkSharp.FormulaParsing.Test - ThinkSharp.FormulaParser.Test - v4.6.1 - 512 - {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 15.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages - False - UnitTest - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Antlr4.Runtime.Standard.4.7.2\lib\net35\Antlr4.Runtime.Standard.dll - - - ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - - - ..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll - - - - - - - - - - - - - {c69728f7-cdc0-4fa2-b805-e0dd6f498e9f} - ThinkSharp.FormulaParser - - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Test.Net461/packages.config b/ThinkSharp.FormulaParser.Test.Net461/packages.config deleted file mode 100644 index b24600c..0000000 --- a/ThinkSharp.FormulaParser.Test.Net461/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Test/ThinkSharp.FluentFormulaParser.Test.projitems b/ThinkSharp.FormulaParser.Test/ThinkSharp.FluentFormulaParser.Test.projitems deleted file mode 100644 index 8f80a56..0000000 --- a/ThinkSharp.FormulaParser.Test/ThinkSharp.FluentFormulaParser.Test.projitems +++ /dev/null @@ -1,19 +0,0 @@ - - - - $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - true - bc2373ca-32d9-4224-a1bb-831e0dbf839a - - - ThinkSharp.FluentFormulaParser.Test - - - - - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Test/ThinkSharp.FormulaParser.Test.shproj b/ThinkSharp.FormulaParser.Test/ThinkSharp.FormulaParser.Test.shproj deleted file mode 100644 index 3982465..0000000 --- a/ThinkSharp.FormulaParser.Test/ThinkSharp.FormulaParser.Test.shproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - bc2373ca-32d9-4224-a1bb-831e0dbf839a - 14.0 - - - - - - - - diff --git a/ThinkSharp.FormulaParser.Wpf/App.config b/ThinkSharp.FormulaParser.Wpf/App.config deleted file mode 100644 index 56efbc7..0000000 --- a/ThinkSharp.FormulaParser.Wpf/App.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Wpf/App.xaml b/ThinkSharp.FormulaParser.Wpf/App.xaml deleted file mode 100644 index 5c8a139..0000000 --- a/ThinkSharp.FormulaParser.Wpf/App.xaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - diff --git a/ThinkSharp.FormulaParser.Wpf/App.xaml.cs b/ThinkSharp.FormulaParser.Wpf/App.xaml.cs deleted file mode 100644 index 849b896..0000000 --- a/ThinkSharp.FormulaParser.Wpf/App.xaml.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Configuration; -using System.Data; -using System.Linq; -using System.Threading.Tasks; -using System.Windows; - -namespace FormulaParser.Wpf -{ - /// - /// Interaction logic for App.xaml - /// - public partial class App : Application - { - } -} diff --git a/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml b/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml deleted file mode 100644 index a936b92..0000000 --- a/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - diff --git a/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml.cs b/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml.cs deleted file mode 100644 index 526191a..0000000 --- a/ThinkSharp.FormulaParser.Wpf/MainWindow.xaml.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Navigation; -using System.Windows.Shapes; -using ThinkSharp.FormulaParsing; -using ThinkSharp.FormulaParsing.Ast.Visitors; - -namespace FormulaParser.Wpf -{ - using ThinkSharp.FormulaParsing.Ast.Nodes; - using FormulaParser = ThinkSharp.FormulaParsing.FormulaParser; - - /// - /// Interaction logic for MainWindow.xaml - /// - public partial class MainWindow : Window - { - private readonly IFormulaParser parser = FormulaParser - .CreateBuilder() - .ConfigureParsingBehavior(parsingBehavior => - { - parsingBehavior.DisableVariableNameValidation(); - }) - .Build(); - public MainWindow() - { - InitializeComponent(); - } - - private void Input_TextChanged(object sender, TextChangedEventArgs e) - { - var result = parser.Parse(Input.Text); - - if (!result.Success) - { - this.Result.Text = string.Join(Environment.NewLine, result.Error); - this.Result.Foreground = Brushes.Red; - } - else - { - var variableNames = result.Value.Visit(new CollectVariableNamesVisitor()); - this.Result.Text = "Variables: " + string.Join("|", variableNames); - this.Result.Foreground = Brushes.Black; - var evalResult = parser.Evaluate(result.Value); - if (!evalResult.Success) - { - this.ResultValue.Text = string.Join(Environment.NewLine, evalResult.Error); - this.ResultValue.Foreground = Brushes.Red; - } - else - { - this.ResultValue.Text = evalResult.Value.ToString(); - this.ResultValue.Foreground = Brushes.Black; - } - } - } - - private class CollectVariableNamesVisitor : NodeVisitor> - { - private readonly List variableNames = new List(); - - public override List Visit(VariableNode node) - { - variableNames.Add(node.Name); - return variableNames; - } - - protected override List DefaultResult() => variableNames; - } - } -} diff --git a/ThinkSharp.FormulaParser.Wpf/Properties/AssemblyInfo.cs b/ThinkSharp.FormulaParser.Wpf/Properties/AssemblyInfo.cs deleted file mode 100644 index 3116d09..0000000 --- a/ThinkSharp.FormulaParser.Wpf/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Reflection; -using System.Resources; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Windows; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("FormulaParser.Wpf")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("FormulaParser.Wpf")] -[assembly: AssemblyCopyright("Copyright © 2019")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -//In order to begin building localizable applications, set -//CultureYouAreCodingWith in your .csproj file -//inside a . For example, if you are using US english -//in your source files, set the to en-US. Then uncomment -//the NeutralResourceLanguage attribute below. Update the "en-US" in -//the line below to match the UICulture setting in the project file. - -//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] - - -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located - //(used if a resource is not found in the page, - // or application resource dictionaries) - ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located - //(used if a resource is not found in the page, - // app, or any theme specific resource dictionaries) -)] - - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/ThinkSharp.FormulaParser.Wpf/Properties/Resources.Designer.cs b/ThinkSharp.FormulaParser.Wpf/Properties/Resources.Designer.cs deleted file mode 100644 index ba2b561..0000000 --- a/ThinkSharp.FormulaParser.Wpf/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ThinkSharp.FormulaParsing.Wpf.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ThinkSharp.FormulaParsing.Wpf.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/ThinkSharp.FormulaParser.Wpf/Properties/Resources.resx b/ThinkSharp.FormulaParser.Wpf/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/ThinkSharp.FormulaParser.Wpf/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Wpf/Properties/Settings.Designer.cs b/ThinkSharp.FormulaParser.Wpf/Properties/Settings.Designer.cs deleted file mode 100644 index b760d95..0000000 --- a/ThinkSharp.FormulaParser.Wpf/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace ThinkSharp.FormulaParsing.Wpf.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/ThinkSharp.FormulaParser.Wpf/Properties/Settings.settings b/ThinkSharp.FormulaParser.Wpf/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/ThinkSharp.FormulaParser.Wpf/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Wpf/ThinkSharp.FormulaParser.Wpf.csproj b/ThinkSharp.FormulaParser.Wpf/ThinkSharp.FormulaParser.Wpf.csproj deleted file mode 100644 index de3fffd..0000000 --- a/ThinkSharp.FormulaParser.Wpf/ThinkSharp.FormulaParser.Wpf.csproj +++ /dev/null @@ -1,105 +0,0 @@ - - - - - Debug - AnyCPU - {18AF0B56-CE95-4740-A5F7-91420E12E7A3} - WinExe - ThinkSharp.FluentFormulaParser.Wpf - ThinkSharp.FluentFormulaParser.Wpf - v4.7.2 - 512 - {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} - 4 - true - true - - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Antlr4.Runtime.Standard.4.7.2\lib\net35\Antlr4.Runtime.Standard.dll - - - - - - - - - - - 4.0 - - - ..\packages\ThinkSharp.FormulaParser.0.9.0\lib\netstandard2.0\ThinkSharp.FormulaParser.dll - - - - - - - - MSBuild:Compile - Designer - - - MSBuild:Compile - Designer - - - App.xaml - Code - - - MainWindow.xaml - Code - - - - - Code - - - True - True - Resources.resx - - - True - Settings.settings - True - - - ResXFileCodeGenerator - Resources.Designer.cs - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.Wpf/packages.config b/ThinkSharp.FormulaParser.Wpf/packages.config deleted file mode 100644 index 04c82cc..0000000 --- a/ThinkSharp.FormulaParser.Wpf/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/ThinkSharp.FormulaParser.sln b/ThinkSharp.FormulaParser.sln index 7982aa3..17b0604 100644 --- a/ThinkSharp.FormulaParser.sln +++ b/ThinkSharp.FormulaParser.sln @@ -3,30 +3,16 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.28922.388 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThinkSharp.FormulaParser.Wpf", "ThinkSharp.FormulaParser.Wpf\ThinkSharp.FormulaParser.Wpf.csproj", "{18AF0B56-CE95-4740-A5F7-91420E12E7A3}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThinkSharp.FormulaParser", "ThinkSharp.FormulaParser\ThinkSharp.FormulaParser.csproj", "{C69728F7-CDC0-4FA2-B805-E0DD6F498E9F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThinkSharp.FormulaParser.Test.Core", "ThinkSharp.FormulaParser.Test.Core\ThinkSharp.FormulaParser.Test.Core.csproj", "{1CAA5403-6EBB-4885-A51A-10533E673890}" -EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "ThinkSharp.FormulaParser.Test", "ThinkSharp.FormulaParser.Test\ThinkSharp.FormulaParser.Test.shproj", "{BC2373CA-32D9-4224-A1BB-831E0DBF839A}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThinkSharp.FormulaParser.Test.Net461", "ThinkSharp.FormulaParser.Test.Net461\ThinkSharp.FormulaParser.Test.Net461.csproj", "{3BC319A0-E6A2-4667-A7E8-8C283ACDA823}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThinkSharp.FormulaParser.Test", "ThinkSharp.FormulaParser.Test.Core\ThinkSharp.FormulaParser.Test.csproj", "{1CAA5403-6EBB-4885-A51A-10533E673890}" EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - ThinkSharp.FormulaParser.Test\ThinkSharp.FluentFormulaParser.Test.projitems*{3bc319a0-e6a2-4667-a7e8-8c283acda823}*SharedItemsImports = 4 - ThinkSharp.FormulaParser.Test\ThinkSharp.FluentFormulaParser.Test.projitems*{bc2373ca-32d9-4224-a1bb-831e0dbf839a}*SharedItemsImports = 13 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {18AF0B56-CE95-4740-A5F7-91420E12E7A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {18AF0B56-CE95-4740-A5F7-91420E12E7A3}.Debug|Any CPU.Build.0 = Debug|Any CPU - {18AF0B56-CE95-4740-A5F7-91420E12E7A3}.Release|Any CPU.ActiveCfg = Release|Any CPU - {18AF0B56-CE95-4740-A5F7-91420E12E7A3}.Release|Any CPU.Build.0 = Release|Any CPU {C69728F7-CDC0-4FA2-B805-E0DD6F498E9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C69728F7-CDC0-4FA2-B805-E0DD6F498E9F}.Debug|Any CPU.Build.0 = Debug|Any CPU {C69728F7-CDC0-4FA2-B805-E0DD6F498E9F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -35,10 +21,6 @@ Global {1CAA5403-6EBB-4885-A51A-10533E673890}.Debug|Any CPU.Build.0 = Debug|Any CPU {1CAA5403-6EBB-4885-A51A-10533E673890}.Release|Any CPU.ActiveCfg = Release|Any CPU {1CAA5403-6EBB-4885-A51A-10533E673890}.Release|Any CPU.Build.0 = Release|Any CPU - {3BC319A0-E6A2-4667-A7E8-8C283ACDA823}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3BC319A0-E6A2-4667-A7E8-8C283ACDA823}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3BC319A0-E6A2-4667-A7E8-8C283ACDA823}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3BC319A0-E6A2-4667-A7E8-8C283ACDA823}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/ThinkSharp.FormulaParser/ANTLR/AntlrToAstNodesGrammerTreeVisitor.cs b/ThinkSharp.FormulaParser/ANTLR/AntlrToAstNodesGrammerTreeVisitor.cs index 5d82626..381423f 100644 --- a/ThinkSharp.FormulaParser/ANTLR/AntlrToAstNodesGrammerTreeVisitor.cs +++ b/ThinkSharp.FormulaParser/ANTLR/AntlrToAstNodesGrammerTreeVisitor.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using Antlr4.Runtime.Misc; using ThinkSharp.FormulaParsing.Ast.Nodes; @@ -20,7 +21,7 @@ public override Node VisitFormula([NotNull] FormulaGrammerParser.FormulaContext { var node = base.Visit(context.expression()); - return new FormulaNode(node, formulaText); + return new FormulaNode(node); } public override Node VisitExpression([NotNull] FormulaGrammerParser.ExpressionContext context) @@ -112,15 +113,83 @@ public override Node VisitAtom([NotNull] FormulaGrammerParser.AtomContext contex return base.VisitAtom(context); } - public override Node VisitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context) + //public override Node VisitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context) + //{ + // //if (this.configuration.IsScientificNotationSupportDisabled) + // //{ + // // ParsingException.ThrowInvalidTokenException(context.E().Symbol); + // //} + + // var scientificNumber = context.SCIENTIFIC_NUMBER().Symbol.Text; + // //var baseNumber = this.Visit(); + // //var exponentNumber = this.Visit(context.number(1)); + // //var isNegativ = context.MINUS() != null; + + // //if (isNegativ) + // //{ + // // exponentNumber = new SignedNode(Sign.Minus, exponentNumber); + // //} + + // //var pow = new PowerNode(new IntegerNode("10", 10), exponentNumber); + // //return new BinaryOperatorNode(BinaryOperator.BySymbol("*"), baseNumber, exponentNumber); + // return new DecimalNode(scientificNumber, double.Parse(scientificNumber.Parse)); + //} + + public override Node VisitPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context) { - if (this.configuration.IsScientificNotationSupportDisabled) + var token = context.PREFIX_INT_NUMBER().Symbol.Text; + return new IntegerNode(NumberFormat.Dec, long.Parse(token.Substring(2))); + } + + public override Node VisitPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context) + { + if (this.configuration.IsBinaryNumberNotationSupportDisabled) { - ParsingException.ThrowInvalidTokenException(context.SCIENTIFIC_NUMBER().Symbol); + ParsingException.ThrowInvalidTokenException(context.PREFIX_BIN_NUMBER().Symbol); } - var scientificNumber = context.SCIENTIFIC_NUMBER().Symbol.Text; - return new NumberNode(double.Parse(scientificNumber)); + var token = context.PREFIX_BIN_NUMBER().Symbol.Text; + return new IntegerNode(NumberFormat.Bin, Convert.ToInt64(token.Substring(2), 2)); + } + + public override Node VisitPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context) + { + var token = context.PREFIX_DEC_NUMBER().Symbol.Text; + return new DecimalNode(double.Parse(token.Substring(2), CultureInfo.InvariantCulture)); + } + + public override Node VisitPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context) + { + if (this.configuration.IsHexadecimalNumberNotationSupportDisabled) + { + ParsingException.ThrowInvalidTokenException(context.PREFIX_HEX_NUMBER().Symbol); + } + + var token = context.PREFIX_HEX_NUMBER().Symbol.Text; + return new IntegerNode(NumberFormat.Hex, Convert.ToInt64(token.Substring(2), 16)); + } + + public override Node VisitPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context) + { + if (this.configuration.IsOctalNumberNotationSupportDisabled) + { + ParsingException.ThrowInvalidTokenException(context.PREFIX_OCT_NUMBER().Symbol); + } + + var token = context.PREFIX_OCT_NUMBER().Symbol.Text; + return new IntegerNode(NumberFormat.Oct, Convert.ToInt64(token.Substring(2), 8)); + } + + public override Node VisitDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context) + { + var token = context.DECIMAL_NUMBER().Symbol.Text; + return new DecimalNode(double.Parse(token, CultureInfo.InvariantCulture)); + } + + public override Node VisitIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context) + { + var token = context.INTEGER_NUMBER().Symbol.Text; + return new IntegerNode(NumberFormat.Dec, long.Parse(token, CultureInfo.InvariantCulture)); } public override Node VisitVariable([NotNull] FormulaGrammerParser.VariableContext context) @@ -166,9 +235,17 @@ public override Node VisitFunc([NotNull] FormulaGrammerParser.FuncContext contex parameters.Add(this.Visit(exp)); } - if (!this.configuration.IsFunctionNameValidationDisabled && !this.configuration.HasFunction(functionName, parameters.Count)) + if (!this.configuration.IsFunctionNameValidationDisabled) { - ParsingException.ThrowUnknownFunctionException(functionNameToken); + if (!this.configuration.HasFunction(functionName)) + { + ParsingException.ThrowUnknownFunctionException(functionNameToken); + } + + if (!this.configuration.HasFunction(functionName, parameters.Count)) + { + ParsingException.ThrowFunctionArgumentCountDoesNotExistException(functionNameToken, parameters.Count); + } } return new FunctionNode(functionName, parameters.ToArray()); diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.g4 b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.g4 index b21d3ba..7c59ad2 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.g4 +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.g4 @@ -19,18 +19,28 @@ powExpression signedAtom : PLUS atom # PlusAtom | MINUS atom # NegativeAtom - | func # Function | atom # UnsignedAtom ; atom - : scientific + : number + | prefixedNumber | variable | LPAREN expression RPAREN + | func ; -scientific - : SCIENTIFIC_NUMBER # ScientificNumber +number + : DECIMAL_NUMBER # DecimalNumber + | INTEGER_NUMBER # IntgerNumber + ; + +prefixedNumber + : PREFIX_DEC_NUMBER # PrefixedDecNumber + | PREFIX_INT_NUMBER # PrefixedIntNumber + | PREFIX_BIN_NUMBER # PrefixedBinNumber + | PREFIX_OCT_NUMBER # PrefixedOctNumber + | PREFIX_HEX_NUMBER # PrefixedHexNumber ; func @@ -86,44 +96,94 @@ POW : '^' ; - IDENTIFIER : VALID_ID_START VALID_ID_CHAR* ; -SCIENTIFIC_NUMBER - : NUMBER ((E1 | E2) SIGN? NUMBER)? +DECIMAL_NUMBER + : NUMBER_DEC ; -fragment VALID_ID_START - : ('a' .. 'z') | ('A' .. 'Z') | '_' +INTEGER_NUMBER + : NUMBER_INT + ; + +PREFIX_BIN_NUMBER + : PREFIX_BIN NUMBER_BIN + ; + +PREFIX_HEX_NUMBER + : PREFIX_HEX NUMBER_HEX ; +PREFIX_INT_NUMBER + : PREFIX_INT NUMBER_INT + ; + +PREFIX_OCT_NUMBER + : PREFIX_OCT NUMBER_OCT + ; + +PREFIX_DEC_NUMBER + : PREFIX_DEC (NUMBER_DEC | NUMBER_INT) + ; +fragment VALID_ID_START + : ('a' .. 'z') | ('A' .. 'Z') | '_' | '$' + ; + fragment VALID_ID_CHAR : VALID_ID_START | ('0' .. '9') ; -fragment NUMBER - : ('0' .. '9') + ('.' ('0' .. '9') +)? +fragment NUMBER_INT + : ('0' .. '9') + + ; + +fragment NUMBER_OCT + : ('0' .. '7') + ; +fragment NUMBER_DEC + : ('0' .. '9') * ('.' ('0' .. '9') +) + ; -fragment E1 - : 'E' +fragment NUMBER_BIN + : ('0' | '1')+ ; +fragment NUMBER_HEX + : (('0' .. '9') | ('A' .. 'F') | ('a' .. 'f')) + + ; -fragment E2 - : 'e' +fragment PREFIX_DEC + : '0' ('D' | 'd') ; +fragment PREFIX_INT + : '0' ('I' | 'i') + ; -fragment SIGN - : ('+' | '-') +fragment PREFIX_OCT + : '0' ('o' | 'O') + ; + +fragment PREFIX_BIN + : '0' ('B' | 'b') + ; + +fragment PREFIX_HEX + : '0' ('X' | 'x') ; +fragment E + : ('E' | 'e') + ; +fragment SIGN + : ('+' | '-') + ; + WS : [ \r\n\t] + -> skip ; \ No newline at end of file diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.interp b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.interp index cfc604b..4c6776b 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.interp +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.interp @@ -12,6 +12,12 @@ null null null null +null +null +null +null +null +null token symbolic names: null @@ -25,7 +31,13 @@ COMMA POINT POW IDENTIFIER -SCIENTIFIC_NUMBER +DECIMAL_NUMBER +INTEGER_NUMBER +PREFIX_BIN_NUMBER +PREFIX_HEX_NUMBER +PREFIX_INT_NUMBER +PREFIX_OCT_NUMBER +PREFIX_DEC_NUMBER WS rule names: @@ -35,10 +47,11 @@ multiplyingExpression powExpression signedAtom atom -scientific +number +prefixedNumber func variable atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 14, 82, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 7, 3, 27, 10, 3, 12, 3, 14, 3, 30, 11, 3, 3, 4, 3, 4, 3, 4, 7, 4, 35, 10, 4, 12, 4, 14, 4, 38, 11, 4, 3, 5, 3, 5, 3, 5, 7, 5, 43, 10, 5, 12, 5, 14, 5, 46, 11, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 54, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 62, 10, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 7, 9, 71, 10, 9, 12, 9, 14, 9, 74, 11, 9, 5, 9, 76, 10, 9, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 2, 2, 11, 2, 4, 6, 8, 10, 12, 14, 16, 18, 2, 4, 3, 2, 5, 6, 3, 2, 7, 8, 2, 82, 2, 20, 3, 2, 2, 2, 4, 23, 3, 2, 2, 2, 6, 31, 3, 2, 2, 2, 8, 39, 3, 2, 2, 2, 10, 53, 3, 2, 2, 2, 12, 61, 3, 2, 2, 2, 14, 63, 3, 2, 2, 2, 16, 65, 3, 2, 2, 2, 18, 79, 3, 2, 2, 2, 20, 21, 5, 4, 3, 2, 21, 22, 7, 2, 2, 3, 22, 3, 3, 2, 2, 2, 23, 28, 5, 6, 4, 2, 24, 25, 9, 2, 2, 2, 25, 27, 5, 6, 4, 2, 26, 24, 3, 2, 2, 2, 27, 30, 3, 2, 2, 2, 28, 26, 3, 2, 2, 2, 28, 29, 3, 2, 2, 2, 29, 5, 3, 2, 2, 2, 30, 28, 3, 2, 2, 2, 31, 36, 5, 8, 5, 2, 32, 33, 9, 3, 2, 2, 33, 35, 5, 8, 5, 2, 34, 32, 3, 2, 2, 2, 35, 38, 3, 2, 2, 2, 36, 34, 3, 2, 2, 2, 36, 37, 3, 2, 2, 2, 37, 7, 3, 2, 2, 2, 38, 36, 3, 2, 2, 2, 39, 44, 5, 10, 6, 2, 40, 41, 7, 11, 2, 2, 41, 43, 5, 10, 6, 2, 42, 40, 3, 2, 2, 2, 43, 46, 3, 2, 2, 2, 44, 42, 3, 2, 2, 2, 44, 45, 3, 2, 2, 2, 45, 9, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 47, 48, 7, 5, 2, 2, 48, 54, 5, 12, 7, 2, 49, 50, 7, 6, 2, 2, 50, 54, 5, 12, 7, 2, 51, 54, 5, 16, 9, 2, 52, 54, 5, 12, 7, 2, 53, 47, 3, 2, 2, 2, 53, 49, 3, 2, 2, 2, 53, 51, 3, 2, 2, 2, 53, 52, 3, 2, 2, 2, 54, 11, 3, 2, 2, 2, 55, 62, 5, 14, 8, 2, 56, 62, 5, 18, 10, 2, 57, 58, 7, 3, 2, 2, 58, 59, 5, 4, 3, 2, 59, 60, 7, 4, 2, 2, 60, 62, 3, 2, 2, 2, 61, 55, 3, 2, 2, 2, 61, 56, 3, 2, 2, 2, 61, 57, 3, 2, 2, 2, 62, 13, 3, 2, 2, 2, 63, 64, 7, 13, 2, 2, 64, 15, 3, 2, 2, 2, 65, 66, 7, 12, 2, 2, 66, 75, 7, 3, 2, 2, 67, 72, 5, 4, 3, 2, 68, 69, 7, 9, 2, 2, 69, 71, 5, 4, 3, 2, 70, 68, 3, 2, 2, 2, 71, 74, 3, 2, 2, 2, 72, 70, 3, 2, 2, 2, 72, 73, 3, 2, 2, 2, 73, 76, 3, 2, 2, 2, 74, 72, 3, 2, 2, 2, 75, 67, 3, 2, 2, 2, 75, 76, 3, 2, 2, 2, 76, 77, 3, 2, 2, 2, 77, 78, 7, 4, 2, 2, 78, 17, 3, 2, 2, 2, 79, 80, 7, 12, 2, 2, 80, 19, 3, 2, 2, 2, 9, 28, 36, 44, 53, 61, 72, 75] \ No newline at end of file +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 20, 94, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 7, 3, 29, 10, 3, 12, 3, 14, 3, 32, 11, 3, 3, 4, 3, 4, 3, 4, 7, 4, 37, 10, 4, 12, 4, 14, 4, 40, 11, 4, 3, 5, 3, 5, 3, 5, 7, 5, 45, 10, 5, 12, 5, 14, 5, 48, 11, 5, 3, 6, 3, 6, 3, 6, 3, 6, 3, 6, 5, 6, 55, 10, 6, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 5, 7, 65, 10, 7, 3, 8, 3, 8, 5, 8, 69, 10, 8, 3, 9, 3, 9, 3, 9, 3, 9, 3, 9, 5, 9, 76, 10, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 7, 10, 83, 10, 10, 12, 10, 14, 10, 86, 11, 10, 5, 10, 88, 10, 10, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 2, 2, 12, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 2, 4, 3, 2, 5, 6, 3, 2, 7, 8, 2, 99, 2, 22, 3, 2, 2, 2, 4, 25, 3, 2, 2, 2, 6, 33, 3, 2, 2, 2, 8, 41, 3, 2, 2, 2, 10, 54, 3, 2, 2, 2, 12, 64, 3, 2, 2, 2, 14, 68, 3, 2, 2, 2, 16, 75, 3, 2, 2, 2, 18, 77, 3, 2, 2, 2, 20, 91, 3, 2, 2, 2, 22, 23, 5, 4, 3, 2, 23, 24, 7, 2, 2, 3, 24, 3, 3, 2, 2, 2, 25, 30, 5, 6, 4, 2, 26, 27, 9, 2, 2, 2, 27, 29, 5, 6, 4, 2, 28, 26, 3, 2, 2, 2, 29, 32, 3, 2, 2, 2, 30, 28, 3, 2, 2, 2, 30, 31, 3, 2, 2, 2, 31, 5, 3, 2, 2, 2, 32, 30, 3, 2, 2, 2, 33, 38, 5, 8, 5, 2, 34, 35, 9, 3, 2, 2, 35, 37, 5, 8, 5, 2, 36, 34, 3, 2, 2, 2, 37, 40, 3, 2, 2, 2, 38, 36, 3, 2, 2, 2, 38, 39, 3, 2, 2, 2, 39, 7, 3, 2, 2, 2, 40, 38, 3, 2, 2, 2, 41, 46, 5, 10, 6, 2, 42, 43, 7, 11, 2, 2, 43, 45, 5, 10, 6, 2, 44, 42, 3, 2, 2, 2, 45, 48, 3, 2, 2, 2, 46, 44, 3, 2, 2, 2, 46, 47, 3, 2, 2, 2, 47, 9, 3, 2, 2, 2, 48, 46, 3, 2, 2, 2, 49, 50, 7, 5, 2, 2, 50, 55, 5, 12, 7, 2, 51, 52, 7, 6, 2, 2, 52, 55, 5, 12, 7, 2, 53, 55, 5, 12, 7, 2, 54, 49, 3, 2, 2, 2, 54, 51, 3, 2, 2, 2, 54, 53, 3, 2, 2, 2, 55, 11, 3, 2, 2, 2, 56, 65, 5, 14, 8, 2, 57, 65, 5, 16, 9, 2, 58, 65, 5, 20, 11, 2, 59, 60, 7, 3, 2, 2, 60, 61, 5, 4, 3, 2, 61, 62, 7, 4, 2, 2, 62, 65, 3, 2, 2, 2, 63, 65, 5, 18, 10, 2, 64, 56, 3, 2, 2, 2, 64, 57, 3, 2, 2, 2, 64, 58, 3, 2, 2, 2, 64, 59, 3, 2, 2, 2, 64, 63, 3, 2, 2, 2, 65, 13, 3, 2, 2, 2, 66, 69, 7, 13, 2, 2, 67, 69, 7, 14, 2, 2, 68, 66, 3, 2, 2, 2, 68, 67, 3, 2, 2, 2, 69, 15, 3, 2, 2, 2, 70, 76, 7, 19, 2, 2, 71, 76, 7, 17, 2, 2, 72, 76, 7, 15, 2, 2, 73, 76, 7, 18, 2, 2, 74, 76, 7, 16, 2, 2, 75, 70, 3, 2, 2, 2, 75, 71, 3, 2, 2, 2, 75, 72, 3, 2, 2, 2, 75, 73, 3, 2, 2, 2, 75, 74, 3, 2, 2, 2, 76, 17, 3, 2, 2, 2, 77, 78, 7, 12, 2, 2, 78, 87, 7, 3, 2, 2, 79, 84, 5, 4, 3, 2, 80, 81, 7, 9, 2, 2, 81, 83, 5, 4, 3, 2, 82, 80, 3, 2, 2, 2, 83, 86, 3, 2, 2, 2, 84, 82, 3, 2, 2, 2, 84, 85, 3, 2, 2, 2, 85, 88, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 87, 79, 3, 2, 2, 2, 87, 88, 3, 2, 2, 2, 88, 89, 3, 2, 2, 2, 89, 90, 7, 4, 2, 2, 90, 19, 3, 2, 2, 2, 91, 92, 7, 12, 2, 2, 92, 21, 3, 2, 2, 2, 11, 30, 38, 46, 54, 64, 68, 75, 84, 87] \ No newline at end of file diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.tokens b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.tokens index 83a628c..a254e9e 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.tokens +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammer.tokens @@ -8,8 +8,14 @@ COMMA=7 POINT=8 POW=9 IDENTIFIER=10 -SCIENTIFIC_NUMBER=11 -WS=12 +DECIMAL_NUMBER=11 +INTEGER_NUMBER=12 +PREFIX_BIN_NUMBER=13 +PREFIX_HEX_NUMBER=14 +PREFIX_INT_NUMBER=15 +PREFIX_OCT_NUMBER=16 +PREFIX_DEC_NUMBER=17 +WS=18 '('=1 ')'=2 '+'=3 diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseListener.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseListener.cs index bce36d1..9791f70 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseListener.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseListener.cs @@ -111,20 +111,6 @@ public virtual void EnterNegativeAtom([NotNull] FormulaGrammerParser.NegativeAto /// The parse tree. public virtual void ExitNegativeAtom([NotNull] FormulaGrammerParser.NegativeAtomContext context) { } /// - /// Enter a parse tree produced by the Function - /// labeled alternative in . - /// The default implementation does nothing. - /// - /// The parse tree. - public virtual void EnterFunction([NotNull] FormulaGrammerParser.FunctionContext context) { } - /// - /// Exit a parse tree produced by the Function - /// labeled alternative in . - /// The default implementation does nothing. - /// - /// The parse tree. - public virtual void ExitFunction([NotNull] FormulaGrammerParser.FunctionContext context) { } - /// /// Enter a parse tree produced by the UnsignedAtom /// labeled alternative in . /// The default implementation does nothing. @@ -151,19 +137,103 @@ public virtual void EnterAtom([NotNull] FormulaGrammerParser.AtomContext context /// The parse tree. public virtual void ExitAtom([NotNull] FormulaGrammerParser.AtomContext context) { } /// - /// Enter a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Enter a parse tree produced by the DecimalNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context) { } + /// + /// Exit a parse tree produced by the DecimalNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context) { } + /// + /// Enter a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context) { } + /// + /// Exit a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context) { } + /// + /// Enter a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context) { } + /// + /// Exit a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context) { } + /// + /// Enter a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context) { } + /// + /// Exit a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context) { } + /// + /// Enter a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context) { } + /// + /// Exit a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context) { } + /// + /// Enter a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void EnterPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context) { } + /// + /// Exit a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// The default implementation does nothing. + /// + /// The parse tree. + public virtual void ExitPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context) { } + /// + /// Enter a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// The default implementation does nothing. /// /// The parse tree. - public virtual void EnterScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context) { } + public virtual void EnterPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context) { } /// - /// Exit a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Exit a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// The default implementation does nothing. /// /// The parse tree. - public virtual void ExitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context) { } + public virtual void ExitPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context) { } /// /// Enter a parse tree produced by . /// The default implementation does nothing. diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseVisitor.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseVisitor.cs index 70a9227..afff3da 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseVisitor.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerBaseVisitor.cs @@ -96,7 +96,7 @@ public partial class FormulaGrammerBaseVisitor : AbstractParseTreeVisito /// The visitor result. public virtual Result VisitNegativeAtom([NotNull] FormulaGrammerParser.NegativeAtomContext context) { return VisitChildren(context); } /// - /// Visit a parse tree produced by the Function + /// Visit a parse tree produced by the UnsignedAtom /// labeled alternative in . /// /// The default implementation returns the result of calling @@ -105,10 +105,9 @@ public partial class FormulaGrammerBaseVisitor : AbstractParseTreeVisito /// /// The parse tree. /// The visitor result. - public virtual Result VisitFunction([NotNull] FormulaGrammerParser.FunctionContext context) { return VisitChildren(context); } + public virtual Result VisitUnsignedAtom([NotNull] FormulaGrammerParser.UnsignedAtomContext context) { return VisitChildren(context); } /// - /// Visit a parse tree produced by the UnsignedAtom - /// labeled alternative in . + /// Visit a parse tree produced by . /// /// The default implementation returns the result of calling /// on . @@ -116,9 +115,10 @@ public partial class FormulaGrammerBaseVisitor : AbstractParseTreeVisito /// /// The parse tree. /// The visitor result. - public virtual Result VisitUnsignedAtom([NotNull] FormulaGrammerParser.UnsignedAtomContext context) { return VisitChildren(context); } + public virtual Result VisitAtom([NotNull] FormulaGrammerParser.AtomContext context) { return VisitChildren(context); } /// - /// Visit a parse tree produced by . + /// Visit a parse tree produced by the DecimalNumber + /// labeled alternative in . /// /// The default implementation returns the result of calling /// on . @@ -126,10 +126,65 @@ public partial class FormulaGrammerBaseVisitor : AbstractParseTreeVisito /// /// The parse tree. /// The visitor result. - public virtual Result VisitAtom([NotNull] FormulaGrammerParser.AtomContext context) { return VisitChildren(context); } + public virtual Result VisitDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context) { return VisitChildren(context); } + /// + /// Visit a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context) { return VisitChildren(context); } + /// + /// Visit a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context) { return VisitChildren(context); } + /// + /// Visit a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context) { return VisitChildren(context); } + /// + /// Visit a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context) { return VisitChildren(context); } + /// + /// Visit a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// + /// The default implementation returns the result of calling + /// on . + /// + /// + /// The parse tree. + /// The visitor result. + public virtual Result VisitPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context) { return VisitChildren(context); } /// - /// Visit a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Visit a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// /// The default implementation returns the result of calling /// on . @@ -137,7 +192,7 @@ public partial class FormulaGrammerBaseVisitor : AbstractParseTreeVisito /// /// The parse tree. /// The visitor result. - public virtual Result VisitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context) { return VisitChildren(context); } + public virtual Result VisitPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context) { return VisitChildren(context); } /// /// Visit a parse tree produced by . /// diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.cs index 735a70b..eef63e6 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.cs @@ -34,7 +34,9 @@ public partial class FormulaGrammerLexer : Lexer { protected static PredictionContextCache sharedContextCache = new PredictionContextCache(); public const int LPAREN=1, RPAREN=2, PLUS=3, MINUS=4, TIMES=5, DIV=6, COMMA=7, POINT=8, - POW=9, IDENTIFIER=10, SCIENTIFIC_NUMBER=11, WS=12; + POW=9, IDENTIFIER=10, DECIMAL_NUMBER=11, INTEGER_NUMBER=12, PREFIX_BIN_NUMBER=13, + PREFIX_HEX_NUMBER=14, PREFIX_INT_NUMBER=15, PREFIX_OCT_NUMBER=16, PREFIX_DEC_NUMBER=17, + WS=18; public static string[] channelNames = { "DEFAULT_TOKEN_CHANNEL", "HIDDEN" }; @@ -45,8 +47,11 @@ public const int public static readonly string[] ruleNames = { "LPAREN", "RPAREN", "PLUS", "MINUS", "TIMES", "DIV", "COMMA", "POINT", - "POW", "IDENTIFIER", "SCIENTIFIC_NUMBER", "VALID_ID_START", "VALID_ID_CHAR", - "NUMBER", "E1", "E2", "SIGN", "WS" + "POW", "IDENTIFIER", "DECIMAL_NUMBER", "INTEGER_NUMBER", "PREFIX_BIN_NUMBER", + "PREFIX_HEX_NUMBER", "PREFIX_INT_NUMBER", "PREFIX_OCT_NUMBER", "PREFIX_DEC_NUMBER", + "VALID_ID_START", "VALID_ID_CHAR", "NUMBER_INT", "NUMBER_OCT", "NUMBER_DEC", + "NUMBER_BIN", "NUMBER_HEX", "PREFIX_DEC", "PREFIX_INT", "PREFIX_OCT", + "PREFIX_BIN", "PREFIX_HEX", "E", "SIGN", "WS" }; @@ -64,7 +69,9 @@ public FormulaGrammerLexer(ICharStream input, TextWriter output, TextWriter erro }; private static readonly string[] _SymbolicNames = { null, "LPAREN", "RPAREN", "PLUS", "MINUS", "TIMES", "DIV", "COMMA", "POINT", - "POW", "IDENTIFIER", "SCIENTIFIC_NUMBER", "WS" + "POW", "IDENTIFIER", "DECIMAL_NUMBER", "INTEGER_NUMBER", "PREFIX_BIN_NUMBER", + "PREFIX_HEX_NUMBER", "PREFIX_INT_NUMBER", "PREFIX_OCT_NUMBER", "PREFIX_DEC_NUMBER", + "WS" }; public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); @@ -95,94 +102,153 @@ static FormulaGrammerLexer() { } private static char[] _serializedATN = { '\x3', '\x608B', '\xA72A', '\x8133', '\xB9ED', '\x417C', '\x3BE7', '\x7786', - '\x5964', '\x2', '\xE', 'm', '\b', '\x1', '\x4', '\x2', '\t', '\x2', '\x4', - '\x3', '\t', '\x3', '\x4', '\x4', '\t', '\x4', '\x4', '\x5', '\t', '\x5', - '\x4', '\x6', '\t', '\x6', '\x4', '\a', '\t', '\a', '\x4', '\b', '\t', - '\b', '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x4', '\v', '\t', - '\v', '\x4', '\f', '\t', '\f', '\x4', '\r', '\t', '\r', '\x4', '\xE', + '\x5964', '\x2', '\x14', '\xB2', '\b', '\x1', '\x4', '\x2', '\t', '\x2', + '\x4', '\x3', '\t', '\x3', '\x4', '\x4', '\t', '\x4', '\x4', '\x5', '\t', + '\x5', '\x4', '\x6', '\t', '\x6', '\x4', '\a', '\t', '\a', '\x4', '\b', + '\t', '\b', '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x4', '\v', + '\t', '\v', '\x4', '\f', '\t', '\f', '\x4', '\r', '\t', '\r', '\x4', '\xE', '\t', '\xE', '\x4', '\xF', '\t', '\xF', '\x4', '\x10', '\t', '\x10', '\x4', '\x11', '\t', '\x11', '\x4', '\x12', '\t', '\x12', '\x4', '\x13', '\t', - '\x13', '\x3', '\x2', '\x3', '\x2', '\x3', '\x3', '\x3', '\x3', '\x3', - '\x4', '\x3', '\x4', '\x3', '\x5', '\x3', '\x5', '\x3', '\x6', '\x3', - '\x6', '\x3', '\a', '\x3', '\a', '\x3', '\b', '\x3', '\b', '\x3', '\t', - '\x3', '\t', '\x3', '\n', '\x3', '\n', '\x3', '\v', '\x3', '\v', '\a', - '\v', '<', '\n', '\v', '\f', '\v', '\xE', '\v', '?', '\v', '\v', '\x3', - '\f', '\x3', '\f', '\x3', '\f', '\x5', '\f', '\x44', '\n', '\f', '\x3', - '\f', '\x5', '\f', 'G', '\n', '\f', '\x3', '\f', '\x3', '\f', '\x5', '\f', - 'K', '\n', '\f', '\x3', '\r', '\x5', '\r', 'N', '\n', '\r', '\x3', '\xE', - '\x3', '\xE', '\x5', '\xE', 'R', '\n', '\xE', '\x3', '\xF', '\x6', '\xF', - 'U', '\n', '\xF', '\r', '\xF', '\xE', '\xF', 'V', '\x3', '\xF', '\x3', - '\xF', '\x6', '\xF', '[', '\n', '\xF', '\r', '\xF', '\xE', '\xF', '\\', - '\x5', '\xF', '_', '\n', '\xF', '\x3', '\x10', '\x3', '\x10', '\x3', '\x11', - '\x3', '\x11', '\x3', '\x12', '\x3', '\x12', '\x3', '\x13', '\x6', '\x13', - 'h', '\n', '\x13', '\r', '\x13', '\xE', '\x13', 'i', '\x3', '\x13', '\x3', - '\x13', '\x2', '\x2', '\x14', '\x3', '\x3', '\x5', '\x4', '\a', '\x5', - '\t', '\x6', '\v', '\a', '\r', '\b', '\xF', '\t', '\x11', '\n', '\x13', - '\v', '\x15', '\f', '\x17', '\r', '\x19', '\x2', '\x1B', '\x2', '\x1D', - '\x2', '\x1F', '\x2', '!', '\x2', '#', '\x2', '%', '\xE', '\x3', '\x2', - '\x5', '\x5', '\x2', '\x43', '\\', '\x61', '\x61', '\x63', '|', '\x4', - '\x2', '-', '-', '/', '/', '\x5', '\x2', '\v', '\f', '\xF', '\xF', '\"', - '\"', '\x2', 'o', '\x2', '\x3', '\x3', '\x2', '\x2', '\x2', '\x2', '\x5', + '\x13', '\x4', '\x14', '\t', '\x14', '\x4', '\x15', '\t', '\x15', '\x4', + '\x16', '\t', '\x16', '\x4', '\x17', '\t', '\x17', '\x4', '\x18', '\t', + '\x18', '\x4', '\x19', '\t', '\x19', '\x4', '\x1A', '\t', '\x1A', '\x4', + '\x1B', '\t', '\x1B', '\x4', '\x1C', '\t', '\x1C', '\x4', '\x1D', '\t', + '\x1D', '\x4', '\x1E', '\t', '\x1E', '\x4', '\x1F', '\t', '\x1F', '\x4', + ' ', '\t', ' ', '\x4', '!', '\t', '!', '\x3', '\x2', '\x3', '\x2', '\x3', + '\x3', '\x3', '\x3', '\x3', '\x4', '\x3', '\x4', '\x3', '\x5', '\x3', + '\x5', '\x3', '\x6', '\x3', '\x6', '\x3', '\a', '\x3', '\a', '\x3', '\b', + '\x3', '\b', '\x3', '\t', '\x3', '\t', '\x3', '\n', '\x3', '\n', '\x3', + '\v', '\x3', '\v', '\a', '\v', 'X', '\n', '\v', '\f', '\v', '\xE', '\v', + '[', '\v', '\v', '\x3', '\f', '\x3', '\f', '\x3', '\r', '\x3', '\r', '\x3', + '\xE', '\x3', '\xE', '\x3', '\xE', '\x3', '\xF', '\x3', '\xF', '\x3', + '\xF', '\x3', '\x10', '\x3', '\x10', '\x3', '\x10', '\x3', '\x11', '\x3', + '\x11', '\x3', '\x11', '\x3', '\x12', '\x3', '\x12', '\x3', '\x12', '\x5', + '\x12', 'p', '\n', '\x12', '\x3', '\x13', '\x5', '\x13', 's', '\n', '\x13', + '\x3', '\x14', '\x3', '\x14', '\x5', '\x14', 'w', '\n', '\x14', '\x3', + '\x15', '\x6', '\x15', 'z', '\n', '\x15', '\r', '\x15', '\xE', '\x15', + '{', '\x3', '\x16', '\x6', '\x16', '\x7F', '\n', '\x16', '\r', '\x16', + '\xE', '\x16', '\x80', '\x3', '\x17', '\a', '\x17', '\x84', '\n', '\x17', + '\f', '\x17', '\xE', '\x17', '\x87', '\v', '\x17', '\x3', '\x17', '\x3', + '\x17', '\x6', '\x17', '\x8B', '\n', '\x17', '\r', '\x17', '\xE', '\x17', + '\x8C', '\x3', '\x18', '\x6', '\x18', '\x90', '\n', '\x18', '\r', '\x18', + '\xE', '\x18', '\x91', '\x3', '\x19', '\x6', '\x19', '\x95', '\n', '\x19', + '\r', '\x19', '\xE', '\x19', '\x96', '\x3', '\x1A', '\x3', '\x1A', '\x3', + '\x1A', '\x3', '\x1B', '\x3', '\x1B', '\x3', '\x1B', '\x3', '\x1C', '\x3', + '\x1C', '\x3', '\x1C', '\x3', '\x1D', '\x3', '\x1D', '\x3', '\x1D', '\x3', + '\x1E', '\x3', '\x1E', '\x3', '\x1E', '\x3', '\x1F', '\x3', '\x1F', '\x3', + ' ', '\x3', ' ', '\x3', '!', '\x6', '!', '\xAD', '\n', '!', '\r', '!', + '\xE', '!', '\xAE', '\x3', '!', '\x3', '!', '\x2', '\x2', '\"', '\x3', + '\x3', '\x5', '\x4', '\a', '\x5', '\t', '\x6', '\v', '\a', '\r', '\b', + '\xF', '\t', '\x11', '\n', '\x13', '\v', '\x15', '\f', '\x17', '\r', '\x19', + '\xE', '\x1B', '\xF', '\x1D', '\x10', '\x1F', '\x11', '!', '\x12', '#', + '\x13', '%', '\x2', '\'', '\x2', ')', '\x2', '+', '\x2', '-', '\x2', '/', + '\x2', '\x31', '\x2', '\x33', '\x2', '\x35', '\x2', '\x37', '\x2', '\x39', + '\x2', ';', '\x2', '=', '\x2', '?', '\x2', '\x41', '\x14', '\x3', '\x2', + '\f', '\x6', '\x2', '&', '&', '\x43', '\\', '\x61', '\x61', '\x63', '|', + '\x5', '\x2', '\x32', ';', '\x43', 'H', '\x63', 'h', '\x4', '\x2', '\x46', + '\x46', '\x66', '\x66', '\x4', '\x2', 'K', 'K', 'k', 'k', '\x4', '\x2', + 'Q', 'Q', 'q', 'q', '\x4', '\x2', '\x44', '\x44', '\x64', '\x64', '\x4', + '\x2', 'Z', 'Z', 'z', 'z', '\x4', '\x2', 'G', 'G', 'g', 'g', '\x4', '\x2', + '-', '-', '/', '/', '\x5', '\x2', '\v', '\f', '\xF', '\xF', '\"', '\"', + '\x2', '\xAD', '\x2', '\x3', '\x3', '\x2', '\x2', '\x2', '\x2', '\x5', '\x3', '\x2', '\x2', '\x2', '\x2', '\a', '\x3', '\x2', '\x2', '\x2', '\x2', '\t', '\x3', '\x2', '\x2', '\x2', '\x2', '\v', '\x3', '\x2', '\x2', '\x2', '\x2', '\r', '\x3', '\x2', '\x2', '\x2', '\x2', '\xF', '\x3', '\x2', '\x2', '\x2', '\x2', '\x11', '\x3', '\x2', '\x2', '\x2', '\x2', '\x13', '\x3', '\x2', '\x2', '\x2', '\x2', '\x15', '\x3', '\x2', '\x2', '\x2', '\x2', - '\x17', '\x3', '\x2', '\x2', '\x2', '\x2', '%', '\x3', '\x2', '\x2', '\x2', - '\x3', '\'', '\x3', '\x2', '\x2', '\x2', '\x5', ')', '\x3', '\x2', '\x2', - '\x2', '\a', '+', '\x3', '\x2', '\x2', '\x2', '\t', '-', '\x3', '\x2', - '\x2', '\x2', '\v', '/', '\x3', '\x2', '\x2', '\x2', '\r', '\x31', '\x3', - '\x2', '\x2', '\x2', '\xF', '\x33', '\x3', '\x2', '\x2', '\x2', '\x11', - '\x35', '\x3', '\x2', '\x2', '\x2', '\x13', '\x37', '\x3', '\x2', '\x2', - '\x2', '\x15', '\x39', '\x3', '\x2', '\x2', '\x2', '\x17', '@', '\x3', - '\x2', '\x2', '\x2', '\x19', 'M', '\x3', '\x2', '\x2', '\x2', '\x1B', - 'Q', '\x3', '\x2', '\x2', '\x2', '\x1D', 'T', '\x3', '\x2', '\x2', '\x2', - '\x1F', '`', '\x3', '\x2', '\x2', '\x2', '!', '\x62', '\x3', '\x2', '\x2', - '\x2', '#', '\x64', '\x3', '\x2', '\x2', '\x2', '%', 'g', '\x3', '\x2', - '\x2', '\x2', '\'', '(', '\a', '*', '\x2', '\x2', '(', '\x4', '\x3', '\x2', - '\x2', '\x2', ')', '*', '\a', '+', '\x2', '\x2', '*', '\x6', '\x3', '\x2', - '\x2', '\x2', '+', ',', '\a', '-', '\x2', '\x2', ',', '\b', '\x3', '\x2', - '\x2', '\x2', '-', '.', '\a', '/', '\x2', '\x2', '.', '\n', '\x3', '\x2', - '\x2', '\x2', '/', '\x30', '\a', ',', '\x2', '\x2', '\x30', '\f', '\x3', - '\x2', '\x2', '\x2', '\x31', '\x32', '\a', '\x31', '\x2', '\x2', '\x32', - '\xE', '\x3', '\x2', '\x2', '\x2', '\x33', '\x34', '\a', '.', '\x2', '\x2', - '\x34', '\x10', '\x3', '\x2', '\x2', '\x2', '\x35', '\x36', '\a', '\x30', - '\x2', '\x2', '\x36', '\x12', '\x3', '\x2', '\x2', '\x2', '\x37', '\x38', - '\a', '`', '\x2', '\x2', '\x38', '\x14', '\x3', '\x2', '\x2', '\x2', '\x39', - '=', '\x5', '\x19', '\r', '\x2', ':', '<', '\x5', '\x1B', '\xE', '\x2', - ';', ':', '\x3', '\x2', '\x2', '\x2', '<', '?', '\x3', '\x2', '\x2', '\x2', - '=', ';', '\x3', '\x2', '\x2', '\x2', '=', '>', '\x3', '\x2', '\x2', '\x2', - '>', '\x16', '\x3', '\x2', '\x2', '\x2', '?', '=', '\x3', '\x2', '\x2', - '\x2', '@', 'J', '\x5', '\x1D', '\xF', '\x2', '\x41', '\x44', '\x5', '\x1F', - '\x10', '\x2', '\x42', '\x44', '\x5', '!', '\x11', '\x2', '\x43', '\x41', - '\x3', '\x2', '\x2', '\x2', '\x43', '\x42', '\x3', '\x2', '\x2', '\x2', - '\x44', '\x46', '\x3', '\x2', '\x2', '\x2', '\x45', 'G', '\x5', '#', '\x12', - '\x2', '\x46', '\x45', '\x3', '\x2', '\x2', '\x2', '\x46', 'G', '\x3', - '\x2', '\x2', '\x2', 'G', 'H', '\x3', '\x2', '\x2', '\x2', 'H', 'I', '\x5', - '\x1D', '\xF', '\x2', 'I', 'K', '\x3', '\x2', '\x2', '\x2', 'J', '\x43', - '\x3', '\x2', '\x2', '\x2', 'J', 'K', '\x3', '\x2', '\x2', '\x2', 'K', - '\x18', '\x3', '\x2', '\x2', '\x2', 'L', 'N', '\t', '\x2', '\x2', '\x2', - 'M', 'L', '\x3', '\x2', '\x2', '\x2', 'N', '\x1A', '\x3', '\x2', '\x2', - '\x2', 'O', 'R', '\x5', '\x19', '\r', '\x2', 'P', 'R', '\x4', '\x32', - ';', '\x2', 'Q', 'O', '\x3', '\x2', '\x2', '\x2', 'Q', 'P', '\x3', '\x2', - '\x2', '\x2', 'R', '\x1C', '\x3', '\x2', '\x2', '\x2', 'S', 'U', '\x4', - '\x32', ';', '\x2', 'T', 'S', '\x3', '\x2', '\x2', '\x2', 'U', 'V', '\x3', - '\x2', '\x2', '\x2', 'V', 'T', '\x3', '\x2', '\x2', '\x2', 'V', 'W', '\x3', - '\x2', '\x2', '\x2', 'W', '^', '\x3', '\x2', '\x2', '\x2', 'X', 'Z', '\a', - '\x30', '\x2', '\x2', 'Y', '[', '\x4', '\x32', ';', '\x2', 'Z', 'Y', '\x3', - '\x2', '\x2', '\x2', '[', '\\', '\x3', '\x2', '\x2', '\x2', '\\', 'Z', - '\x3', '\x2', '\x2', '\x2', '\\', ']', '\x3', '\x2', '\x2', '\x2', ']', - '_', '\x3', '\x2', '\x2', '\x2', '^', 'X', '\x3', '\x2', '\x2', '\x2', - '^', '_', '\x3', '\x2', '\x2', '\x2', '_', '\x1E', '\x3', '\x2', '\x2', - '\x2', '`', '\x61', '\a', 'G', '\x2', '\x2', '\x61', ' ', '\x3', '\x2', - '\x2', '\x2', '\x62', '\x63', '\a', 'g', '\x2', '\x2', '\x63', '\"', '\x3', - '\x2', '\x2', '\x2', '\x64', '\x65', '\t', '\x3', '\x2', '\x2', '\x65', - '$', '\x3', '\x2', '\x2', '\x2', '\x66', 'h', '\t', '\x4', '\x2', '\x2', - 'g', '\x66', '\x3', '\x2', '\x2', '\x2', 'h', 'i', '\x3', '\x2', '\x2', - '\x2', 'i', 'g', '\x3', '\x2', '\x2', '\x2', 'i', 'j', '\x3', '\x2', '\x2', - '\x2', 'j', 'k', '\x3', '\x2', '\x2', '\x2', 'k', 'l', '\b', '\x13', '\x2', - '\x2', 'l', '&', '\x3', '\x2', '\x2', '\x2', '\r', '\x2', '=', '\x43', - '\x46', 'J', 'M', 'Q', 'V', '\\', '^', 'i', '\x3', '\b', '\x2', '\x2', + '\x17', '\x3', '\x2', '\x2', '\x2', '\x2', '\x19', '\x3', '\x2', '\x2', + '\x2', '\x2', '\x1B', '\x3', '\x2', '\x2', '\x2', '\x2', '\x1D', '\x3', + '\x2', '\x2', '\x2', '\x2', '\x1F', '\x3', '\x2', '\x2', '\x2', '\x2', + '!', '\x3', '\x2', '\x2', '\x2', '\x2', '#', '\x3', '\x2', '\x2', '\x2', + '\x2', '\x41', '\x3', '\x2', '\x2', '\x2', '\x3', '\x43', '\x3', '\x2', + '\x2', '\x2', '\x5', '\x45', '\x3', '\x2', '\x2', '\x2', '\a', 'G', '\x3', + '\x2', '\x2', '\x2', '\t', 'I', '\x3', '\x2', '\x2', '\x2', '\v', 'K', + '\x3', '\x2', '\x2', '\x2', '\r', 'M', '\x3', '\x2', '\x2', '\x2', '\xF', + 'O', '\x3', '\x2', '\x2', '\x2', '\x11', 'Q', '\x3', '\x2', '\x2', '\x2', + '\x13', 'S', '\x3', '\x2', '\x2', '\x2', '\x15', 'U', '\x3', '\x2', '\x2', + '\x2', '\x17', '\\', '\x3', '\x2', '\x2', '\x2', '\x19', '^', '\x3', '\x2', + '\x2', '\x2', '\x1B', '`', '\x3', '\x2', '\x2', '\x2', '\x1D', '\x63', + '\x3', '\x2', '\x2', '\x2', '\x1F', '\x66', '\x3', '\x2', '\x2', '\x2', + '!', 'i', '\x3', '\x2', '\x2', '\x2', '#', 'l', '\x3', '\x2', '\x2', '\x2', + '%', 'r', '\x3', '\x2', '\x2', '\x2', '\'', 'v', '\x3', '\x2', '\x2', + '\x2', ')', 'y', '\x3', '\x2', '\x2', '\x2', '+', '~', '\x3', '\x2', '\x2', + '\x2', '-', '\x85', '\x3', '\x2', '\x2', '\x2', '/', '\x8F', '\x3', '\x2', + '\x2', '\x2', '\x31', '\x94', '\x3', '\x2', '\x2', '\x2', '\x33', '\x98', + '\x3', '\x2', '\x2', '\x2', '\x35', '\x9B', '\x3', '\x2', '\x2', '\x2', + '\x37', '\x9E', '\x3', '\x2', '\x2', '\x2', '\x39', '\xA1', '\x3', '\x2', + '\x2', '\x2', ';', '\xA4', '\x3', '\x2', '\x2', '\x2', '=', '\xA7', '\x3', + '\x2', '\x2', '\x2', '?', '\xA9', '\x3', '\x2', '\x2', '\x2', '\x41', + '\xAC', '\x3', '\x2', '\x2', '\x2', '\x43', '\x44', '\a', '*', '\x2', + '\x2', '\x44', '\x4', '\x3', '\x2', '\x2', '\x2', '\x45', '\x46', '\a', + '+', '\x2', '\x2', '\x46', '\x6', '\x3', '\x2', '\x2', '\x2', 'G', 'H', + '\a', '-', '\x2', '\x2', 'H', '\b', '\x3', '\x2', '\x2', '\x2', 'I', 'J', + '\a', '/', '\x2', '\x2', 'J', '\n', '\x3', '\x2', '\x2', '\x2', 'K', 'L', + '\a', ',', '\x2', '\x2', 'L', '\f', '\x3', '\x2', '\x2', '\x2', 'M', 'N', + '\a', '\x31', '\x2', '\x2', 'N', '\xE', '\x3', '\x2', '\x2', '\x2', 'O', + 'P', '\a', '.', '\x2', '\x2', 'P', '\x10', '\x3', '\x2', '\x2', '\x2', + 'Q', 'R', '\a', '\x30', '\x2', '\x2', 'R', '\x12', '\x3', '\x2', '\x2', + '\x2', 'S', 'T', '\a', '`', '\x2', '\x2', 'T', '\x14', '\x3', '\x2', '\x2', + '\x2', 'U', 'Y', '\x5', '%', '\x13', '\x2', 'V', 'X', '\x5', '\'', '\x14', + '\x2', 'W', 'V', '\x3', '\x2', '\x2', '\x2', 'X', '[', '\x3', '\x2', '\x2', + '\x2', 'Y', 'W', '\x3', '\x2', '\x2', '\x2', 'Y', 'Z', '\x3', '\x2', '\x2', + '\x2', 'Z', '\x16', '\x3', '\x2', '\x2', '\x2', '[', 'Y', '\x3', '\x2', + '\x2', '\x2', '\\', ']', '\x5', '-', '\x17', '\x2', ']', '\x18', '\x3', + '\x2', '\x2', '\x2', '^', '_', '\x5', ')', '\x15', '\x2', '_', '\x1A', + '\x3', '\x2', '\x2', '\x2', '`', '\x61', '\x5', '\x39', '\x1D', '\x2', + '\x61', '\x62', '\x5', '/', '\x18', '\x2', '\x62', '\x1C', '\x3', '\x2', + '\x2', '\x2', '\x63', '\x64', '\x5', ';', '\x1E', '\x2', '\x64', '\x65', + '\x5', '\x31', '\x19', '\x2', '\x65', '\x1E', '\x3', '\x2', '\x2', '\x2', + '\x66', 'g', '\x5', '\x35', '\x1B', '\x2', 'g', 'h', '\x5', ')', '\x15', + '\x2', 'h', ' ', '\x3', '\x2', '\x2', '\x2', 'i', 'j', '\x5', '\x37', + '\x1C', '\x2', 'j', 'k', '\x5', '+', '\x16', '\x2', 'k', '\"', '\x3', + '\x2', '\x2', '\x2', 'l', 'o', '\x5', '\x33', '\x1A', '\x2', 'm', 'p', + '\x5', '-', '\x17', '\x2', 'n', 'p', '\x5', ')', '\x15', '\x2', 'o', 'm', + '\x3', '\x2', '\x2', '\x2', 'o', 'n', '\x3', '\x2', '\x2', '\x2', 'p', + '$', '\x3', '\x2', '\x2', '\x2', 'q', 's', '\t', '\x2', '\x2', '\x2', + 'r', 'q', '\x3', '\x2', '\x2', '\x2', 's', '&', '\x3', '\x2', '\x2', '\x2', + 't', 'w', '\x5', '%', '\x13', '\x2', 'u', 'w', '\x4', '\x32', ';', '\x2', + 'v', 't', '\x3', '\x2', '\x2', '\x2', 'v', 'u', '\x3', '\x2', '\x2', '\x2', + 'w', '(', '\x3', '\x2', '\x2', '\x2', 'x', 'z', '\x4', '\x32', ';', '\x2', + 'y', 'x', '\x3', '\x2', '\x2', '\x2', 'z', '{', '\x3', '\x2', '\x2', '\x2', + '{', 'y', '\x3', '\x2', '\x2', '\x2', '{', '|', '\x3', '\x2', '\x2', '\x2', + '|', '*', '\x3', '\x2', '\x2', '\x2', '}', '\x7F', '\x4', '\x32', '\x39', + '\x2', '~', '}', '\x3', '\x2', '\x2', '\x2', '\x7F', '\x80', '\x3', '\x2', + '\x2', '\x2', '\x80', '~', '\x3', '\x2', '\x2', '\x2', '\x80', '\x81', + '\x3', '\x2', '\x2', '\x2', '\x81', ',', '\x3', '\x2', '\x2', '\x2', '\x82', + '\x84', '\x4', '\x32', ';', '\x2', '\x83', '\x82', '\x3', '\x2', '\x2', + '\x2', '\x84', '\x87', '\x3', '\x2', '\x2', '\x2', '\x85', '\x83', '\x3', + '\x2', '\x2', '\x2', '\x85', '\x86', '\x3', '\x2', '\x2', '\x2', '\x86', + '\x88', '\x3', '\x2', '\x2', '\x2', '\x87', '\x85', '\x3', '\x2', '\x2', + '\x2', '\x88', '\x8A', '\a', '\x30', '\x2', '\x2', '\x89', '\x8B', '\x4', + '\x32', ';', '\x2', '\x8A', '\x89', '\x3', '\x2', '\x2', '\x2', '\x8B', + '\x8C', '\x3', '\x2', '\x2', '\x2', '\x8C', '\x8A', '\x3', '\x2', '\x2', + '\x2', '\x8C', '\x8D', '\x3', '\x2', '\x2', '\x2', '\x8D', '.', '\x3', + '\x2', '\x2', '\x2', '\x8E', '\x90', '\x4', '\x32', '\x33', '\x2', '\x8F', + '\x8E', '\x3', '\x2', '\x2', '\x2', '\x90', '\x91', '\x3', '\x2', '\x2', + '\x2', '\x91', '\x8F', '\x3', '\x2', '\x2', '\x2', '\x91', '\x92', '\x3', + '\x2', '\x2', '\x2', '\x92', '\x30', '\x3', '\x2', '\x2', '\x2', '\x93', + '\x95', '\t', '\x3', '\x2', '\x2', '\x94', '\x93', '\x3', '\x2', '\x2', + '\x2', '\x95', '\x96', '\x3', '\x2', '\x2', '\x2', '\x96', '\x94', '\x3', + '\x2', '\x2', '\x2', '\x96', '\x97', '\x3', '\x2', '\x2', '\x2', '\x97', + '\x32', '\x3', '\x2', '\x2', '\x2', '\x98', '\x99', '\a', '\x32', '\x2', + '\x2', '\x99', '\x9A', '\t', '\x4', '\x2', '\x2', '\x9A', '\x34', '\x3', + '\x2', '\x2', '\x2', '\x9B', '\x9C', '\a', '\x32', '\x2', '\x2', '\x9C', + '\x9D', '\t', '\x5', '\x2', '\x2', '\x9D', '\x36', '\x3', '\x2', '\x2', + '\x2', '\x9E', '\x9F', '\a', '\x32', '\x2', '\x2', '\x9F', '\xA0', '\t', + '\x6', '\x2', '\x2', '\xA0', '\x38', '\x3', '\x2', '\x2', '\x2', '\xA1', + '\xA2', '\a', '\x32', '\x2', '\x2', '\xA2', '\xA3', '\t', '\a', '\x2', + '\x2', '\xA3', ':', '\x3', '\x2', '\x2', '\x2', '\xA4', '\xA5', '\a', + '\x32', '\x2', '\x2', '\xA5', '\xA6', '\t', '\b', '\x2', '\x2', '\xA6', + '<', '\x3', '\x2', '\x2', '\x2', '\xA7', '\xA8', '\t', '\t', '\x2', '\x2', + '\xA8', '>', '\x3', '\x2', '\x2', '\x2', '\xA9', '\xAA', '\t', '\n', '\x2', + '\x2', '\xAA', '@', '\x3', '\x2', '\x2', '\x2', '\xAB', '\xAD', '\t', + '\v', '\x2', '\x2', '\xAC', '\xAB', '\x3', '\x2', '\x2', '\x2', '\xAD', + '\xAE', '\x3', '\x2', '\x2', '\x2', '\xAE', '\xAC', '\x3', '\x2', '\x2', + '\x2', '\xAE', '\xAF', '\x3', '\x2', '\x2', '\x2', '\xAF', '\xB0', '\x3', + '\x2', '\x2', '\x2', '\xB0', '\xB1', '\b', '!', '\x2', '\x2', '\xB1', + '\x42', '\x3', '\x2', '\x2', '\x2', '\xF', '\x2', 'Y', 'o', 'r', 'v', + '{', '\x80', '\x85', '\x8C', '\x91', '\x94', '\x96', '\xAE', '\x3', '\b', + '\x2', '\x2', }; public static readonly ATN _ATN = diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.interp b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.interp index c636130..f372ee7 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.interp +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.interp @@ -12,6 +12,12 @@ null null null null +null +null +null +null +null +null token symbolic names: null @@ -25,7 +31,13 @@ COMMA POINT POW IDENTIFIER -SCIENTIFIC_NUMBER +DECIMAL_NUMBER +INTEGER_NUMBER +PREFIX_BIN_NUMBER +PREFIX_HEX_NUMBER +PREFIX_INT_NUMBER +PREFIX_OCT_NUMBER +PREFIX_DEC_NUMBER WS rule names: @@ -39,12 +51,26 @@ COMMA POINT POW IDENTIFIER -SCIENTIFIC_NUMBER +DECIMAL_NUMBER +INTEGER_NUMBER +PREFIX_BIN_NUMBER +PREFIX_HEX_NUMBER +PREFIX_INT_NUMBER +PREFIX_OCT_NUMBER +PREFIX_DEC_NUMBER VALID_ID_START VALID_ID_CHAR -NUMBER -E1 -E2 +NUMBER_INT +NUMBER_OCT +NUMBER_DEC +NUMBER_BIN +NUMBER_HEX +PREFIX_DEC +PREFIX_INT +PREFIX_OCT +PREFIX_BIN +PREFIX_HEX +E SIGN WS @@ -56,4 +82,4 @@ mode names: DEFAULT_MODE atn: -[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 14, 109, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 7, 11, 60, 10, 11, 12, 11, 14, 11, 63, 11, 11, 3, 12, 3, 12, 3, 12, 5, 12, 68, 10, 12, 3, 12, 5, 12, 71, 10, 12, 3, 12, 3, 12, 5, 12, 75, 10, 12, 3, 13, 5, 13, 78, 10, 13, 3, 14, 3, 14, 5, 14, 82, 10, 14, 3, 15, 6, 15, 85, 10, 15, 13, 15, 14, 15, 86, 3, 15, 3, 15, 6, 15, 91, 10, 15, 13, 15, 14, 15, 92, 5, 15, 95, 10, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 19, 6, 19, 104, 10, 19, 13, 19, 14, 19, 105, 3, 19, 3, 19, 2, 2, 20, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 2, 27, 2, 29, 2, 31, 2, 33, 2, 35, 2, 37, 14, 3, 2, 5, 5, 2, 67, 92, 97, 97, 99, 124, 4, 2, 45, 45, 47, 47, 5, 2, 11, 12, 15, 15, 34, 34, 2, 111, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 3, 39, 3, 2, 2, 2, 5, 41, 3, 2, 2, 2, 7, 43, 3, 2, 2, 2, 9, 45, 3, 2, 2, 2, 11, 47, 3, 2, 2, 2, 13, 49, 3, 2, 2, 2, 15, 51, 3, 2, 2, 2, 17, 53, 3, 2, 2, 2, 19, 55, 3, 2, 2, 2, 21, 57, 3, 2, 2, 2, 23, 64, 3, 2, 2, 2, 25, 77, 3, 2, 2, 2, 27, 81, 3, 2, 2, 2, 29, 84, 3, 2, 2, 2, 31, 96, 3, 2, 2, 2, 33, 98, 3, 2, 2, 2, 35, 100, 3, 2, 2, 2, 37, 103, 3, 2, 2, 2, 39, 40, 7, 42, 2, 2, 40, 4, 3, 2, 2, 2, 41, 42, 7, 43, 2, 2, 42, 6, 3, 2, 2, 2, 43, 44, 7, 45, 2, 2, 44, 8, 3, 2, 2, 2, 45, 46, 7, 47, 2, 2, 46, 10, 3, 2, 2, 2, 47, 48, 7, 44, 2, 2, 48, 12, 3, 2, 2, 2, 49, 50, 7, 49, 2, 2, 50, 14, 3, 2, 2, 2, 51, 52, 7, 46, 2, 2, 52, 16, 3, 2, 2, 2, 53, 54, 7, 48, 2, 2, 54, 18, 3, 2, 2, 2, 55, 56, 7, 96, 2, 2, 56, 20, 3, 2, 2, 2, 57, 61, 5, 25, 13, 2, 58, 60, 5, 27, 14, 2, 59, 58, 3, 2, 2, 2, 60, 63, 3, 2, 2, 2, 61, 59, 3, 2, 2, 2, 61, 62, 3, 2, 2, 2, 62, 22, 3, 2, 2, 2, 63, 61, 3, 2, 2, 2, 64, 74, 5, 29, 15, 2, 65, 68, 5, 31, 16, 2, 66, 68, 5, 33, 17, 2, 67, 65, 3, 2, 2, 2, 67, 66, 3, 2, 2, 2, 68, 70, 3, 2, 2, 2, 69, 71, 5, 35, 18, 2, 70, 69, 3, 2, 2, 2, 70, 71, 3, 2, 2, 2, 71, 72, 3, 2, 2, 2, 72, 73, 5, 29, 15, 2, 73, 75, 3, 2, 2, 2, 74, 67, 3, 2, 2, 2, 74, 75, 3, 2, 2, 2, 75, 24, 3, 2, 2, 2, 76, 78, 9, 2, 2, 2, 77, 76, 3, 2, 2, 2, 78, 26, 3, 2, 2, 2, 79, 82, 5, 25, 13, 2, 80, 82, 4, 50, 59, 2, 81, 79, 3, 2, 2, 2, 81, 80, 3, 2, 2, 2, 82, 28, 3, 2, 2, 2, 83, 85, 4, 50, 59, 2, 84, 83, 3, 2, 2, 2, 85, 86, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 86, 87, 3, 2, 2, 2, 87, 94, 3, 2, 2, 2, 88, 90, 7, 48, 2, 2, 89, 91, 4, 50, 59, 2, 90, 89, 3, 2, 2, 2, 91, 92, 3, 2, 2, 2, 92, 90, 3, 2, 2, 2, 92, 93, 3, 2, 2, 2, 93, 95, 3, 2, 2, 2, 94, 88, 3, 2, 2, 2, 94, 95, 3, 2, 2, 2, 95, 30, 3, 2, 2, 2, 96, 97, 7, 71, 2, 2, 97, 32, 3, 2, 2, 2, 98, 99, 7, 103, 2, 2, 99, 34, 3, 2, 2, 2, 100, 101, 9, 3, 2, 2, 101, 36, 3, 2, 2, 2, 102, 104, 9, 4, 2, 2, 103, 102, 3, 2, 2, 2, 104, 105, 3, 2, 2, 2, 105, 103, 3, 2, 2, 2, 105, 106, 3, 2, 2, 2, 106, 107, 3, 2, 2, 2, 107, 108, 8, 19, 2, 2, 108, 38, 3, 2, 2, 2, 13, 2, 61, 67, 70, 74, 77, 81, 86, 92, 94, 105, 3, 8, 2, 2] \ No newline at end of file +[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 20, 178, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 7, 11, 88, 10, 11, 12, 11, 14, 11, 91, 11, 11, 3, 12, 3, 12, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 16, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 5, 18, 112, 10, 18, 3, 19, 5, 19, 115, 10, 19, 3, 20, 3, 20, 5, 20, 119, 10, 20, 3, 21, 6, 21, 122, 10, 21, 13, 21, 14, 21, 123, 3, 22, 6, 22, 127, 10, 22, 13, 22, 14, 22, 128, 3, 23, 7, 23, 132, 10, 23, 12, 23, 14, 23, 135, 11, 23, 3, 23, 3, 23, 6, 23, 139, 10, 23, 13, 23, 14, 23, 140, 3, 24, 6, 24, 144, 10, 24, 13, 24, 14, 24, 145, 3, 25, 6, 25, 149, 10, 25, 13, 25, 14, 25, 150, 3, 26, 3, 26, 3, 26, 3, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 30, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 33, 6, 33, 173, 10, 33, 13, 33, 14, 33, 174, 3, 33, 3, 33, 2, 2, 34, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 2, 39, 2, 41, 2, 43, 2, 45, 2, 47, 2, 49, 2, 51, 2, 53, 2, 55, 2, 57, 2, 59, 2, 61, 2, 63, 2, 65, 20, 3, 2, 12, 6, 2, 38, 38, 67, 92, 97, 97, 99, 124, 5, 2, 50, 59, 67, 72, 99, 104, 4, 2, 70, 70, 102, 102, 4, 2, 75, 75, 107, 107, 4, 2, 81, 81, 113, 113, 4, 2, 68, 68, 100, 100, 4, 2, 90, 90, 122, 122, 4, 2, 71, 71, 103, 103, 4, 2, 45, 45, 47, 47, 5, 2, 11, 12, 15, 15, 34, 34, 2, 173, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 65, 3, 2, 2, 2, 3, 67, 3, 2, 2, 2, 5, 69, 3, 2, 2, 2, 7, 71, 3, 2, 2, 2, 9, 73, 3, 2, 2, 2, 11, 75, 3, 2, 2, 2, 13, 77, 3, 2, 2, 2, 15, 79, 3, 2, 2, 2, 17, 81, 3, 2, 2, 2, 19, 83, 3, 2, 2, 2, 21, 85, 3, 2, 2, 2, 23, 92, 3, 2, 2, 2, 25, 94, 3, 2, 2, 2, 27, 96, 3, 2, 2, 2, 29, 99, 3, 2, 2, 2, 31, 102, 3, 2, 2, 2, 33, 105, 3, 2, 2, 2, 35, 108, 3, 2, 2, 2, 37, 114, 3, 2, 2, 2, 39, 118, 3, 2, 2, 2, 41, 121, 3, 2, 2, 2, 43, 126, 3, 2, 2, 2, 45, 133, 3, 2, 2, 2, 47, 143, 3, 2, 2, 2, 49, 148, 3, 2, 2, 2, 51, 152, 3, 2, 2, 2, 53, 155, 3, 2, 2, 2, 55, 158, 3, 2, 2, 2, 57, 161, 3, 2, 2, 2, 59, 164, 3, 2, 2, 2, 61, 167, 3, 2, 2, 2, 63, 169, 3, 2, 2, 2, 65, 172, 3, 2, 2, 2, 67, 68, 7, 42, 2, 2, 68, 4, 3, 2, 2, 2, 69, 70, 7, 43, 2, 2, 70, 6, 3, 2, 2, 2, 71, 72, 7, 45, 2, 2, 72, 8, 3, 2, 2, 2, 73, 74, 7, 47, 2, 2, 74, 10, 3, 2, 2, 2, 75, 76, 7, 44, 2, 2, 76, 12, 3, 2, 2, 2, 77, 78, 7, 49, 2, 2, 78, 14, 3, 2, 2, 2, 79, 80, 7, 46, 2, 2, 80, 16, 3, 2, 2, 2, 81, 82, 7, 48, 2, 2, 82, 18, 3, 2, 2, 2, 83, 84, 7, 96, 2, 2, 84, 20, 3, 2, 2, 2, 85, 89, 5, 37, 19, 2, 86, 88, 5, 39, 20, 2, 87, 86, 3, 2, 2, 2, 88, 91, 3, 2, 2, 2, 89, 87, 3, 2, 2, 2, 89, 90, 3, 2, 2, 2, 90, 22, 3, 2, 2, 2, 91, 89, 3, 2, 2, 2, 92, 93, 5, 45, 23, 2, 93, 24, 3, 2, 2, 2, 94, 95, 5, 41, 21, 2, 95, 26, 3, 2, 2, 2, 96, 97, 5, 57, 29, 2, 97, 98, 5, 47, 24, 2, 98, 28, 3, 2, 2, 2, 99, 100, 5, 59, 30, 2, 100, 101, 5, 49, 25, 2, 101, 30, 3, 2, 2, 2, 102, 103, 5, 53, 27, 2, 103, 104, 5, 41, 21, 2, 104, 32, 3, 2, 2, 2, 105, 106, 5, 55, 28, 2, 106, 107, 5, 43, 22, 2, 107, 34, 3, 2, 2, 2, 108, 111, 5, 51, 26, 2, 109, 112, 5, 45, 23, 2, 110, 112, 5, 41, 21, 2, 111, 109, 3, 2, 2, 2, 111, 110, 3, 2, 2, 2, 112, 36, 3, 2, 2, 2, 113, 115, 9, 2, 2, 2, 114, 113, 3, 2, 2, 2, 115, 38, 3, 2, 2, 2, 116, 119, 5, 37, 19, 2, 117, 119, 4, 50, 59, 2, 118, 116, 3, 2, 2, 2, 118, 117, 3, 2, 2, 2, 119, 40, 3, 2, 2, 2, 120, 122, 4, 50, 59, 2, 121, 120, 3, 2, 2, 2, 122, 123, 3, 2, 2, 2, 123, 121, 3, 2, 2, 2, 123, 124, 3, 2, 2, 2, 124, 42, 3, 2, 2, 2, 125, 127, 4, 50, 57, 2, 126, 125, 3, 2, 2, 2, 127, 128, 3, 2, 2, 2, 128, 126, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 44, 3, 2, 2, 2, 130, 132, 4, 50, 59, 2, 131, 130, 3, 2, 2, 2, 132, 135, 3, 2, 2, 2, 133, 131, 3, 2, 2, 2, 133, 134, 3, 2, 2, 2, 134, 136, 3, 2, 2, 2, 135, 133, 3, 2, 2, 2, 136, 138, 7, 48, 2, 2, 137, 139, 4, 50, 59, 2, 138, 137, 3, 2, 2, 2, 139, 140, 3, 2, 2, 2, 140, 138, 3, 2, 2, 2, 140, 141, 3, 2, 2, 2, 141, 46, 3, 2, 2, 2, 142, 144, 4, 50, 51, 2, 143, 142, 3, 2, 2, 2, 144, 145, 3, 2, 2, 2, 145, 143, 3, 2, 2, 2, 145, 146, 3, 2, 2, 2, 146, 48, 3, 2, 2, 2, 147, 149, 9, 3, 2, 2, 148, 147, 3, 2, 2, 2, 149, 150, 3, 2, 2, 2, 150, 148, 3, 2, 2, 2, 150, 151, 3, 2, 2, 2, 151, 50, 3, 2, 2, 2, 152, 153, 7, 50, 2, 2, 153, 154, 9, 4, 2, 2, 154, 52, 3, 2, 2, 2, 155, 156, 7, 50, 2, 2, 156, 157, 9, 5, 2, 2, 157, 54, 3, 2, 2, 2, 158, 159, 7, 50, 2, 2, 159, 160, 9, 6, 2, 2, 160, 56, 3, 2, 2, 2, 161, 162, 7, 50, 2, 2, 162, 163, 9, 7, 2, 2, 163, 58, 3, 2, 2, 2, 164, 165, 7, 50, 2, 2, 165, 166, 9, 8, 2, 2, 166, 60, 3, 2, 2, 2, 167, 168, 9, 9, 2, 2, 168, 62, 3, 2, 2, 2, 169, 170, 9, 10, 2, 2, 170, 64, 3, 2, 2, 2, 171, 173, 9, 11, 2, 2, 172, 171, 3, 2, 2, 2, 173, 174, 3, 2, 2, 2, 174, 172, 3, 2, 2, 2, 174, 175, 3, 2, 2, 2, 175, 176, 3, 2, 2, 2, 176, 177, 8, 33, 2, 2, 177, 66, 3, 2, 2, 2, 15, 2, 89, 111, 114, 118, 123, 128, 133, 140, 145, 148, 150, 174, 3, 8, 2, 2] \ No newline at end of file diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.tokens b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.tokens index 83a628c..a254e9e 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.tokens +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerLexer.tokens @@ -8,8 +8,14 @@ COMMA=7 POINT=8 POW=9 IDENTIFIER=10 -SCIENTIFIC_NUMBER=11 -WS=12 +DECIMAL_NUMBER=11 +INTEGER_NUMBER=12 +PREFIX_BIN_NUMBER=13 +PREFIX_HEX_NUMBER=14 +PREFIX_INT_NUMBER=15 +PREFIX_OCT_NUMBER=16 +PREFIX_DEC_NUMBER=17 +WS=18 '('=1 ')'=2 '+'=3 diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerListener.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerListener.cs index 0b0ceb3..f53f669 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerListener.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerListener.cs @@ -95,18 +95,6 @@ public interface IFormulaGrammerListener : IParseTreeListener { /// The parse tree. void ExitNegativeAtom([NotNull] FormulaGrammerParser.NegativeAtomContext context); /// - /// Enter a parse tree produced by the Function - /// labeled alternative in . - /// - /// The parse tree. - void EnterFunction([NotNull] FormulaGrammerParser.FunctionContext context); - /// - /// Exit a parse tree produced by the Function - /// labeled alternative in . - /// - /// The parse tree. - void ExitFunction([NotNull] FormulaGrammerParser.FunctionContext context); - /// /// Enter a parse tree produced by the UnsignedAtom /// labeled alternative in . /// @@ -129,17 +117,89 @@ public interface IFormulaGrammerListener : IParseTreeListener { /// The parse tree. void ExitAtom([NotNull] FormulaGrammerParser.AtomContext context); /// - /// Enter a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Enter a parse tree produced by the DecimalNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context); + /// + /// Exit a parse tree produced by the DecimalNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context); + /// + /// Enter a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context); + /// + /// Exit a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context); + /// + /// Enter a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context); + /// + /// Exit a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context); + /// + /// Enter a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context); + /// + /// Exit a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context); + /// + /// Enter a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context); + /// + /// Exit a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context); + /// + /// Enter a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// + /// The parse tree. + void EnterPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context); + /// + /// Exit a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// + /// The parse tree. + void ExitPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context); + /// + /// Enter a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// /// The parse tree. - void EnterScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context); + void EnterPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context); /// - /// Exit a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Exit a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// /// The parse tree. - void ExitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context); + void ExitPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context); /// /// Enter a parse tree produced by . /// diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerParser.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerParser.cs index 05fe37c..3dd8c31 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerParser.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerParser.cs @@ -37,14 +37,16 @@ public partial class FormulaGrammerParser : Parser { protected static PredictionContextCache sharedContextCache = new PredictionContextCache(); public const int LPAREN=1, RPAREN=2, PLUS=3, MINUS=4, TIMES=5, DIV=6, COMMA=7, POINT=8, - POW=9, IDENTIFIER=10, SCIENTIFIC_NUMBER=11, WS=12; + POW=9, IDENTIFIER=10, DECIMAL_NUMBER=11, INTEGER_NUMBER=12, PREFIX_BIN_NUMBER=13, + PREFIX_HEX_NUMBER=14, PREFIX_INT_NUMBER=15, PREFIX_OCT_NUMBER=16, PREFIX_DEC_NUMBER=17, + WS=18; public const int RULE_formula = 0, RULE_expression = 1, RULE_multiplyingExpression = 2, - RULE_powExpression = 3, RULE_signedAtom = 4, RULE_atom = 5, RULE_scientific = 6, - RULE_func = 7, RULE_variable = 8; + RULE_powExpression = 3, RULE_signedAtom = 4, RULE_atom = 5, RULE_number = 6, + RULE_prefixedNumber = 7, RULE_func = 8, RULE_variable = 9; public static readonly string[] ruleNames = { "formula", "expression", "multiplyingExpression", "powExpression", "signedAtom", - "atom", "scientific", "func", "variable" + "atom", "number", "prefixedNumber", "func", "variable" }; private static readonly string[] _LiteralNames = { @@ -52,7 +54,9 @@ public const int }; private static readonly string[] _SymbolicNames = { null, "LPAREN", "RPAREN", "PLUS", "MINUS", "TIMES", "DIV", "COMMA", "POINT", - "POW", "IDENTIFIER", "SCIENTIFIC_NUMBER", "WS" + "POW", "IDENTIFIER", "DECIMAL_NUMBER", "INTEGER_NUMBER", "PREFIX_BIN_NUMBER", + "PREFIX_HEX_NUMBER", "PREFIX_INT_NUMBER", "PREFIX_OCT_NUMBER", "PREFIX_DEC_NUMBER", + "WS" }; public static readonly IVocabulary DefaultVocabulary = new Vocabulary(_LiteralNames, _SymbolicNames); @@ -118,8 +122,8 @@ public FormulaContext formula() { try { EnterOuterAlt(_localctx, 1); { - State = 18; expression(); - State = 19; Match(Eof); + State = 20; expression(); + State = 21; Match(Eof); } } catch (RecognitionException re) { @@ -176,14 +180,14 @@ public ExpressionContext expression() { try { EnterOuterAlt(_localctx, 1); { - State = 21; multiplyingExpression(); - State = 26; + State = 23; multiplyingExpression(); + State = 28; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==PLUS || _la==MINUS) { { { - State = 22; + State = 24; _la = TokenStream.LA(1); if ( !(_la==PLUS || _la==MINUS) ) { ErrorHandler.RecoverInline(this); @@ -192,10 +196,10 @@ public ExpressionContext expression() { ErrorHandler.ReportMatch(this); Consume(); } - State = 23; multiplyingExpression(); + State = 25; multiplyingExpression(); } } - State = 28; + State = 30; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } @@ -255,14 +259,14 @@ public MultiplyingExpressionContext multiplyingExpression() { try { EnterOuterAlt(_localctx, 1); { - State = 29; powExpression(); - State = 34; + State = 31; powExpression(); + State = 36; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==TIMES || _la==DIV) { { { - State = 30; + State = 32; _la = TokenStream.LA(1); if ( !(_la==TIMES || _la==DIV) ) { ErrorHandler.RecoverInline(this); @@ -271,10 +275,10 @@ public MultiplyingExpressionContext multiplyingExpression() { ErrorHandler.ReportMatch(this); Consume(); } - State = 31; powExpression(); + State = 33; powExpression(); } } - State = 36; + State = 38; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } @@ -330,18 +334,18 @@ public PowExpressionContext powExpression() { try { EnterOuterAlt(_localctx, 1); { - State = 37; signedAtom(); - State = 42; + State = 39; signedAtom(); + State = 44; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==POW) { { { - State = 38; Match(POW); - State = 39; signedAtom(); + State = 40; Match(POW); + State = 41; signedAtom(); } } - State = 44; + State = 46; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } @@ -390,25 +394,6 @@ public override TResult Accept(IParseTreeVisitor visitor) { else return visitor.VisitChildren(this); } } - public partial class FunctionContext : SignedAtomContext { - public FuncContext func() { - return GetRuleContext(0); - } - public FunctionContext(SignedAtomContext context) { CopyFrom(context); } - public override void EnterRule(IParseTreeListener listener) { - IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; - if (typedListener != null) typedListener.EnterFunction(this); - } - public override void ExitRule(IParseTreeListener listener) { - IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; - if (typedListener != null) typedListener.ExitFunction(this); - } - public override TResult Accept(IParseTreeVisitor visitor) { - IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; - if (typedVisitor != null) return typedVisitor.VisitFunction(this); - else return visitor.VisitChildren(this); - } - } public partial class PlusAtomContext : SignedAtomContext { public ITerminalNode PLUS() { return GetToken(FormulaGrammerParser.PLUS, 0); } public AtomContext atom() { @@ -454,39 +439,42 @@ public SignedAtomContext signedAtom() { SignedAtomContext _localctx = new SignedAtomContext(Context, State); EnterRule(_localctx, 8, RULE_signedAtom); try { - State = 51; + State = 52; ErrorHandler.Sync(this); - switch ( Interpreter.AdaptivePredict(TokenStream,3,Context) ) { - case 1: + switch (TokenStream.LA(1)) { + case PLUS: _localctx = new PlusAtomContext(_localctx); EnterOuterAlt(_localctx, 1); { - State = 45; Match(PLUS); - State = 46; atom(); + State = 47; Match(PLUS); + State = 48; atom(); } break; - case 2: + case MINUS: _localctx = new NegativeAtomContext(_localctx); EnterOuterAlt(_localctx, 2); { - State = 47; Match(MINUS); - State = 48; atom(); - } - break; - case 3: - _localctx = new FunctionContext(_localctx); - EnterOuterAlt(_localctx, 3); - { - State = 49; func(); + State = 49; Match(MINUS); + State = 50; atom(); } break; - case 4: + case LPAREN: + case IDENTIFIER: + case DECIMAL_NUMBER: + case INTEGER_NUMBER: + case PREFIX_BIN_NUMBER: + case PREFIX_HEX_NUMBER: + case PREFIX_INT_NUMBER: + case PREFIX_OCT_NUMBER: + case PREFIX_DEC_NUMBER: _localctx = new UnsignedAtomContext(_localctx); - EnterOuterAlt(_localctx, 4); + EnterOuterAlt(_localctx, 3); { - State = 50; atom(); + State = 51; atom(); } break; + default: + throw new NoViableAltException(this); } } catch (RecognitionException re) { @@ -501,8 +489,11 @@ public SignedAtomContext signedAtom() { } public partial class AtomContext : ParserRuleContext { - public ScientificContext scientific() { - return GetRuleContext(0); + public NumberContext number() { + return GetRuleContext(0); + } + public PrefixedNumberContext prefixedNumber() { + return GetRuleContext(0); } public VariableContext variable() { return GetRuleContext(0); @@ -512,6 +503,9 @@ public ExpressionContext expression() { return GetRuleContext(0); } public ITerminalNode RPAREN() { return GetToken(FormulaGrammerParser.RPAREN, 0); } + public FuncContext func() { + return GetRuleContext(0); + } public AtomContext(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { @@ -537,27 +531,121 @@ public AtomContext atom() { AtomContext _localctx = new AtomContext(Context, State); EnterRule(_localctx, 10, RULE_atom); try { - State = 59; + State = 62; ErrorHandler.Sync(this); - switch (TokenStream.LA(1)) { - case SCIENTIFIC_NUMBER: + switch ( Interpreter.AdaptivePredict(TokenStream,4,Context) ) { + case 1: EnterOuterAlt(_localctx, 1); { - State = 53; scientific(); + State = 54; number(); } break; - case IDENTIFIER: + case 2: EnterOuterAlt(_localctx, 2); { - State = 54; variable(); + State = 55; prefixedNumber(); } break; - case LPAREN: + case 3: EnterOuterAlt(_localctx, 3); { - State = 55; Match(LPAREN); - State = 56; expression(); - State = 57; Match(RPAREN); + State = 56; variable(); + } + break; + case 4: + EnterOuterAlt(_localctx, 4); + { + State = 57; Match(LPAREN); + State = 58; expression(); + State = 59; Match(RPAREN); + } + break; + case 5: + EnterOuterAlt(_localctx, 5); + { + State = 61; func(); + } + break; + } + } + catch (RecognitionException re) { + _localctx.exception = re; + ErrorHandler.ReportError(this, re); + ErrorHandler.Recover(this, re); + } + finally { + ExitRule(); + } + return _localctx; + } + + public partial class NumberContext : ParserRuleContext { + public NumberContext(ParserRuleContext parent, int invokingState) + : base(parent, invokingState) + { + } + public override int RuleIndex { get { return RULE_number; } } + + public NumberContext() { } + public virtual void CopyFrom(NumberContext context) { + base.CopyFrom(context); + } + } + public partial class DecimalNumberContext : NumberContext { + public ITerminalNode DECIMAL_NUMBER() { return GetToken(FormulaGrammerParser.DECIMAL_NUMBER, 0); } + public DecimalNumberContext(NumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterDecimalNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitDecimalNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitDecimalNumber(this); + else return visitor.VisitChildren(this); + } + } + public partial class IntgerNumberContext : NumberContext { + public ITerminalNode INTEGER_NUMBER() { return GetToken(FormulaGrammerParser.INTEGER_NUMBER, 0); } + public IntgerNumberContext(NumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterIntgerNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitIntgerNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitIntgerNumber(this); + else return visitor.VisitChildren(this); + } + } + + [RuleVersion(0)] + public NumberContext number() { + NumberContext _localctx = new NumberContext(Context, State); + EnterRule(_localctx, 12, RULE_number); + try { + State = 66; + ErrorHandler.Sync(this); + switch (TokenStream.LA(1)) { + case DECIMAL_NUMBER: + _localctx = new DecimalNumberContext(_localctx); + EnterOuterAlt(_localctx, 1); + { + State = 64; Match(DECIMAL_NUMBER); + } + break; + case INTEGER_NUMBER: + _localctx = new IntgerNumberContext(_localctx); + EnterOuterAlt(_localctx, 2); + { + State = 65; Match(INTEGER_NUMBER); } break; default: @@ -575,45 +663,149 @@ public AtomContext atom() { return _localctx; } - public partial class ScientificContext : ParserRuleContext { - public ScientificContext(ParserRuleContext parent, int invokingState) + public partial class PrefixedNumberContext : ParserRuleContext { + public PrefixedNumberContext(ParserRuleContext parent, int invokingState) : base(parent, invokingState) { } - public override int RuleIndex { get { return RULE_scientific; } } + public override int RuleIndex { get { return RULE_prefixedNumber; } } - public ScientificContext() { } - public virtual void CopyFrom(ScientificContext context) { + public PrefixedNumberContext() { } + public virtual void CopyFrom(PrefixedNumberContext context) { base.CopyFrom(context); } } - public partial class ScientificNumberContext : ScientificContext { - public ITerminalNode SCIENTIFIC_NUMBER() { return GetToken(FormulaGrammerParser.SCIENTIFIC_NUMBER, 0); } - public ScientificNumberContext(ScientificContext context) { CopyFrom(context); } + public partial class PrefixedOctNumberContext : PrefixedNumberContext { + public ITerminalNode PREFIX_OCT_NUMBER() { return GetToken(FormulaGrammerParser.PREFIX_OCT_NUMBER, 0); } + public PrefixedOctNumberContext(PrefixedNumberContext context) { CopyFrom(context); } public override void EnterRule(IParseTreeListener listener) { IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; - if (typedListener != null) typedListener.EnterScientificNumber(this); + if (typedListener != null) typedListener.EnterPrefixedOctNumber(this); } public override void ExitRule(IParseTreeListener listener) { IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; - if (typedListener != null) typedListener.ExitScientificNumber(this); + if (typedListener != null) typedListener.ExitPrefixedOctNumber(this); } public override TResult Accept(IParseTreeVisitor visitor) { IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; - if (typedVisitor != null) return typedVisitor.VisitScientificNumber(this); + if (typedVisitor != null) return typedVisitor.VisitPrefixedOctNumber(this); + else return visitor.VisitChildren(this); + } + } + public partial class PrefixedHexNumberContext : PrefixedNumberContext { + public ITerminalNode PREFIX_HEX_NUMBER() { return GetToken(FormulaGrammerParser.PREFIX_HEX_NUMBER, 0); } + public PrefixedHexNumberContext(PrefixedNumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterPrefixedHexNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitPrefixedHexNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitPrefixedHexNumber(this); + else return visitor.VisitChildren(this); + } + } + public partial class PrefixedDecNumberContext : PrefixedNumberContext { + public ITerminalNode PREFIX_DEC_NUMBER() { return GetToken(FormulaGrammerParser.PREFIX_DEC_NUMBER, 0); } + public PrefixedDecNumberContext(PrefixedNumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterPrefixedDecNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitPrefixedDecNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitPrefixedDecNumber(this); + else return visitor.VisitChildren(this); + } + } + public partial class PrefixedIntNumberContext : PrefixedNumberContext { + public ITerminalNode PREFIX_INT_NUMBER() { return GetToken(FormulaGrammerParser.PREFIX_INT_NUMBER, 0); } + public PrefixedIntNumberContext(PrefixedNumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterPrefixedIntNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitPrefixedIntNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitPrefixedIntNumber(this); + else return visitor.VisitChildren(this); + } + } + public partial class PrefixedBinNumberContext : PrefixedNumberContext { + public ITerminalNode PREFIX_BIN_NUMBER() { return GetToken(FormulaGrammerParser.PREFIX_BIN_NUMBER, 0); } + public PrefixedBinNumberContext(PrefixedNumberContext context) { CopyFrom(context); } + public override void EnterRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.EnterPrefixedBinNumber(this); + } + public override void ExitRule(IParseTreeListener listener) { + IFormulaGrammerListener typedListener = listener as IFormulaGrammerListener; + if (typedListener != null) typedListener.ExitPrefixedBinNumber(this); + } + public override TResult Accept(IParseTreeVisitor visitor) { + IFormulaGrammerVisitor typedVisitor = visitor as IFormulaGrammerVisitor; + if (typedVisitor != null) return typedVisitor.VisitPrefixedBinNumber(this); else return visitor.VisitChildren(this); } } [RuleVersion(0)] - public ScientificContext scientific() { - ScientificContext _localctx = new ScientificContext(Context, State); - EnterRule(_localctx, 12, RULE_scientific); + public PrefixedNumberContext prefixedNumber() { + PrefixedNumberContext _localctx = new PrefixedNumberContext(Context, State); + EnterRule(_localctx, 14, RULE_prefixedNumber); try { - _localctx = new ScientificNumberContext(_localctx); - EnterOuterAlt(_localctx, 1); - { - State = 61; Match(SCIENTIFIC_NUMBER); + State = 73; + ErrorHandler.Sync(this); + switch (TokenStream.LA(1)) { + case PREFIX_DEC_NUMBER: + _localctx = new PrefixedDecNumberContext(_localctx); + EnterOuterAlt(_localctx, 1); + { + State = 68; Match(PREFIX_DEC_NUMBER); + } + break; + case PREFIX_INT_NUMBER: + _localctx = new PrefixedIntNumberContext(_localctx); + EnterOuterAlt(_localctx, 2); + { + State = 69; Match(PREFIX_INT_NUMBER); + } + break; + case PREFIX_BIN_NUMBER: + _localctx = new PrefixedBinNumberContext(_localctx); + EnterOuterAlt(_localctx, 3); + { + State = 70; Match(PREFIX_BIN_NUMBER); + } + break; + case PREFIX_OCT_NUMBER: + _localctx = new PrefixedOctNumberContext(_localctx); + EnterOuterAlt(_localctx, 4); + { + State = 71; Match(PREFIX_OCT_NUMBER); + } + break; + case PREFIX_HEX_NUMBER: + _localctx = new PrefixedHexNumberContext(_localctx); + EnterOuterAlt(_localctx, 5); + { + State = 72; Match(PREFIX_HEX_NUMBER); + } + break; + default: + throw new NoViableAltException(this); } } catch (RecognitionException re) { @@ -664,37 +856,37 @@ public override TResult Accept(IParseTreeVisitor visitor) { [RuleVersion(0)] public FuncContext func() { FuncContext _localctx = new FuncContext(Context, State); - EnterRule(_localctx, 14, RULE_func); + EnterRule(_localctx, 16, RULE_func); int _la; try { EnterOuterAlt(_localctx, 1); { - State = 63; Match(IDENTIFIER); - State = 64; Match(LPAREN); - State = 73; + State = 75; Match(IDENTIFIER); + State = 76; Match(LPAREN); + State = 85; ErrorHandler.Sync(this); _la = TokenStream.LA(1); - if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LPAREN) | (1L << PLUS) | (1L << MINUS) | (1L << IDENTIFIER) | (1L << SCIENTIFIC_NUMBER))) != 0)) { + if ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << LPAREN) | (1L << PLUS) | (1L << MINUS) | (1L << IDENTIFIER) | (1L << DECIMAL_NUMBER) | (1L << INTEGER_NUMBER) | (1L << PREFIX_BIN_NUMBER) | (1L << PREFIX_HEX_NUMBER) | (1L << PREFIX_INT_NUMBER) | (1L << PREFIX_OCT_NUMBER) | (1L << PREFIX_DEC_NUMBER))) != 0)) { { - State = 65; expression(); - State = 70; + State = 77; expression(); + State = 82; ErrorHandler.Sync(this); _la = TokenStream.LA(1); while (_la==COMMA) { { { - State = 66; Match(COMMA); - State = 67; expression(); + State = 78; Match(COMMA); + State = 79; expression(); } } - State = 72; + State = 84; ErrorHandler.Sync(this); _la = TokenStream.LA(1); } } } - State = 75; Match(RPAREN); + State = 87; Match(RPAREN); } } catch (RecognitionException re) { @@ -733,11 +925,11 @@ public override TResult Accept(IParseTreeVisitor visitor) { [RuleVersion(0)] public VariableContext variable() { VariableContext _localctx = new VariableContext(Context, State); - EnterRule(_localctx, 16, RULE_variable); + EnterRule(_localctx, 18, RULE_variable); try { EnterOuterAlt(_localctx, 1); { - State = 77; Match(IDENTIFIER); + State = 89; Match(IDENTIFIER); } } catch (RecognitionException re) { @@ -753,69 +945,81 @@ public VariableContext variable() { private static char[] _serializedATN = { '\x3', '\x608B', '\xA72A', '\x8133', '\xB9ED', '\x417C', '\x3BE7', '\x7786', - '\x5964', '\x3', '\xE', 'R', '\x4', '\x2', '\t', '\x2', '\x4', '\x3', + '\x5964', '\x3', '\x14', '^', '\x4', '\x2', '\t', '\x2', '\x4', '\x3', '\t', '\x3', '\x4', '\x4', '\t', '\x4', '\x4', '\x5', '\t', '\x5', '\x4', '\x6', '\t', '\x6', '\x4', '\a', '\t', '\a', '\x4', '\b', '\t', '\b', - '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x3', '\x2', '\x3', - '\x2', '\x3', '\x2', '\x3', '\x3', '\x3', '\x3', '\x3', '\x3', '\a', '\x3', - '\x1B', '\n', '\x3', '\f', '\x3', '\xE', '\x3', '\x1E', '\v', '\x3', '\x3', - '\x4', '\x3', '\x4', '\x3', '\x4', '\a', '\x4', '#', '\n', '\x4', '\f', - '\x4', '\xE', '\x4', '&', '\v', '\x4', '\x3', '\x5', '\x3', '\x5', '\x3', - '\x5', '\a', '\x5', '+', '\n', '\x5', '\f', '\x5', '\xE', '\x5', '.', - '\v', '\x5', '\x3', '\x6', '\x3', '\x6', '\x3', '\x6', '\x3', '\x6', '\x3', - '\x6', '\x3', '\x6', '\x5', '\x6', '\x36', '\n', '\x6', '\x3', '\a', '\x3', - '\a', '\x3', '\a', '\x3', '\a', '\x3', '\a', '\x3', '\a', '\x5', '\a', - '>', '\n', '\a', '\x3', '\b', '\x3', '\b', '\x3', '\t', '\x3', '\t', '\x3', - '\t', '\x3', '\t', '\x3', '\t', '\a', '\t', 'G', '\n', '\t', '\f', '\t', - '\xE', '\t', 'J', '\v', '\t', '\x5', '\t', 'L', '\n', '\t', '\x3', '\t', - '\x3', '\t', '\x3', '\n', '\x3', '\n', '\x3', '\n', '\x2', '\x2', '\v', - '\x2', '\x4', '\x6', '\b', '\n', '\f', '\xE', '\x10', '\x12', '\x2', '\x4', - '\x3', '\x2', '\x5', '\x6', '\x3', '\x2', '\a', '\b', '\x2', 'R', '\x2', - '\x14', '\x3', '\x2', '\x2', '\x2', '\x4', '\x17', '\x3', '\x2', '\x2', - '\x2', '\x6', '\x1F', '\x3', '\x2', '\x2', '\x2', '\b', '\'', '\x3', '\x2', - '\x2', '\x2', '\n', '\x35', '\x3', '\x2', '\x2', '\x2', '\f', '=', '\x3', - '\x2', '\x2', '\x2', '\xE', '?', '\x3', '\x2', '\x2', '\x2', '\x10', '\x41', - '\x3', '\x2', '\x2', '\x2', '\x12', 'O', '\x3', '\x2', '\x2', '\x2', '\x14', - '\x15', '\x5', '\x4', '\x3', '\x2', '\x15', '\x16', '\a', '\x2', '\x2', - '\x3', '\x16', '\x3', '\x3', '\x2', '\x2', '\x2', '\x17', '\x1C', '\x5', - '\x6', '\x4', '\x2', '\x18', '\x19', '\t', '\x2', '\x2', '\x2', '\x19', - '\x1B', '\x5', '\x6', '\x4', '\x2', '\x1A', '\x18', '\x3', '\x2', '\x2', - '\x2', '\x1B', '\x1E', '\x3', '\x2', '\x2', '\x2', '\x1C', '\x1A', '\x3', - '\x2', '\x2', '\x2', '\x1C', '\x1D', '\x3', '\x2', '\x2', '\x2', '\x1D', - '\x5', '\x3', '\x2', '\x2', '\x2', '\x1E', '\x1C', '\x3', '\x2', '\x2', - '\x2', '\x1F', '$', '\x5', '\b', '\x5', '\x2', ' ', '!', '\t', '\x3', - '\x2', '\x2', '!', '#', '\x5', '\b', '\x5', '\x2', '\"', ' ', '\x3', '\x2', - '\x2', '\x2', '#', '&', '\x3', '\x2', '\x2', '\x2', '$', '\"', '\x3', - '\x2', '\x2', '\x2', '$', '%', '\x3', '\x2', '\x2', '\x2', '%', '\a', - '\x3', '\x2', '\x2', '\x2', '&', '$', '\x3', '\x2', '\x2', '\x2', '\'', - ',', '\x5', '\n', '\x6', '\x2', '(', ')', '\a', '\v', '\x2', '\x2', ')', - '+', '\x5', '\n', '\x6', '\x2', '*', '(', '\x3', '\x2', '\x2', '\x2', - '+', '.', '\x3', '\x2', '\x2', '\x2', ',', '*', '\x3', '\x2', '\x2', '\x2', - ',', '-', '\x3', '\x2', '\x2', '\x2', '-', '\t', '\x3', '\x2', '\x2', - '\x2', '.', ',', '\x3', '\x2', '\x2', '\x2', '/', '\x30', '\a', '\x5', - '\x2', '\x2', '\x30', '\x36', '\x5', '\f', '\a', '\x2', '\x31', '\x32', - '\a', '\x6', '\x2', '\x2', '\x32', '\x36', '\x5', '\f', '\a', '\x2', '\x33', - '\x36', '\x5', '\x10', '\t', '\x2', '\x34', '\x36', '\x5', '\f', '\a', - '\x2', '\x35', '/', '\x3', '\x2', '\x2', '\x2', '\x35', '\x31', '\x3', - '\x2', '\x2', '\x2', '\x35', '\x33', '\x3', '\x2', '\x2', '\x2', '\x35', - '\x34', '\x3', '\x2', '\x2', '\x2', '\x36', '\v', '\x3', '\x2', '\x2', - '\x2', '\x37', '>', '\x5', '\xE', '\b', '\x2', '\x38', '>', '\x5', '\x12', - '\n', '\x2', '\x39', ':', '\a', '\x3', '\x2', '\x2', ':', ';', '\x5', - '\x4', '\x3', '\x2', ';', '<', '\a', '\x4', '\x2', '\x2', '<', '>', '\x3', - '\x2', '\x2', '\x2', '=', '\x37', '\x3', '\x2', '\x2', '\x2', '=', '\x38', - '\x3', '\x2', '\x2', '\x2', '=', '\x39', '\x3', '\x2', '\x2', '\x2', '>', - '\r', '\x3', '\x2', '\x2', '\x2', '?', '@', '\a', '\r', '\x2', '\x2', - '@', '\xF', '\x3', '\x2', '\x2', '\x2', '\x41', '\x42', '\a', '\f', '\x2', - '\x2', '\x42', 'K', '\a', '\x3', '\x2', '\x2', '\x43', 'H', '\x5', '\x4', - '\x3', '\x2', '\x44', '\x45', '\a', '\t', '\x2', '\x2', '\x45', 'G', '\x5', - '\x4', '\x3', '\x2', '\x46', '\x44', '\x3', '\x2', '\x2', '\x2', 'G', - 'J', '\x3', '\x2', '\x2', '\x2', 'H', '\x46', '\x3', '\x2', '\x2', '\x2', - 'H', 'I', '\x3', '\x2', '\x2', '\x2', 'I', 'L', '\x3', '\x2', '\x2', '\x2', - 'J', 'H', '\x3', '\x2', '\x2', '\x2', 'K', '\x43', '\x3', '\x2', '\x2', - '\x2', 'K', 'L', '\x3', '\x2', '\x2', '\x2', 'L', 'M', '\x3', '\x2', '\x2', - '\x2', 'M', 'N', '\a', '\x4', '\x2', '\x2', 'N', '\x11', '\x3', '\x2', - '\x2', '\x2', 'O', 'P', '\a', '\f', '\x2', '\x2', 'P', '\x13', '\x3', - '\x2', '\x2', '\x2', '\t', '\x1C', '$', ',', '\x35', '=', 'H', 'K', + '\x4', '\t', '\t', '\t', '\x4', '\n', '\t', '\n', '\x4', '\v', '\t', '\v', + '\x3', '\x2', '\x3', '\x2', '\x3', '\x2', '\x3', '\x3', '\x3', '\x3', + '\x3', '\x3', '\a', '\x3', '\x1D', '\n', '\x3', '\f', '\x3', '\xE', '\x3', + ' ', '\v', '\x3', '\x3', '\x4', '\x3', '\x4', '\x3', '\x4', '\a', '\x4', + '%', '\n', '\x4', '\f', '\x4', '\xE', '\x4', '(', '\v', '\x4', '\x3', + '\x5', '\x3', '\x5', '\x3', '\x5', '\a', '\x5', '-', '\n', '\x5', '\f', + '\x5', '\xE', '\x5', '\x30', '\v', '\x5', '\x3', '\x6', '\x3', '\x6', + '\x3', '\x6', '\x3', '\x6', '\x3', '\x6', '\x5', '\x6', '\x37', '\n', + '\x6', '\x3', '\a', '\x3', '\a', '\x3', '\a', '\x3', '\a', '\x3', '\a', + '\x3', '\a', '\x3', '\a', '\x3', '\a', '\x5', '\a', '\x41', '\n', '\a', + '\x3', '\b', '\x3', '\b', '\x5', '\b', '\x45', '\n', '\b', '\x3', '\t', + '\x3', '\t', '\x3', '\t', '\x3', '\t', '\x3', '\t', '\x5', '\t', 'L', + '\n', '\t', '\x3', '\n', '\x3', '\n', '\x3', '\n', '\x3', '\n', '\x3', + '\n', '\a', '\n', 'S', '\n', '\n', '\f', '\n', '\xE', '\n', 'V', '\v', + '\n', '\x5', '\n', 'X', '\n', '\n', '\x3', '\n', '\x3', '\n', '\x3', '\v', + '\x3', '\v', '\x3', '\v', '\x2', '\x2', '\f', '\x2', '\x4', '\x6', '\b', + '\n', '\f', '\xE', '\x10', '\x12', '\x14', '\x2', '\x4', '\x3', '\x2', + '\x5', '\x6', '\x3', '\x2', '\a', '\b', '\x2', '\x63', '\x2', '\x16', + '\x3', '\x2', '\x2', '\x2', '\x4', '\x19', '\x3', '\x2', '\x2', '\x2', + '\x6', '!', '\x3', '\x2', '\x2', '\x2', '\b', ')', '\x3', '\x2', '\x2', + '\x2', '\n', '\x36', '\x3', '\x2', '\x2', '\x2', '\f', '@', '\x3', '\x2', + '\x2', '\x2', '\xE', '\x44', '\x3', '\x2', '\x2', '\x2', '\x10', 'K', + '\x3', '\x2', '\x2', '\x2', '\x12', 'M', '\x3', '\x2', '\x2', '\x2', '\x14', + '[', '\x3', '\x2', '\x2', '\x2', '\x16', '\x17', '\x5', '\x4', '\x3', + '\x2', '\x17', '\x18', '\a', '\x2', '\x2', '\x3', '\x18', '\x3', '\x3', + '\x2', '\x2', '\x2', '\x19', '\x1E', '\x5', '\x6', '\x4', '\x2', '\x1A', + '\x1B', '\t', '\x2', '\x2', '\x2', '\x1B', '\x1D', '\x5', '\x6', '\x4', + '\x2', '\x1C', '\x1A', '\x3', '\x2', '\x2', '\x2', '\x1D', ' ', '\x3', + '\x2', '\x2', '\x2', '\x1E', '\x1C', '\x3', '\x2', '\x2', '\x2', '\x1E', + '\x1F', '\x3', '\x2', '\x2', '\x2', '\x1F', '\x5', '\x3', '\x2', '\x2', + '\x2', ' ', '\x1E', '\x3', '\x2', '\x2', '\x2', '!', '&', '\x5', '\b', + '\x5', '\x2', '\"', '#', '\t', '\x3', '\x2', '\x2', '#', '%', '\x5', '\b', + '\x5', '\x2', '$', '\"', '\x3', '\x2', '\x2', '\x2', '%', '(', '\x3', + '\x2', '\x2', '\x2', '&', '$', '\x3', '\x2', '\x2', '\x2', '&', '\'', + '\x3', '\x2', '\x2', '\x2', '\'', '\a', '\x3', '\x2', '\x2', '\x2', '(', + '&', '\x3', '\x2', '\x2', '\x2', ')', '.', '\x5', '\n', '\x6', '\x2', + '*', '+', '\a', '\v', '\x2', '\x2', '+', '-', '\x5', '\n', '\x6', '\x2', + ',', '*', '\x3', '\x2', '\x2', '\x2', '-', '\x30', '\x3', '\x2', '\x2', + '\x2', '.', ',', '\x3', '\x2', '\x2', '\x2', '.', '/', '\x3', '\x2', '\x2', + '\x2', '/', '\t', '\x3', '\x2', '\x2', '\x2', '\x30', '.', '\x3', '\x2', + '\x2', '\x2', '\x31', '\x32', '\a', '\x5', '\x2', '\x2', '\x32', '\x37', + '\x5', '\f', '\a', '\x2', '\x33', '\x34', '\a', '\x6', '\x2', '\x2', '\x34', + '\x37', '\x5', '\f', '\a', '\x2', '\x35', '\x37', '\x5', '\f', '\a', '\x2', + '\x36', '\x31', '\x3', '\x2', '\x2', '\x2', '\x36', '\x33', '\x3', '\x2', + '\x2', '\x2', '\x36', '\x35', '\x3', '\x2', '\x2', '\x2', '\x37', '\v', + '\x3', '\x2', '\x2', '\x2', '\x38', '\x41', '\x5', '\xE', '\b', '\x2', + '\x39', '\x41', '\x5', '\x10', '\t', '\x2', ':', '\x41', '\x5', '\x14', + '\v', '\x2', ';', '<', '\a', '\x3', '\x2', '\x2', '<', '=', '\x5', '\x4', + '\x3', '\x2', '=', '>', '\a', '\x4', '\x2', '\x2', '>', '\x41', '\x3', + '\x2', '\x2', '\x2', '?', '\x41', '\x5', '\x12', '\n', '\x2', '@', '\x38', + '\x3', '\x2', '\x2', '\x2', '@', '\x39', '\x3', '\x2', '\x2', '\x2', '@', + ':', '\x3', '\x2', '\x2', '\x2', '@', ';', '\x3', '\x2', '\x2', '\x2', + '@', '?', '\x3', '\x2', '\x2', '\x2', '\x41', '\r', '\x3', '\x2', '\x2', + '\x2', '\x42', '\x45', '\a', '\r', '\x2', '\x2', '\x43', '\x45', '\a', + '\xE', '\x2', '\x2', '\x44', '\x42', '\x3', '\x2', '\x2', '\x2', '\x44', + '\x43', '\x3', '\x2', '\x2', '\x2', '\x45', '\xF', '\x3', '\x2', '\x2', + '\x2', '\x46', 'L', '\a', '\x13', '\x2', '\x2', 'G', 'L', '\a', '\x11', + '\x2', '\x2', 'H', 'L', '\a', '\xF', '\x2', '\x2', 'I', 'L', '\a', '\x12', + '\x2', '\x2', 'J', 'L', '\a', '\x10', '\x2', '\x2', 'K', '\x46', '\x3', + '\x2', '\x2', '\x2', 'K', 'G', '\x3', '\x2', '\x2', '\x2', 'K', 'H', '\x3', + '\x2', '\x2', '\x2', 'K', 'I', '\x3', '\x2', '\x2', '\x2', 'K', 'J', '\x3', + '\x2', '\x2', '\x2', 'L', '\x11', '\x3', '\x2', '\x2', '\x2', 'M', 'N', + '\a', '\f', '\x2', '\x2', 'N', 'W', '\a', '\x3', '\x2', '\x2', 'O', 'T', + '\x5', '\x4', '\x3', '\x2', 'P', 'Q', '\a', '\t', '\x2', '\x2', 'Q', 'S', + '\x5', '\x4', '\x3', '\x2', 'R', 'P', '\x3', '\x2', '\x2', '\x2', 'S', + 'V', '\x3', '\x2', '\x2', '\x2', 'T', 'R', '\x3', '\x2', '\x2', '\x2', + 'T', 'U', '\x3', '\x2', '\x2', '\x2', 'U', 'X', '\x3', '\x2', '\x2', '\x2', + 'V', 'T', '\x3', '\x2', '\x2', '\x2', 'W', 'O', '\x3', '\x2', '\x2', '\x2', + 'W', 'X', '\x3', '\x2', '\x2', '\x2', 'X', 'Y', '\x3', '\x2', '\x2', '\x2', + 'Y', 'Z', '\a', '\x4', '\x2', '\x2', 'Z', '\x13', '\x3', '\x2', '\x2', + '\x2', '[', '\\', '\a', '\f', '\x2', '\x2', '\\', '\x15', '\x3', '\x2', + '\x2', '\x2', '\v', '\x1E', '&', '.', '\x36', '@', '\x44', 'K', 'T', 'W', }; public static readonly ATN _ATN = diff --git a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerVisitor.cs b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerVisitor.cs index 6269d38..b519a00 100644 --- a/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerVisitor.cs +++ b/ThinkSharp.FormulaParser/ANTLR/FormulaGrammerVisitor.cs @@ -70,13 +70,6 @@ public interface IFormulaGrammerVisitor : IParseTreeVisitor { /// The visitor result. Result VisitNegativeAtom([NotNull] FormulaGrammerParser.NegativeAtomContext context); /// - /// Visit a parse tree produced by the Function - /// labeled alternative in . - /// - /// The parse tree. - /// The visitor result. - Result VisitFunction([NotNull] FormulaGrammerParser.FunctionContext context); - /// /// Visit a parse tree produced by the UnsignedAtom /// labeled alternative in . /// @@ -90,12 +83,54 @@ public interface IFormulaGrammerVisitor : IParseTreeVisitor { /// The visitor result. Result VisitAtom([NotNull] FormulaGrammerParser.AtomContext context); /// - /// Visit a parse tree produced by the ScientificNumber - /// labeled alternative in . + /// Visit a parse tree produced by the DecimalNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitDecimalNumber([NotNull] FormulaGrammerParser.DecimalNumberContext context); + /// + /// Visit a parse tree produced by the IntgerNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitIntgerNumber([NotNull] FormulaGrammerParser.IntgerNumberContext context); + /// + /// Visit a parse tree produced by the PrefixedDecNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitPrefixedDecNumber([NotNull] FormulaGrammerParser.PrefixedDecNumberContext context); + /// + /// Visit a parse tree produced by the PrefixedIntNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitPrefixedIntNumber([NotNull] FormulaGrammerParser.PrefixedIntNumberContext context); + /// + /// Visit a parse tree produced by the PrefixedBinNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitPrefixedBinNumber([NotNull] FormulaGrammerParser.PrefixedBinNumberContext context); + /// + /// Visit a parse tree produced by the PrefixedOctNumber + /// labeled alternative in . + /// + /// The parse tree. + /// The visitor result. + Result VisitPrefixedOctNumber([NotNull] FormulaGrammerParser.PrefixedOctNumberContext context); + /// + /// Visit a parse tree produced by the PrefixedHexNumber + /// labeled alternative in . /// /// The parse tree. /// The visitor result. - Result VisitScientificNumber([NotNull] FormulaGrammerParser.ScientificNumberContext context); + Result VisitPrefixedHexNumber([NotNull] FormulaGrammerParser.PrefixedHexNumberContext context); /// /// Visit a parse tree produced by . /// diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperator.cs b/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperator.cs index 94452a8..2d2fad5 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperator.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperator.cs @@ -6,19 +6,39 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { public sealed class BinaryOperator { - readonly Func evaluation; - private static readonly IEnumerable allBinaryOperators = new[] + private readonly Func evaluationDouble; + private readonly Func evaluationInt; + private static readonly BinaryOperator[] allBinaryOperators; + + public static BinaryOperator Plus { get; } + public static BinaryOperator Minus { get; } + public static BinaryOperator Multiply { get; } + public static BinaryOperator DividedBy { get; } + + static BinaryOperator() { - new BinaryOperator("+", (x, y) => x + y), - new BinaryOperator( "-", (x, y) => x - y), - new BinaryOperator( "/", (x, y) => x / y), - new BinaryOperator("*", (x, y) => x* y), - }; + Plus = new BinaryOperator("+", (x, y) => x + y, (x, y) => x + y); + Minus = new BinaryOperator("-", (x, y) => x - y, (x, y) => x - y); + Multiply = new BinaryOperator("*", (x, y) => x * y, (x, y) => x * y); + DividedBy = new BinaryOperator("/", (x, y) => x / y, (x, y) => x / y); + + allBinaryOperators = new[] + { + Plus, + Minus, + Multiply, + DividedBy + }; + } - private BinaryOperator(string symbol, Func evaluation) + private BinaryOperator(string symbol, + Func evaluateDouble, + Func evaluateInt) { this.Symbol = symbol; - this.evaluation = evaluation; + this.evaluationDouble = evaluateDouble; + this.evaluationInt = evaluateInt; +; } public string Symbol { get; } @@ -26,6 +46,8 @@ private BinaryOperator(string symbol, Func evaluation) public static BinaryOperator BySymbol(string symbol) => allBinaryOperators.FirstOrDefault(o => o.Symbol == symbol) ?? throw new InvalidOperationException($"Unknonw binary operator symbol '{0}'."); - public double Evaluate(double left, double right) => this.evaluation(left, right); + public double Evaluate(double left, double right) => this.evaluationDouble(left, right); + + public long Evaluate(long left, long right) => this.evaluationInt(left, right); } } diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperatorNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperatorNode.cs index 5a29ab8..8a50ca0 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperatorNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/BinaryOperatorNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,6 +8,7 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("({LeftNode} {BinaryOperator.Symbol} {RightNode})")] public class BinaryOperatorNode : Node { public BinaryOperatorNode(BinaryOperator binaryOperator, Node leftNode, Node rightNode) diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/BracketedNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/BracketedNode.cs index 64500a2..67d7e14 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/BracketedNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/BracketedNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,9 +8,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("({ChildNode})")] public class BracketedNode : Node { - internal BracketedNode(Node childNode) + public BracketedNode(Node childNode) { this.ChildNode = childNode ?? throw new ArgumentNullException(nameof(childNode)); } diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/ConstantNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/ConstantNode.cs index 23d4769..a6de78b 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/ConstantNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/ConstantNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,9 +8,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("{Name}")] public class ConstantNode : Node { - internal ConstantNode(string name) + public ConstantNode(string name) { this.Name = name; } diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/NumericNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/DecimalNode.cs similarity index 75% rename from ThinkSharp.FormulaParser/Ast/Nodes/NumericNode.cs rename to ThinkSharp.FormulaParser/Ast/Nodes/DecimalNode.cs index 8c14d7f..b65fba8 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/NumericNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/DecimalNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,9 +8,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { - public class NumberNode : Node + [DebuggerDisplay("{Value}")] + public class DecimalNode : Node { - public NumberNode(double value) + public DecimalNode(double value) { this.Value = value; } diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/FormulaNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/FormulaNode.cs index 6139f5c..b786800 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/FormulaNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/FormulaNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,16 +8,14 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("{ChildNode}")] public class FormulaNode : Node { - public FormulaNode(Node childNode, string formularText) + public FormulaNode(Node childNode) { this.ChildNode = childNode ?? throw new ArgumentNullException(nameof(childNode)); - this.FormulaText = formularText; } - public string FormulaText { get; } - public Node ChildNode { get; } public override TReturn Visit(INodeVisitor visitor) => visitor.Visit(this); diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/FunctionNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/FunctionNode.cs index 0edc35b..e32e109 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/FunctionNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/FunctionNode.cs @@ -1,15 +1,14 @@ using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Diagnostics; using ThinkSharp.FormulaParsing.Ast.Visitors; namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("{Name}()")] public class FunctionNode : Node { - internal FunctionNode(string functionName, params Node[] parameters) + public FunctionNode(string functionName, params Node[] parameters) { this.FunctionName = functionName ?? throw new ArgumentNullException(nameof(functionName)); this.Parameters = parameters ?? new Node[0]; diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/IntegerNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/IntegerNode.cs new file mode 100644 index 0000000..2ab3ae2 --- /dev/null +++ b/ThinkSharp.FormulaParser/Ast/Nodes/IntegerNode.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using ThinkSharp.FormulaParsing.Ast.Visitors; + +namespace ThinkSharp.FormulaParsing.Ast.Nodes +{ + [DebuggerDisplay("{Value}")] + public class IntegerNode : Node + { + public IntegerNode(long value) : this(NumberFormat.Dec, value) + { + } + public IntegerNode(NumberFormat format, long value) + { + this.Format = format; + this.Value = value; + } + + public NumberFormat Format { get; } + + public long Value { get; } + + public override TReturn Visit(INodeVisitor visitor) => visitor.Visit(this); + } +} diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/NumberFormat.cs b/ThinkSharp.FormulaParser/Ast/Nodes/NumberFormat.cs new file mode 100644 index 0000000..6c55faf --- /dev/null +++ b/ThinkSharp.FormulaParser/Ast/Nodes/NumberFormat.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ThinkSharp.FormulaParsing.Ast.Nodes +{ + public enum NumberFormat + { + Dec, + Hex, + Bin, + Oct + } +} diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/PowerNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/PowerNode.cs index d397a0f..28c8ccc 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/PowerNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/PowerNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,9 +8,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("{BaseNode}^{ExponentNode}")] public class PowerNode : Node { - internal PowerNode(Node baseNode, Node exponentNode) + public PowerNode(Node baseNode, Node exponentNode) { this.BaseNode = baseNode ?? throw new ArgumentNullException(nameof(baseNode)); this.ExponentNode = exponentNode ?? throw new ArgumentNullException(nameof(exponentNode)); diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/SignedNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/SignedNode.cs index 788b6ce..f343abf 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/SignedNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/SignedNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -9,9 +10,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { public enum Sign { Plus, Minus } + [DebuggerDisplay("{Sign} {Node}")] public class SignedNode : Node { - internal SignedNode(Sign sign, Node node) + public SignedNode(Sign sign, Node node) { this.Sign = sign; this.Node = node ?? throw new ArgumentNullException(nameof(node)); diff --git a/ThinkSharp.FormulaParser/Ast/Nodes/VariableNode.cs b/ThinkSharp.FormulaParser/Ast/Nodes/VariableNode.cs index 8c0a254..d12a9e8 100644 --- a/ThinkSharp.FormulaParser/Ast/Nodes/VariableNode.cs +++ b/ThinkSharp.FormulaParser/Ast/Nodes/VariableNode.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -7,9 +8,10 @@ namespace ThinkSharp.FormulaParsing.Ast.Nodes { + [DebuggerDisplay("{Name}")] public class VariableNode : Node { - internal VariableNode(string name) + public VariableNode(string name) { this.Name = name; } diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/CloneTreeVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/CloneTreeVisitor.cs new file mode 100644 index 0000000..03c71e5 --- /dev/null +++ b/ThinkSharp.FormulaParser/Ast/Visitors/CloneTreeVisitor.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using ThinkSharp.FormulaParsing.Ast.Nodes; + +namespace ThinkSharp.FormulaParsing.Ast.Visitors +{ + public class CloneTreeVisitor : NodeVisitor + { + public override Node Visit(BinaryOperatorNode node) + { + return new BinaryOperatorNode( + node.BinaryOperator, + node.LeftNode.Visit(this), + node.RightNode.Visit(this)); + } + + public override Node Visit(BracketedNode node) + { + return new BracketedNode(node.ChildNode.Visit(this)); + } + + public override Node Visit(ConstantNode node) + { + return new ConstantNode(node.Name); + } + + public override Node Visit(FormulaNode node) + { + return new FormulaNode(node.ChildNode.Visit(this)); + } + + public override Node Visit(FunctionNode node) + { + return new FunctionNode(node.FunctionName, node.Parameters.Select(p => p.Visit(this)).ToArray()); + } + + public override Node Visit(DecimalNode node) + { + return new DecimalNode(node.Value); + } + + public override Node Visit(IntegerNode node) + { + return new IntegerNode(node.Format, node.Value); + } + + public override Node Visit(PowerNode node) + { + return new PowerNode(node.BaseNode.Visit(this), node.ExponentNode.Visit(this)); + } + + public override Node Visit(SignedNode node) + { + return new SignedNode(node.Sign, node.Node.Visit(this)); + } + + public override Node Visit(VariableNode node) + { + return new VariableNode(node.Name); + } + } +} diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/EvaluateAstVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/EvaluateAstVisitor.cs index 9520cfa..e2f6b4b 100644 --- a/ThinkSharp.FormulaParser/Ast/Visitors/EvaluateAstVisitor.cs +++ b/ThinkSharp.FormulaParser/Ast/Visitors/EvaluateAstVisitor.cs @@ -10,9 +10,9 @@ internal class EvaluateAstVisitor : NodeVisitor private readonly IDictionary variables; private readonly IConfigurationEvaluator configuration; - public EvaluateAstVisitor(IConfigurationEvaluator configurationEvaluation, IDictionary variables = null) + public EvaluateAstVisitor(IConfigurationEvaluator configurationEvaluation, IReadOnlyDictionary variables = null) { - this.variables = new Dictionary(variables ?? new Dictionary()); + this.variables = variables?.ToDictionary(x => x.Key, x => x.Value) ?? new Dictionary(); this.configuration = configurationEvaluation ?? throw new ArgumentNullException(nameof(configurationEvaluation)); foreach (var constant in configurationEvaluation.EnumerateConstantes()) @@ -26,7 +26,12 @@ public EvaluateAstVisitor(IConfigurationEvaluator configurationEvaluation, IDict } } - public override double Visit(NumberNode node) + public override double Visit(DecimalNode node) + { + return node.Value; + } + + public override double Visit(IntegerNode node) { return node.Value; } diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/INodeVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/INodeVisitor.cs index f982e03..b5fb893 100644 --- a/ThinkSharp.FormulaParser/Ast/Visitors/INodeVisitor.cs +++ b/ThinkSharp.FormulaParser/Ast/Visitors/INodeVisitor.cs @@ -13,7 +13,9 @@ public interface INodeVisitor TReturn Visit(BracketedNode node); - TReturn Visit(NumberNode node); + TReturn Visit(DecimalNode node); + + TReturn Visit(IntegerNode node); TReturn Visit(VariableNode node); diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/NodeVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/NodeVisitor.cs index 3998f93..4209d93 100644 --- a/ThinkSharp.FormulaParser/Ast/Visitors/NodeVisitor.cs +++ b/ThinkSharp.FormulaParser/Ast/Visitors/NodeVisitor.cs @@ -13,7 +13,9 @@ public abstract class NodeVisitor : INodeVisitor public virtual TResult Visit(BracketedNode node) => node.ChildNode.Visit(this); - public virtual TResult Visit(NumberNode node) => DefaultResult(); + public virtual TResult Visit(DecimalNode node) => DefaultResult(); + + public virtual TResult Visit(IntegerNode node) => DefaultResult(); public virtual TResult Visit(VariableNode node) => DefaultResult(); diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/NodesToTextDebugVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/NodesToTextDebugVisitor.cs new file mode 100644 index 0000000..b15c693 --- /dev/null +++ b/ThinkSharp.FormulaParser/Ast/Visitors/NodesToTextDebugVisitor.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using ThinkSharp.FormulaParsing.Ast.Nodes; + +namespace ThinkSharp.FormulaParsing.Ast.Visitors +{ + internal class NodesToTextDebugVisitor : INodeVisitor + { + public string Visit(FormulaNode node) + { + return node.ChildNode.Visit(this); + } + + public string Visit(BracketedNode node) => $"({node.ChildNode.Visit(this)})"; + + public string Visit(DecimalNode node) => node.Value.ToString("0.00", CultureInfo.InvariantCulture); + + public string Visit(VariableNode node) => node.Name; + + public string Visit(ConstantNode node) => node.Name; + + public string Visit(BinaryOperatorNode node) => $"{node.LeftNode.Visit(this)}{node.BinaryOperator.Symbol}{node.RightNode.Visit(this)}"; + + public string Visit(PowerNode node) => $"{node.BaseNode.Visit(this)}^{node.ExponentNode.Visit(this)}"; + + public string Visit(SignedNode node) => (node.Sign == Sign.Minus ? "-" : "") + node.Node.Visit(this); + + public string Visit(FunctionNode node) => $"{node.FunctionName}({string.Join(", ", node.Parameters.Select(p => p.Visit(this)))})"; + + public string Visit(IntegerNode node) => node.Value.ToString(); + } +} diff --git a/ThinkSharp.FormulaParser/Ast/Visitors/TransformNodesVisitor.cs b/ThinkSharp.FormulaParser/Ast/Visitors/TransformNodesVisitor.cs new file mode 100644 index 0000000..30ffb25 --- /dev/null +++ b/ThinkSharp.FormulaParser/Ast/Visitors/TransformNodesVisitor.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ThinkSharp.FormulaParsing.Ast.Nodes; + +namespace ThinkSharp.FormulaParsing.Ast.Visitors +{ + public abstract class TransformNodesVisitor : INodeVisitor + { + public virtual Node Visit(FormulaNode node) + { + var child = node.ChildNode.Visit(this); + + if (child == node.ChildNode) + { + return node; + } + + return new FormulaNode(child); + } + + public virtual Node Visit(BracketedNode node) + { + var child = node.ChildNode.Visit(this); + + if (child == node.ChildNode) + { + return node; + } + + return new BracketedNode(child); + } + + public virtual Node Visit(DecimalNode node) => node; + + public virtual Node Visit(IntegerNode node) => node; + + public virtual Node Visit(VariableNode node) => node; + + public virtual Node Visit(ConstantNode node) => node; + + public virtual Node Visit(BinaryOperatorNode node) + { + var left = node.LeftNode.Visit(this); + var right = node.RightNode.Visit(this); + + if (left == node.LeftNode && right == node.RightNode) + { + return node; + } + + return new BinaryOperatorNode(node.BinaryOperator, left, right); + } + + public virtual Node Visit(PowerNode node) + { + var baseNode = node.BaseNode.Visit(this); + var exponentNode = node.ExponentNode.Visit(this); + + if (baseNode == node.BaseNode && exponentNode == node.ExponentNode) + { + return node; + } + + return new PowerNode(baseNode, exponentNode); + } + + public virtual Node Visit(SignedNode node) + { + var child = node.Node.Visit(this); + + if (child == node.Node) + { + return node; + } + + return new SignedNode(node.Sign, child); + } + + public virtual Node Visit(FunctionNode node) + { + var transformedParameters = new List(); + var hasChanged = false; + + foreach (var parameter in node.Parameters) + { + var transformedParameter = parameter.Visit(this); + if (transformedParameter != parameter) hasChanged = true; + transformedParameters.Add(transformedParameter); + } + + if (!hasChanged) + { + return node; + } + + return new FunctionNode(node.FunctionName, transformedParameters.ToArray()); + } + } +} diff --git a/ThinkSharp.FormulaParser/Configuration.cs b/ThinkSharp.FormulaParser/Configuration.cs index b4b9dea..7c082c6 100644 --- a/ThinkSharp.FormulaParser/Configuration.cs +++ b/ThinkSharp.FormulaParser/Configuration.cs @@ -6,7 +6,7 @@ namespace ThinkSharp.FormulaParsing { - internal class Configuration : IConfigureFunctions, IConfigureConstants, IConfigureSupportedFeatures, IConfigureParsingBehavior, IConfiguration, IConfigurationEvaluator + internal class Configuration : IConfigureFunctions, IConfigureConstants, IConfigureSupportedFeatures, IConfigureValidationBehavior, IConfiguration, IConfigurationEvaluator { private static readonly Random random = new Random(); @@ -38,6 +38,7 @@ public Configuration() (this as IConfigureFunctions).Add("sin", u => Math.Sin(u)); (this as IConfigureFunctions).Add("cos", u => Math.Cos(u)); (this as IConfigureFunctions).Add("tan", u => Math.Tan(u)); + (this as IConfigureFunctions).Add("sqrt", u => Math.Sqrt(u)); (this as IConfigureConstants).Add("pi", Math.PI); (this as IConfigureConstants).Add("e", Math.E); @@ -60,6 +61,12 @@ public Configuration() public bool IsFunctionNameValidationDisabled { get; private set; } = false; + public bool IsBinaryNumberNotationSupportDisabled { get; private set; } = false; + + public bool IsHexadecimalNumberNotationSupportDisabled { get; private set; } = false; + + public bool IsOctalNumberNotationSupportDisabled { get; private set; } = false; + bool IConfiguration.HasFunction(string name, int argumentCount) { if (this.MatchFunction0To5(name, argumentCount)) @@ -75,6 +82,17 @@ bool IConfiguration.HasFunction(string name, int argumentCount) return false; } + bool IConfiguration.HasFunction(string name) + { + return this.functionsArgs0.ContainsKey(name) + || this.functionsArgs1.ContainsKey(name) + || this.functionsArgs2.ContainsKey(name) + || this.functionsArgs3.ContainsKey(name) + || this.functionsArgs4.ContainsKey(name) + || this.functionsArgs5.ContainsKey(name) + || this.functionsArgsN.ContainsKey(name); + } + private bool MatchFunction0To5(string name, int argumentCount) { switch (argumentCount) @@ -256,16 +274,19 @@ IEnumerable> IConfigurationEvaluator.EnumerateConst // //////////////////////////////////////////////////////////////////// void IConfigureSupportedFeatures.DisableScientificNotation() => this.IsScientificNotationSupportDisabled = true; + void IConfigureSupportedFeatures.DisableBinaryNumberNotation() => this.IsBinaryNumberNotationSupportDisabled = true; + void IConfigureSupportedFeatures.DisableHexadecimalNumberNotation() => this.IsHexadecimalNumberNotationSupportDisabled = true; + void IConfigureSupportedFeatures.DisableOctalNumberNotation() => this.IsOctalNumberNotationSupportDisabled = true; void IConfigureSupportedFeatures.DisableBracket() => this.IsBracketSupportDisabled = true; void IConfigureSupportedFeatures.DisablePow() => this.IsPowSupportDisabled = true; void IConfigureSupportedFeatures.DisableVariables() => this.IsVariablesSupportDisabled = true; void IConfigureSupportedFeatures.DisableFunctions() => this.IsFunctionsSupportDisabled = true; - // IConfigureParsingBehavior + // IConfigureValidationBehavior // //////////////////////////////////////////////////////////////////// - void IConfigureParsingBehavior.DisableVariableNameValidation() => this.IsVariableNameValidationDisabled = true; - void IConfigureParsingBehavior.DisableFunctionNameValidation() => this.IsFunctionNameValidationDisabled = true; + void IConfigureValidationBehavior.DisableVariableNameValidation() => this.IsVariableNameValidationDisabled = true; + void IConfigureValidationBehavior.DisableFunctionNameValidation() => this.IsFunctionNameValidationDisabled = true; // Helper // //////////////////////////////////////////////////////////////////// diff --git a/ThinkSharp.FormulaParser/FormulaParser.cs b/ThinkSharp.FormulaParser/FormulaParser.cs index 8fc18de..d6d458b 100644 --- a/ThinkSharp.FormulaParser/FormulaParser.cs +++ b/ThinkSharp.FormulaParser/FormulaParser.cs @@ -8,6 +8,11 @@ namespace ThinkSharp.FormulaParsing { + /// + /// The class provides static methods for creating instances. + /// Use the method to create a with default configuration. + /// Use the method to create a that allows to configure the instance. + /// public class FormulaParser : IFormulaParser { private readonly Configuration configuration; @@ -20,16 +25,33 @@ internal FormulaParser(Configuration configuration) this.configuration = configuration; } + /// + /// Creates a new with its default configuration. + /// + /// + /// A new with its default configuration. + /// public static IFormulaParser Create() => new FormulaParser(); + /// + /// Creates a that allows to configure the . + /// + /// + /// a . + /// public static IFormulaParserBuilder CreateBuilder() => new FormulaParserBuilder(); + /// + /// Gets the configuration for the parser. + /// + public IConfiguration Configuration => this.configuration; + public FormulaParserResult Evaluate(string formula) { return this.Evaluate(formula, null); } - public FormulaParserResult Evaluate(string formula, IDictionary variables) + public FormulaParserResult Evaluate(string formula, IReadOnlyDictionary variables) { return WrapWithExceptionHandling(() => { @@ -46,7 +68,7 @@ public FormulaParserResult Evaluate(Node formulaNode) return this.Evaluate(formulaNode, null); } - public FormulaParserResult Evaluate(Node formulaNode, IDictionary variables) + public FormulaParserResult Evaluate(Node formulaNode, IReadOnlyDictionary variables) { return WrapWithExceptionHandling(() => { @@ -59,7 +81,7 @@ public FormulaParserResult Evaluate(Node formulaNode, IDictionary Parse(string formula) => this.Parse(formula, null); - public FormulaParserResult Parse(string formula, IDictionary variables) + public FormulaParserResult Parse(string formula, IReadOnlyDictionary variables) { return WrapWithExceptionHandling(() => { @@ -70,7 +92,7 @@ public FormulaParserResult Parse(string formula, IDictionary RunVisitor(string formula, INodeVisitor visitor) => RunVisitor(formula, visitor, null); - public FormulaParserResult RunVisitor(string formula, INodeVisitor visitor, IDictionary variables) + public FormulaParserResult RunVisitor(string formula, INodeVisitor visitor, IReadOnlyDictionary variables) { return WrapWithExceptionHandling(() => { @@ -114,10 +136,9 @@ private static FormulaParserResult WrapWithExceptionHandling(F { return new FormulaParserResult(new Error(ex.Message)); } - } - private Node ParseFormula(string formula, IDictionary variables) + private Node ParseFormula(string formula, IReadOnlyDictionary variables) { var inputStream = new AntlrInputStream(formula); var lexer = new FormulaGrammerLexer(inputStream); diff --git a/ThinkSharp.FormulaParser/FormulaParserBuilder.cs b/ThinkSharp.FormulaParser/FormulaParserBuilder.cs index 1f4b1d3..6510a9c 100644 --- a/ThinkSharp.FormulaParser/FormulaParserBuilder.cs +++ b/ThinkSharp.FormulaParser/FormulaParserBuilder.cs @@ -21,7 +21,7 @@ public IFormulaParser Build() public IFormulaParserBuilder ConfigureSupportedFeatures(Action supportedFeatures) => Configure(supportedFeatures); - public IFormulaParserBuilder ConfigureParsingBehavior(Action parsingBehavior) => Configure(parsingBehavior); + public IFormulaParserBuilder ConfigureValidationBehavior(Action parsingBehavior) => Configure(parsingBehavior); private IFormulaParserBuilder Configure(Action action) where TConfigure : class { diff --git a/ThinkSharp.FormulaParser/FormulaParserResult.cs b/ThinkSharp.FormulaParser/FormulaParserResult.cs index 55fdbc7..4449c6a 100644 --- a/ThinkSharp.FormulaParser/FormulaParserResult.cs +++ b/ThinkSharp.FormulaParser/FormulaParserResult.cs @@ -45,5 +45,52 @@ private void EnsureResultHasNoErrors() Environment.NewLine + this.Error); } } + + public TResult HandleError(Func onError) + { + if (onError == null) throw new ArgumentNullException(nameof(onError)); + + if (this.Success) + { + return Value; + } + else + { + throw onError(this.Error); + } + } + + public bool Handle(Action onSuccess, Action onError) + { + if (onSuccess == null) throw new ArgumentNullException(nameof(onSuccess)); + if (onError == null) throw new ArgumentNullException(nameof(onError)); + + if (this.Success) + { + onSuccess(this.Value); + return true; + } + else + { + onError(this.Error); + return false; + } + } + + public bool Handle(Func onSuccess, Action onError) + { + if (onSuccess == null) throw new ArgumentNullException(nameof(onSuccess)); + if (onError == null) throw new ArgumentNullException(nameof(onError)); + + if (this.Success) + { + return onSuccess(this.Value); + } + else + { + onError(this.Error); + return false; + } + } } } diff --git a/ThinkSharp.FormulaParser/IConfiguration.cs b/ThinkSharp.FormulaParser/IConfiguration.cs index 9a18aeb..10ca6cc 100644 --- a/ThinkSharp.FormulaParser/IConfiguration.cs +++ b/ThinkSharp.FormulaParser/IConfiguration.cs @@ -6,10 +6,16 @@ namespace ThinkSharp.FormulaParsing { - internal interface IConfiguration + public interface IConfiguration { bool IsScientificNotationSupportDisabled { get; } + bool IsBinaryNumberNotationSupportDisabled { get; } + + bool IsHexadecimalNumberNotationSupportDisabled { get; } + + bool IsOctalNumberNotationSupportDisabled { get; } + bool IsBracketSupportDisabled { get; } bool IsPowSupportDisabled { get; } @@ -22,6 +28,8 @@ internal interface IConfiguration bool IsFunctionNameValidationDisabled { get; } + bool HasFunction(string name); + bool HasFunction(string name, int argumentCount); bool HasConstant(string name); diff --git a/ThinkSharp.FormulaParser/IConfigureConstants.cs b/ThinkSharp.FormulaParser/IConfigureConstants.cs index a4810c4..b8cc88f 100644 --- a/ThinkSharp.FormulaParser/IConfigureConstants.cs +++ b/ThinkSharp.FormulaParser/IConfigureConstants.cs @@ -6,12 +6,33 @@ namespace ThinkSharp.FormulaParsing { + /// + /// Interface encapsulating the API for configuring constants. + /// public interface IConfigureConstants { + /// + /// Adds a constant. + /// + /// + /// The name of the constant to add. + /// + /// + /// The value of the constant. + /// void Add(string name, double value); + /// + /// Removes all configured contants. + /// void RemoveAll(); + /// + /// Removes the constant with the specified name. + /// + /// + /// The name of the constant to remove. + /// void Remove(string name); } } diff --git a/ThinkSharp.FormulaParser/IConfigureFunctions.cs b/ThinkSharp.FormulaParser/IConfigureFunctions.cs index e9021cb..9f30103 100644 --- a/ThinkSharp.FormulaParser/IConfigureFunctions.cs +++ b/ThinkSharp.FormulaParser/IConfigureFunctions.cs @@ -6,24 +6,99 @@ namespace ThinkSharp.FormulaParsing { + /// + /// Interface encapsulating the API for configuring functions. + /// public interface IConfigureFunctions { + /// + /// Adds a function with zero parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with one paramteter. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with two parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with three parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with four parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with five parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Adds a function with 2 to n parameters. + /// + /// + /// The name of the function. + /// + /// + /// The function. + /// void Add(string name, Func function); + /// + /// Removes all configured functions. + /// void RemoveAll(); + /// + /// Removes the function with the specified name. + /// + /// + /// The name of the function to remove. + /// void Remove(string name); } } diff --git a/ThinkSharp.FormulaParser/IConfigureParsingBehavior.cs b/ThinkSharp.FormulaParser/IConfigureParsingBehavior.cs deleted file mode 100644 index 3168243..0000000 --- a/ThinkSharp.FormulaParser/IConfigureParsingBehavior.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace ThinkSharp.FormulaParsing -{ - public interface IConfigureParsingBehavior - { - void DisableVariableNameValidation(); - - void DisableFunctionNameValidation(); - } -} diff --git a/ThinkSharp.FormulaParser/IConfigureSupportedFeatures.cs b/ThinkSharp.FormulaParser/IConfigureSupportedFeatures.cs index 32b1883..779aa9b 100644 --- a/ThinkSharp.FormulaParser/IConfigureSupportedFeatures.cs +++ b/ThinkSharp.FormulaParser/IConfigureSupportedFeatures.cs @@ -1,15 +1,48 @@ namespace ThinkSharp.FormulaParsing { + /// + /// Interface encapsulating the API for configuring supported features. + /// public interface IConfigureSupportedFeatures { + /// + /// Prevents the usage of scientific notation (e.g. 2e3 = 4000) + /// void DisableScientificNotation(); + /// + /// Prevents the usage of binary notation (e.g. 0b101 = 5) + /// + void DisableBinaryNumberNotation(); + + /// + /// Prevents the usage of hexadecimal notation (e.g. 0x20 = 32) + /// + void DisableHexadecimalNumberNotation(); + + /// + /// Prevents the usage of octal notation (e.g. 0o10 = 8) + /// + void DisableOctalNumberNotation(); + + /// + /// Prevents the usage of brackets. + /// void DisableBracket(); + /// + /// Prevents the usage of pow (e.g. 3^2 = 9) + /// void DisablePow(); + /// + /// Ptevents the usage of variables. + /// void DisableVariables(); + /// + /// Prevents the usage of functions. + /// void DisableFunctions(); } } diff --git a/ThinkSharp.FormulaParser/IConfigureValidationBehavior.cs b/ThinkSharp.FormulaParser/IConfigureValidationBehavior.cs new file mode 100644 index 0000000..7f25b45 --- /dev/null +++ b/ThinkSharp.FormulaParser/IConfigureValidationBehavior.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ThinkSharp.FormulaParsing +{ + /// + /// Interface encapsulating the API for configuring validation behavior. + /// + public interface IConfigureValidationBehavior + { + /// + /// Diables the validation of variable names when creating a parsing tree. + /// + void DisableVariableNameValidation(); + + /// + /// Diables the validation of functions names when creating a parsing tree. + /// + void DisableFunctionNameValidation(); + } +} diff --git a/ThinkSharp.FormulaParser/IFormulaParser.cs b/ThinkSharp.FormulaParser/IFormulaParser.cs index 3b4c909..f6c07ac 100644 --- a/ThinkSharp.FormulaParser/IFormulaParser.cs +++ b/ThinkSharp.FormulaParser/IFormulaParser.cs @@ -10,22 +10,138 @@ namespace ThinkSharp.FormulaParsing { public interface IFormulaParser { + /// + /// Gets the configuration for the parser. + /// + IConfiguration Configuration { get; } + + /// + /// Evaluates the provided formula to a numeric value. + /// + /// + /// The formula to evaluate. + /// + /// + /// The object that contains the evaluation result or an error. + /// FormulaParserResult Evaluate(string formula); - FormulaParserResult Evaluate(string formula, IDictionary variables); + /// + /// Evaluates the provided formula to a numeric value. + /// + /// + /// The formula to evaluate. + /// + /// + /// A dictionary that provides variables to be used for evaluation. + /// + /// + /// The object that contains the evaluation result or an error. + /// + FormulaParserResult Evaluate(string formula, IReadOnlyDictionary variables); + /// + /// Evaluates the provided . + /// + /// + /// The root node of the parsing tree to evaluate. + /// + /// + /// The object that contains the evaluation result or an error. + /// FormulaParserResult Evaluate(Node formulaNode); - FormulaParserResult Evaluate(Node formulaNode, IDictionary variables); + /// + /// Evaluates the provided . + /// + /// + /// The root node of the parsing tree to evaluate. + /// + /// + /// A dictionary that provides variables to be used for evaluation. + /// + /// + /// The object that contains the evaluation result or an error. + /// + FormulaParserResult Evaluate(Node formulaNode, IReadOnlyDictionary variables); + /// + /// Parses the provided formula to a parsing tree. + /// + /// + /// The formula to parse. + /// + /// + /// The object that contains the root node of the parsing tree or an error. + /// FormulaParserResult Parse(string formula); - FormulaParserResult Parse(string formula, IDictionary variables); + /// + /// Parses the provided formula to a parsing tree. + /// + /// + /// The formula to parse. + /// + /// + /// A dictionary that provides variables to be used for evaluation. + /// + /// + /// The object that contains the root node of the parsing tree or an error. + /// + FormulaParserResult Parse(string formula, IReadOnlyDictionary variables); + /// + /// Parses the formula and executes the visitor to the genereted parsing tree. + /// + /// + /// The type of the visitors result. + /// + /// + /// The formula to parse. + /// + /// + /// The visitor to run on the parsing tree. + /// + /// + /// The object that contains the result produced by the visitor or an error. + /// FormulaParserResult RunVisitor(string formula, INodeVisitor visitor); - FormulaParserResult RunVisitor(string formula, INodeVisitor visitor, IDictionary variables); + /// + /// Parses the formula and executes the visitor to the genereted parsing tree. + /// + /// + /// The type of the visitors result. + /// + /// + /// The formula to parse. + /// + /// + /// The visitor to run on the parsing tree. + /// + /// + /// A dictionary that provides variables to be used for evaluation. + /// + /// + /// The object that contains the result produced by the visitor or an error. + /// + FormulaParserResult RunVisitor(string formula, INodeVisitor visitor, IReadOnlyDictionary variables); + /// + /// Executes the visitor to the provided parsing tree. + /// + /// + /// The type of the visitors result. + /// + /// + /// The root node of the parsing tree to run the visitor on. + /// + /// + /// The visitor to run on the parsing tree. + /// + /// + /// The object that contains the result produced by the visitor or an error. + /// FormulaParserResult RunVisitor(Node node, INodeVisitor visitor); } } diff --git a/ThinkSharp.FormulaParser/IFormulaParserBuilder.cs b/ThinkSharp.FormulaParser/IFormulaParserBuilder.cs index ffa7d0d..4115863 100644 --- a/ThinkSharp.FormulaParser/IFormulaParserBuilder.cs +++ b/ThinkSharp.FormulaParser/IFormulaParserBuilder.cs @@ -8,14 +8,61 @@ namespace ThinkSharp.FormulaParsing { public interface IFormulaParserBuilder { + /// + /// Allows to configure functions of the . + /// + /// + /// The object that provides methods for configuring functions of the formula parser. + /// + /// + /// The . + /// IFormulaParserBuilder ConfigureFunctions(Action functions); + /// + /// Allows to configure constants of the . + /// + /// + /// The object that provides methods for configuring constants of the formula parser. + /// + /// + /// The . + /// IFormulaParserBuilder ConfigureConstats(Action constants); + /// + /// Allows to disable features of the . + /// + /// + /// The object that provides methods for disabling features of the formula parser. + /// + /// + /// The . + /// IFormulaParserBuilder ConfigureSupportedFeatures(Action supportedFeatures); - IFormulaParserBuilder ConfigureParsingBehavior(Action parsingBehavior); + /// + /// Allows to configure the validation behavior of the . + /// + /// + /// The default behavior is, that names of configured functions / provided variables are required. If the formula contains unknown + /// functions / variables, the parsing process fails with an appropriated error message. + /// This method allows to disable validation for variables / functions which may be useful for creating a parsing tree. + /// + /// + /// The object that provides methods for disabling features of the formula parser. + /// + /// + /// The . + /// + IFormulaParserBuilder ConfigureValidationBehavior(Action parsingBehavior); + /// + /// Build the configured . + /// + /// + /// The configured . + /// IFormulaParser Build(); } } diff --git a/ThinkSharp.FormulaParser/ParserConfiguration.cs b/ThinkSharp.FormulaParser/ParserConfiguration.cs index 070fc93..92e839f 100644 --- a/ThinkSharp.FormulaParser/ParserConfiguration.cs +++ b/ThinkSharp.FormulaParser/ParserConfiguration.cs @@ -11,7 +11,7 @@ internal class ParserConfiguration : IParserConfiguration private readonly IConfiguration configuration; private readonly HashSet varialeNames; - public ParserConfiguration(IConfiguration configuration, IDictionary variables) + public ParserConfiguration(IConfiguration configuration, IReadOnlyDictionary variables) { this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); this.varialeNames = new HashSet(variables?.Keys ?? Enumerable.Empty()); @@ -31,10 +31,18 @@ public ParserConfiguration(IConfiguration configuration, IDictionary this.configuration.IsFunctionNameValidationDisabled; + public bool IsBinaryNumberNotationSupportDisabled => this.configuration.IsBinaryNumberNotationSupportDisabled; + + public bool IsHexadecimalNumberNotationSupportDisabled => this.configuration.IsHexadecimalNumberNotationSupportDisabled; + + public bool IsOctalNumberNotationSupportDisabled => this.configuration.IsOctalNumberNotationSupportDisabled; + public bool HasConstant(string name) => this.configuration.HasConstant(name); public bool HasFunction(string name, int argumentCount) => this.configuration.HasFunction(name, argumentCount); + public bool HasFunction(string name) => this.configuration.HasFunction(name); + public bool HasVariable(string variable) => this.varialeNames.Contains(variable); } } diff --git a/ThinkSharp.FormulaParser/ParsingException.cs b/ThinkSharp.FormulaParser/ParsingException.cs index f8efa50..d37233c 100644 --- a/ThinkSharp.FormulaParser/ParsingException.cs +++ b/ThinkSharp.FormulaParser/ParsingException.cs @@ -27,8 +27,12 @@ private ParsingException(int line, int column, string invalidToken, string messa internal static void ThrowInvalidTokenException(IToken token) => ThrowException(token.Line, token.Column, token.Text, $"Invalid token '{token.Text}'."); + internal static void ThrowInvalidScientificNumberException(IToken token) => ThrowException(token.Line, token.Column, token.Text, $"Invalid scientific number: '{token.Text}'."); + internal static void ThrowUnknownFunctionException(IToken token) => ThrowException(token.Line, token.Column, token.Text, $"Unknown function '{token.Text}'."); + internal static void ThrowFunctionArgumentCountDoesNotExistException(IToken token, int argumentCount) => ThrowException(token.Line, token.Column, token.Text, $"There is no function '{token.Text}' that takes {argumentCount} argument(s)."); + internal static void ThrowUnknownVariableException(IToken token) => ThrowException(token.Line, token.Column, token.Text, $"Unknown variable '{token.Text}'."); } } diff --git a/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.csproj b/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.csproj index 6e2806e..b556f14 100644 --- a/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.csproj +++ b/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.csproj @@ -8,15 +8,21 @@ Jan-Niklas Schäfer ThinkSharp A formula parser with fluent API that allows parsing and evaluation of mathematically formulas. Features: functions, constants, variables, scientific numbers, focus on customization and flexibility. - © 2019 Jan-Niklas Schäfer - 0.1.0.0 - 0.1.0.0 + © 2020-2024 Jan-Niklas Schäfer + 0.10.0.0 + 0.10.0.0 LICENSE.txt - 0.1 Initial Version + Removed term rewriting functionality (has been moved to its own project) + 0.10.0 Bugfix: decimal parsing should not depend on OS Culture https://github.com/JanDotNet/ThinkSharp.FormulaParser true - 0.1.0 + 0.10.0 + README.md + + + + C:\Users\Tachy\Projects\ThinkSharp\ThinkSharp.FormulaParser\ThinkSharp.FormulaParser\ThinkSharp.FormulaParser.xml @@ -27,10 +33,23 @@ True + + True + \ + + + + <_Parameter1>$(MSBuildProjectName).Test + + + <_Parameter1>$(MSBuildProjectName).TermRewriting + + + diff --git a/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.xml b/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.xml new file mode 100644 index 0000000..e897a6b --- /dev/null +++ b/ThinkSharp.FormulaParser/ThinkSharp.FormulaParser.xml @@ -0,0 +1,1263 @@ + + + + ThinkSharp.FormulaParser + + + + + The class provides static methods for creating instances. + Use the method to create a with default configuration. + Use the method to create a that allows to configure the instance. + + + + + Creates a new with its default configuration. + + + A new with its default configuration. + + + + + Creates a that allows to configure the . + + + a . + + + + + Gets the configuration for the parser. + + + + + Interface encapsulating the API for configuring constants. + + + + + Adds a constant. + + + The name of the constant to add. + + + The value of the constant. + + + + + Removes all configured contants. + + + + + Removes the constant with the specified name. + + + The name of the constant to remove. + + + + + Interface encapsulating the API for configuring functions. + + + + + Adds a function with zero parameters. + + + The name of the function. + + + The function. + + + + + Adds a function with one paramteter. + + + The name of the function. + + + The function. + + + + + Adds a function with two parameters. + + + The name of the function. + + + The function. + + + + + Adds a function with three parameters. + + + The name of the function. + + + The function. + + + + + Adds a function with four parameters. + + + The name of the function. + + + The function. + + + + + Adds a function with five parameters. + + + The name of the function. + + + The function. + + + + + Adds a function with 2 to n parameters. + + + The name of the function. + + + The function. + + + + + Removes all configured functions. + + + + + Removes the function with the specified name. + + + The name of the function to remove. + + + + + Interface encapsulating the API for configuring supported features. + + + + + Prevents the usage of scientific notation (e.g. 2e3 = 4000) + + + + + Prevents the usage of binary notation (e.g. 0b101 = 5) + + + + + Prevents the usage of hexadecimal notation (e.g. 0x20 = 32) + + + + + Prevents the usage of octal notation (e.g. 0o10 = 8) + + + + + Prevents the usage of brackets. + + + + + Prevents the usage of pow (e.g. 3^2 = 9) + + + + + Ptevents the usage of variables. + + + + + Prevents the usage of functions. + + + + + Interface encapsulating the API for configuring validation behavior. + + + + + Diables the validation of variable names when creating a parsing tree. + + + + + Diables the validation of functions names when creating a parsing tree. + + + + + Gets the configuration for the parser. + + + + + Evaluates the provided formula to a numeric value. + + + The formula to evaluate. + + + The object that contains the evaluation result or an error. + + + + + Evaluates the provided formula to a numeric value. + + + The formula to evaluate. + + + A dictionary that provides variables to be used for evaluation. + + + The object that contains the evaluation result or an error. + + + + + Evaluates the provided . + + + The root node of the parsing tree to evaluate. + + + The object that contains the evaluation result or an error. + + + + + Evaluates the provided . + + + The root node of the parsing tree to evaluate. + + + A dictionary that provides variables to be used for evaluation. + + + The object that contains the evaluation result or an error. + + + + + Parses the provided formula to a parsing tree. + + + The formula to parse. + + + The object that contains the root node of the parsing tree or an error. + + + + + Parses the provided formula to a parsing tree. + + + The formula to parse. + + + A dictionary that provides variables to be used for evaluation. + + + The object that contains the root node of the parsing tree or an error. + + + + + Parses the formula and executes the visitor to the genereted parsing tree. + + + The type of the visitors result. + + + The formula to parse. + + + The visitor to run on the parsing tree. + + + The object that contains the result produced by the visitor or an error. + + + + + Parses the formula and executes the visitor to the genereted parsing tree. + + + The type of the visitors result. + + + The formula to parse. + + + The visitor to run on the parsing tree. + + + A dictionary that provides variables to be used for evaluation. + + + The object that contains the result produced by the visitor or an error. + + + + + Executes the visitor to the provided parsing tree. + + + The type of the visitors result. + + + The root node of the parsing tree to run the visitor on. + + + The visitor to run on the parsing tree. + + + The object that contains the result produced by the visitor or an error. + + + + + Allows to configure functions of the . + + + The object that provides methods for configuring functions of the formula parser. + + + The . + + + + + Allows to configure constants of the . + + + The object that provides methods for configuring constants of the formula parser. + + + The . + + + + + Allows to disable features of the . + + + The object that provides methods for disabling features of the formula parser. + + + The . + + + + + Allows to configure the validation behavior of the . + + + The default behavior is, that names of configured functions / provided variables are required. If the formula contains unknown + functions / variables, the parsing process fails with an appropriated error message. + This method allows to disable validation for variables / functions which may be useful for creating a parsing tree. + + + The object that provides methods for disabling features of the formula parser. + + + The . + + + + + Build the configured . + + + The configured . + + + + + This class provides an empty implementation of , + which can be extended to create a listener which only needs to handle a subset + of the available methods. + + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PlusAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PlusAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the NegativeAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the NegativeAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the UnsignedAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the UnsignedAtom + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the DecimalNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the DecimalNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the IntgerNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the IntgerNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PrefixedDecNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PrefixedDecNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PrefixedIntNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PrefixedIntNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PrefixedBinNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PrefixedBinNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PrefixedOctNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PrefixedOctNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by the PrefixedHexNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by the PrefixedHexNumber + labeled alternative in . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Enter a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + Exit a parse tree produced by . + The default implementation does nothing. + + The parse tree. + + + + The default implementation does nothing. + + + + The default implementation does nothing. + + + + The default implementation does nothing. + + + + The default implementation does nothing. + + + + This class provides an empty implementation of , + which can be extended to create a visitor which only needs to handle a subset + of the available methods. + + The return type of the visit operation. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PlusAtom + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the NegativeAtom + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the UnsignedAtom + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the DecimalNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the IntgerNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedDecNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedIntNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedBinNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedOctNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedHexNumber + labeled alternative in . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The default implementation returns the result of calling + on . + + + The parse tree. + The visitor result. + + + + This interface defines a complete listener for a parse tree produced by + . + + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by the PlusAtom + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PlusAtom + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the NegativeAtom + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the NegativeAtom + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the UnsignedAtom + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the UnsignedAtom + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by the DecimalNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the DecimalNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the IntgerNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the IntgerNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the PrefixedDecNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PrefixedDecNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the PrefixedIntNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PrefixedIntNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the PrefixedBinNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PrefixedBinNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the PrefixedOctNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PrefixedOctNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by the PrefixedHexNumber + labeled alternative in . + + The parse tree. + + + + Exit a parse tree produced by the PrefixedHexNumber + labeled alternative in . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + Enter a parse tree produced by . + + The parse tree. + + + + Exit a parse tree produced by . + + The parse tree. + + + + This interface defines a complete generic visitor for a parse tree produced + by . + + The return type of the visit operation. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PlusAtom + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the NegativeAtom + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the UnsignedAtom + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the DecimalNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the IntgerNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedDecNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedIntNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedBinNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedOctNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by the PrefixedHexNumber + labeled alternative in . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + + Visit a parse tree produced by . + + The parse tree. + The visitor result. + + + diff --git a/ThinkSharp.FormulaParser/Validation/ValidationHelper.cs b/ThinkSharp.FormulaParser/Validation/ValidationHelper.cs new file mode 100644 index 0000000..0983032 --- /dev/null +++ b/ThinkSharp.FormulaParser/Validation/ValidationHelper.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; + +namespace ThinkSharp.FormulaParsing.Validation +{ + public static class ValidationHelper + { + private static Regex variableRegex = new Regex("[a-zA-Z$_][a-zA-Z0-9$_]*", RegexOptions.Compiled); + + public static bool IsValidIdentifier(string name) => variableRegex.IsMatch(name); + } +}