public decimal Calculate(string str) { ShuntingYard sy = new ShuntingYard(); PostFixEvaluator pfe = new PostFixEvaluator(); return(Math.Round(pfe.Evaluate(sy.InfixToPostfix(str)), 2)); }
static void SetupParser() { Lexer = new Lex(); Lexer.Rules.Add(LexRule.SpaceSkipper); Lexer.Rules.Add(new LexRule(LexPatterns.Float, typeof(double), Kinds.Value)); foreach (string op in @"\+ \- \* \/ \( \) ! ,".Split(' ')) { Lexer.Rules.Add(new LexRule(op, typeof(string), Kinds.Operator)); } Lexer.Rules.Add(new LexRule(LexPatterns.Identifier, typeof(string), Kinds.Identifier)); SY = new ShuntingYard(); SY.Grammar.Add(new GrammarRule("+", Kinds.Operator, GrammarTokenType.Operator, 2, GrammarTokenAssociativity.Left)); SY.Grammar.Add(new GrammarRule("-", Kinds.Operator, GrammarTokenType.Operator, 2, GrammarTokenAssociativity.Left)); SY.Grammar.Add(new GrammarRule("*", Kinds.Operator, GrammarTokenType.Operator, 3, GrammarTokenAssociativity.Left)); SY.Grammar.Add(new GrammarRule("/", Kinds.Operator, GrammarTokenType.Operator, 3, GrammarTokenAssociativity.Left)); SY.Grammar.Add(new GrammarRule("!", Kinds.Operator, GrammarTokenType.Operator, 1, GrammarTokenAssociativity.Left)); SY.Grammar.Add(new GrammarRule(null, Kinds.Value, GrammarTokenType.Value, 0, GrammarTokenAssociativity.None)); SY.Grammar.Add(new GrammarRule(null, Kinds.Identifier, GrammarTokenType.Function, 0, GrammarTokenAssociativity.None)); SY.Grammar.Add(new GrammarRule("(", Kinds.Operator, GrammarTokenType.LeftParenthesis, 0, GrammarTokenAssociativity.None)); SY.Grammar.Add(new GrammarRule(")", Kinds.Operator, GrammarTokenType.RightParenthesis, 0, GrammarTokenAssociativity.None)); SY.Grammar.Add(new GrammarRule(",", Kinds.Operator, GrammarTokenType.Separator, 0, GrammarTokenAssociativity.None)); }
private void AssertInfixConvertsToExpected(string infix, string[] expected) { var split = Utilities.Split(infix); var result = ShuntingYard.GetRPNAsArrayFromString(split); Assert.That(expected, Is.EqualTo(result)); }
public void AdvancedShuntTest() { var yard = new ShuntingYard(new Symbol[] { new Operand(3), new Operator("+", Operators.Addition, 2), new Operand(4), new Operator("*", Operators.Multiplication, 3), new Operand(2), new Operator("/", Operators.Division, 3), new Operator("(", Operators.OpenBracket, 0), new Operand(1), new Operator("-", Operators.Subtraction, 2), new Operand(5), new Operator(")", Operators.CloseBracket, 0), new Operator("^", Operators.Power, 4, true), new Operand(2), new Operator("^", Operators.Power, 4, true), new Operand(3) }); Assert.True(yard.ShuntValid); yard.Shunt(); Assert.IsEmpty(yard.OperatorStack); var expected = new Symbol[] { new Operand(3), new Operand(4), new Operand(2), new Operator("*", Operators.Multiplication, 3), new Operand(1), new Operand(5), new Operator("-", Operators.Subtraction, 2), new Operand(2), new Operand(3), new Operator("^", Operators.Power, 4, true), new Operator("^", Operators.Power, 4, true), new Operator("/", Operators.Division, 3), new Operator("+", Operators.Addition, 2) } .Select(s => s.ToString()); var actual = yard.Output .Select(s => s.ToString()); Assert.AreEqual(expected, actual); }
public void FunctionShuntTest() { // It'll be fun to see how it deals with Pi! var yard = new ShuntingYard(new Symbol[] { new Operator("sin", Operators.Function, 5), new Operator("(", Operators.OpenBracket, 0), new Operator("max", Operators.Function, 5), new Operator("(", Operators.OpenBracket, 0), new Operand(2), new Operand(3), new Operator(")", Operators.CloseBracket, 0), new Operator("/", Operators.Division, 3), new Operand(3), new Operator("*", Operators.Multiplication, 3), new Operand((float)Math.PI), new Operator(")", Operators.CloseBracket, 0) }); Assert.True(yard.ShuntValid); yard.Shunt(); Assert.IsEmpty(yard.OperatorStack); var expected = new Symbol[] { new Operand(2), new Operand(3), new Operator("max", Operators.Function, 5), new Operand(3), new Operator("/", Operators.Division, 3), new Operand((float)Math.PI), new Operator("*", Operators.Multiplication, 3), new Operator("sin", Operators.Function, 5) } .Select(s => s.ToString()); var actual = yard.Output .Select(s => s.ToString()); Assert.AreEqual(expected, actual); }
public void Parse_CheckRightAssociative_ReturnBool() { ShuntingYard.CheckRightAssociativeAndPrecedence("^", "-").Should().BeFalse(); ShuntingYard.CheckRightAssociativeAndPrecedence("^", "*").Should().BeFalse(); ShuntingYard.CheckRightAssociativeAndPrecedence("^", "+").Should().BeFalse(); ShuntingYard.CheckRightAssociativeAndPrecedence("^", "/").Should().BeFalse(); }
static void Main(string[] args) { // Just for fun - coloring the console text :-) WriteColorLine(ConsoleColor.Cyan, "Exercise_2_1_2\n"); // Example from exercise WriteColor(ConsoleColor.Green, "5 1 2 + 4 * + 3 - "); Console.Write("= "); WriteColorLine(ConsoleColor.Red, ReversePolishCalculator.Compute("5 1 2 + 4 * + 3 -")); // Example from https://en.wikipedia.org/wiki/Shunting-yard_algorithm WriteColor(ConsoleColor.Green, "3 + 4 * 2 / (1 - 5) ^ 2 ^ 3 "); Console.Write("= "); WriteColorLine(ConsoleColor.Red, ReversePolishCalculator.Compute(ShuntingYard.Parse("3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"))); Console.WriteLine("\nThe correct answer if we had used real numbers (doubles instead of integers) would be:"); WriteColor(ConsoleColor.Green, "3 + 4 * 2 / (1 - 5) ^ 2 ^ 3 "); Console.Write("= "); var result = 3.0 + ((4.0 * 2.0) / Math.Pow((1.0 - 5.0), Math.Pow(2.0, 3.0))); WriteColorLine(ConsoleColor.Red, result.ToString(CultureInfo.InvariantCulture)); // the use of CultureInfo.InvariantCulture prevent formatting of numbers using the // systems format, ie. for me the Danish format with a comma instead of a dot: 3,0001220703125 }
public static double EvaluateInfix(string infixString) { var resultStack = new Stack <double>(); var postfixQueue = ShuntingYard.GetPostfixQueue(infixString); while (postfixQueue.Any()) { var currentToken = postfixQueue.Dequeue(); if (Token.IsNumber(currentToken)) { resultStack.Push(double.Parse(currentToken)); continue; } if (Token.IsOperator(currentToken)) { var val1 = resultStack.Pop(); var val2 = resultStack.Pop(); var output = Token.Evaluate(val2, val1, currentToken); resultStack.Push(output); continue; } if (Token.IsFunction(currentToken)) { var value = resultStack.Pop(); var result = Token.Evaluate(value, currentToken); resultStack.Push(result); } } return(resultStack.Pop()); }
public void NoMatchingRParenProducesError() { const string expression = "1+(2+3"; Result <string> result = ShuntingYard.InfixToPostfixStr(expression); Assert.IsFalse(result.HasValue); Assert.True(result.ErrorMessage.StartsWith("No matching right parenthesis")); }
public void TestMethodDivision() { string input = "8 / 2"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 4); }
public void TestMethodMultiplication() { string input = "8 * 2"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 16); }
public void TestMethod_5() { string input = "( 2 - 2 )"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 0); }
public void TestInfixIncorrectInput(string input, int count) { var operators = new OperatorList().Operators; var result = new ShuntingYard().CreateReversePolishNotation(input, operators); Assert.Equal(count, result.Result.Count); Assert.NotEmpty(result.Error); }
public void TestMethod() { string input = "2 + 2 * 2 / 2 - 2"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 2); }
public void TestMethodSubtraction() { string input = "8 - 2"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 6); }
public void TestMethod_1() { string input = "( 2 + 2 ) * ( 2 - 6 ) + 7"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, -9); }
public void TestMethodAddition() { string input = "8 + 2"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, 10); }
public void TestMethod_6() { string input = "7 - 16"; double output = 0; ShuntingYard s = new ShuntingYard(input, ref output); Assert.AreEqual(output, -9); }
public MathCompilerEBNF() { var parser = new EBNFGrammarParserCustom(50); var definition = new MathEBNFGrammarDefinition(); var startSymbol = parser.Parse(definition); this.grammarCompiler = new MathEBNFGrammarCompiler(startSymbol); shuntingYard = new ShuntingYard(); }
public void TestInfixTrial() { var input = "2^2-1+3/2*7"; var operators = new OperatorList().Operators; var result = new ShuntingYard().CreateReversePolishNotation(input, operators); //Assert.Equal(count, result.Result.Count); Assert.Empty(result.Error); }
public void ParseTest() { var yard = new ShuntingYard("3 + 4 / 6 ( 12 * 75 ) - 3"); IEnumerable <string> expected = new[] { "3", "+", "4", "/", "6", "(", "12", "*", "75", ")", "-", "3" }; var actual = yard.Input.Select(s => s.ToString()); Assert.AreEqual(expected, actual); }
static void Main(string[] args) { string input = "( -2 + 2 ) * ( 2 - 6 )"; double output = 0; Console.WriteLine($"input: {input}\n"); ShuntingYard s = new ShuntingYard(input, ref output); Console.WriteLine($"output: {output}\n"); Console.ReadKey(); }
public void CanProducePostfixNotation() { const string expression = "3 + 4 * 2 / ( 1 - 5 ) ^ 2 ^ 3"; Result <string> result = ShuntingYard.InfixToPostfixStr(expression); if (!result.HasValue) { Debug.LogError("ShuntingYard.InfixToPostfix(" + expression + ") Error: " + result.ErrorMessage); } Assert.True(result.HasValue); Assert.AreEqual("3 4 2 * 1 5 - 2 3 ^ ^ / +", result.Value); }
public void CanProducePostfixNotationWithFunction() { const string expression = "sin(max(2, 3) / 3 * 3.1415)"; Result <string> result = ShuntingYard.InfixToPostfixStr(expression); if (!result.HasValue) { Debug.LogError("ShuntingYard.InfixToPostfix(" + expression + ") Error: " + result.ErrorMessage); } Assert.True(result.HasValue); Assert.AreEqual("2 3 max 3 / 3.1415 * sin", result.Value); }
private static void Calculate() { Console.WriteLine("Enter expression to calculate:"); string input = Console.ReadLine(); List <string> convertFromInfixToPostfix = ShuntingYard.Convert(input); Console.WriteLine("\nExpression in postfix: {0}", string.Join(" ", convertFromInfixToPostfix)); double result = RpnAlgorithm.Calculate(convertFromInfixToPostfix); Console.WriteLine("\nResult = {0}", result); }
/// <summary> /// Called from button wired through the Unity inspector /// </summary> public void Evaluate() { Result <string> shuntingYardResult = ShuntingYard.InfixToPostfixStr(InputField.text); RpnField.text = shuntingYardResult.HasValue ? shuntingYardResult.Value : "<error>"; Result <Expression <Func <double> > > rpnExpTreeResult = rpnEvaluator.TryEvaluateToExpressionTree(InputField.text); RpnExpressionTreeField.text = rpnExpTreeResult.HasValue ? rpnExpTreeResult.Value.ToString() : "<error>"; Result <Expression <Func <double> > > combinatorExpTreeResult = combinatorEvaluator.TryEvaluateToExpressionTree(InputField.text); CombinatorExpressionTreeField.text = combinatorExpTreeResult.HasValue ? combinatorExpTreeResult.Value.ToString() : "<error>"; Result <double> rpnResult = rpnEvaluator.TryEvaluate(InputField.text); if (!rpnResult.HasValue) { RpnErrorsField.text = rpnResult.ErrorMessage; RpnResultField.text = "<error>"; } else { RpnErrorsField.text = string.Empty; RpnResultField.text = rpnResult.Value.ToString(CultureInfo.InvariantCulture); } Result <double> combinatorResult = combinatorEvaluator.TryEvaluate(InputField.text); if (!combinatorResult.HasValue) { CombinatorErrorsField.text = combinatorResult.ErrorMessage; CombinatorResultField.text = "<error>"; } else { CombinatorErrorsField.text = string.Empty; CombinatorResultField.text = combinatorResult.Value.ToString(CultureInfo.InvariantCulture); } InputField.ActivateInputField(); }
void HandleMessage(IQueryMsg e) { var expr = VerifiedExpression.Parse(e.Message, CalcEnv); // Only automatically calculate if the expression is legitimate and if it's reasonable to assume it's meant // to be a calculation (not just a single number). A minimal calculation will involve at least 3 tokens: // `number operator number`. const int minTokenCount = 3; if (expr.Success && expr.Expression.Count >= minTokenCount) { double result = ShuntingYard.Calculate(expr); e.Reply(result.ToString()); } }
public void ShouldEvaluateTheExpressionCorrectly(string input, double expectedOutput) { // ARRANGE input = Helper.RemoveWhiteSpace(input: input); IShuntingYard sy = new ShuntingYard(input: input); sy.ConvertToPostfix(); // ACT double output = sy.Evaluate(); // ASSERT Assert.Equal(expectedOutput, output); }
public void ShouldDisplayTheCorrectPostfixNotation(string input, string expectedOutput) { // ARRANGE input = Helper.RemoveWhiteSpace(input: input); IShuntingYard sy = new ShuntingYard(input: input); sy.ConvertToPostfix(); // ACT string output = Helper.ConvertToString(input: sy.GetPostfix()); // ASSERT Assert.Equal(expectedOutput, output); }
public void BasicShuntTest() { var yard = new ShuntingYard(new Symbol[] { new Operand(3), new Operator("+", Operators.Addition, 2), new Operand(4) }); Assert.True(yard.ShuntValid); yard.Shunt(); Assert.IsEmpty(yard.OperatorStack); var expected = new Symbol[] { new Operand(3), new Operand(4), new Operator("+", Operators.Addition, 2) } .Select(s => s.ToString()); var actual = yard.Output .Select(s => s.ToString()); Assert.AreEqual(expected, actual); }