/// <summary> /// Performs the shunting-yard algorithm on an input to convert from infix to postfix notation /// </summary> /// <param name="input">String input in infix notation</param> /// <returns>Queue of elements in postfix notation</returns> public static Queue <Element> SYA(string input) { List <string> tokens = ParseInput(input).ToList(); Stack <Operator> opStack = new(); Queue <Element> outQueue = new(); foreach (string token in tokens) { //if the token is a number, simply add to queue if (double.TryParse(token, out double number)) { outQueue.Enqueue(new Value(number)); } //if the token is an operator else if (OperatorsHelper.TryParse(token, out Operators op) && op != Operators.LeftBracket && op != Operators.RightBracket) { //move operators from operator stack to output queue while the top element in operator stack has greater precedence while (opStack.Count > 0 && opStack.Peek().Precedence() > op.Precedence()) { outQueue.Enqueue(opStack.Pop()); } //once all operators of greater precedence gone, add operator to operator queue opStack.Push(new Operator(op)); } //if the operator is a left bracket, just push onto opstack else if (op == Operators.LeftBracket) { opStack.Push(new Operator(op)); } //if right bracket, move operators from opstack to outqueue until left bracket is found //then discard both left and right bracket else if (op == Operators.RightBracket) { while (opStack.Peek().Op != Operators.LeftBracket) { outQueue.Enqueue(opStack.Pop()); } opStack.Pop(); } //otherwise, assume it's a variable else { outQueue.Enqueue(new Variable(token)); } } //once all tokens are done, move all operators over to output queue while (opStack.Count > 0) { outQueue.Enqueue(opStack.Pop()); } return(outQueue); }
private void ProcessCallingFunction() { _lastIsOperator = null; _context.Recovery(_currToken); var parser = new CallingFunctionExpressionParser(_context); parser.Run(); var node = parser.Result; #if DEBUG //Log($"node = {node}"); #endif var priority = OperatorsHelper.GetPriority(KindOfOperator.CallFunction); #if DEBUG //Log($"priority = {priority}"); #endif var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.UnaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); _state = State.Init; }
private void ProcessUnaryOperator(KindOfOperatorOfLogicalQueryNode kindOfOperator) { var node = new LogicalQueryNode(); _lastLogicalQueryNode = node; node.Kind = KindOfLogicalQueryNode.UnaryOperator; node.KindOfOperator = kindOfOperator; var kind = KindOfOperator.Unknown; switch (kindOfOperator) { case KindOfOperatorOfLogicalQueryNode.Not: kind = KindOfOperator.Not; break; default: throw new ArgumentOutOfRangeException(nameof(kindOfOperator), kindOfOperator, null); } var priority = OperatorsHelper.GetPriority(kind); #if DEBUG //Log($"priority = {priority}"); #endif var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.UnaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); _state = State.GotOperator; }
private void ProcessIsOperator() { var node = new BinaryOperatorAstExpression(); node.KindOfOperator = KindOfOperator.Is; _lastIsOperator = node; var priority = OperatorsHelper.GetPriority(node.KindOfOperator); var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.BinaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); _state = State.Init; }
/// <inheritdoc/> string IObjectToDbgString.PropertiesToDbgString(uint n) { var spaces = DisplayHelper.Spaces(n); switch (OperationCode) { case OperationCode.Nop: case OperationCode.ClearStack: case OperationCode.Return: case OperationCode.ReturnVal: case OperationCode.UseInheritance: case OperationCode.UseNotInheritance: case OperationCode.Error: case OperationCode.RemoveSEHGroup: return($"{spaces}{OperationCode}"); case OperationCode.PushVal: case OperationCode.PushValFromVar: case OperationCode.PushValToVar: return($"{spaces}{OperationCode} {Value.ToDbgString()}"); case OperationCode.CallUnOp: case OperationCode.CallBinOp: return($"{spaces}{OperationCode} {OperatorsHelper.GetSymbol(KindOfOperator)}"); case OperationCode.AllocateAnonymousWaypoint: case OperationCode.AllocateNamedWaypoint: return($"{spaces}{OperationCode} {CountParams}"); case OperationCode.Call: case OperationCode.Call_N: case OperationCode.Call_P: case OperationCode.AsyncCall: case OperationCode.AsyncCall_N: case OperationCode.AsyncCall_P: return($"{spaces}{OperationCode} {CountParams}"); case OperationCode.SetSEHGroup: case OperationCode.JumpTo: return($"{spaces}{OperationCode} {TargetPosition}"); default: throw new ArgumentOutOfRangeException(nameof(OperationCode), OperationCode, null); } }
private void ProcessUsualBinaryOperator(KindOfOperator kindOfOperator) { _lastIsOperator = null; var node = new BinaryOperatorAstExpression(); node.KindOfOperator = kindOfOperator; var priority = OperatorsHelper.GetPriority(kindOfOperator); #if DEBUG //Log($"priority = {priority}"); #endif var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.BinaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); _state = State.Init; }
private void ProcessPredicate(StrongIdentifierValue name) { var node = new LogicalQueryNode(); _lastLogicalQueryNode = node; node.Kind = KindOfLogicalQueryNode.Relation; node.Name = name; node.ParamsList = new List <LogicalQueryNode>(); var priority = OperatorsHelper.GetPriority(KindOfOperator.Predicate); #if DEBUG //Log($"priority = {priority}"); #endif var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.UnaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); _state = State.WaitForPredicateParameter; }
private void ProcessLogicalQueryOperator() { _lastIsOperator = null; //_context.Recovery(_currToken); var parser = new LogicalQueryOperationParser(_context); parser.Run(); var resultItem = parser.Result; #if DEBUG //Log($"resultItem = {resultItem}"); #endif var node = new UnaryOperatorAstExpression(); node.KindOfOperator = KindOfOperator.CallLogicalQuery; var priority = OperatorsHelper.GetPriority(node.KindOfOperator); #if DEBUG //Log($"priority = {priority}"); #endif var intermediateNode = new IntermediateAstNode(node, KindOfIntermediateAstNode.UnaryOperator, priority); AstNodesLinker.SetNode(intermediateNode, _nodePoint); var valueNode = new ConstValueAstExpression(); valueNode.Value = resultItem; var valueIntermediateNode = new IntermediateAstNode(valueNode); AstNodesLinker.SetNode(valueIntermediateNode, _nodePoint); _state = State.GotCallLogicalQueryOperator; }
public void ComputeTests(double expected, string input, double xValue = 0) { Queue <Element> elements = new(); foreach (string token in input.Split(' ')) { if (double.TryParse(token, out double number)) { elements.Enqueue(new Value(number)); } else if (OperatorsHelper.TryParse(token, out Operators op)) { elements.Enqueue(new Operator(op)); } else { elements.Enqueue(new Variable(token)); } } double value = RPN.Compute(elements, ("x", xValue)); Assert.AreEqual(expected, value, 1e-6); }
public void TryParseTests(Operators expected, string input) { Assert.IsTrue(OperatorsHelper.TryParse(input, out var op)); Assert.AreEqual(expected, op); }