コード例 #1
0
        /// <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);
        }
コード例 #2
0
        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;
        }
コード例 #3
0
        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;
        }
コード例 #4
0
        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;
        }
コード例 #5
0
        /// <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);
            }
        }
コード例 #6
0
        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;
        }
コード例 #7
0
        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;
        }
コード例 #8
0
        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;
        }
コード例 #9
0
        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);
        }
コード例 #10
0
 public void TryParseTests(Operators expected, string input)
 {
     Assert.IsTrue(OperatorsHelper.TryParse(input, out var op));
     Assert.AreEqual(expected, op);
 }