private void SetTopOperatorRightContext(object rightContext)
        {
            int leftPrecedence = ops.Top.LeftPrecedence;

            ops.Top.RightContext = rightContext;
            if (ops.Top.LeftPrecedence > leftPrecedence)
            {
                ConstraintOperator constraintOperator = ops.Pop();
                ReduceOperatorStack(constraintOperator.LeftPrecedence);
                ops.Push(constraintOperator);
            }
        }
示例#2
0
 public void Push(Token p_token)
 {
     //push in operator/ operand stack
     if (p_token is Operator)
     {
         //operatorStack.
         if (operatorStack.Count == 0 || (operatorStack.Count > 0 && operatorStack.Peek().Priority < (p_token as Operator).Priority))
         {
             //do remaining operation
             operatorStack.Push(p_token as Operator);
         }
         else
         {
             List <Token> args = new List <Token>();
             for (int i = 0; i < 2; i++) //as these all are binary operators
             {
                 args.Insert(0, LiteralStack.Pop());
             }
             Token tkn = OperatorStack.Pop().Evalute(args);
             LiteralStack.Push(tkn as Literal);
             OperatorStack.Push(p_token as Operator);
         }
     }
     else if (p_token is Literal)
     {
         LiteralStack.Push(p_token as Literal);
     }
 }
示例#3
0
        /// <summary>
        /// Sets the top operator right context.
        /// </summary>
        /// <param name="rightContext">The right context.</param>
        private void SetTopOperatorRightContext(object rightContext)
        {
            // Some operators change their precedence based on
            // the right context - save current precedence.
            int oldPrecedence = ops.Top.LeftPrecedence;

            ops.Top.RightContext = rightContext;

            // If the precedence increased, we may be able to
            // reduce the region of the stack below the operator
            if (ops.Top.LeftPrecedence > oldPrecedence)
            {
                ConstraintOperator changedOp = ops.Pop();
                ReduceOperatorStack(changedOp.LeftPrecedence);
                ops.Push(changedOp);
            }
        }
示例#4
0
        /// <summary>
        /// 要素登録
        /// </summary>
        /// <param name="pItem">要素</param>
        /// <remarks>
        /// CalculatorItemBaseクラスおよび派生クラスを登録します。
        /// 登録する順番は数式に準じます。
        /// </remarks>
        public void Entry(CalculatorItemBase pItem)
        {
            if (pItem is CalculatorValueBase)
            {
                this.mStackValue.Push((CalculatorValue)pItem);
                return;
            }

            CalculatorOperatorBase opeThis = (CalculatorOperatorBase)pItem;

            // (
            if (opeThis.OperatorType == CalculatorOperatorBase.EnumOperatorType.Open)
            {
                this.mStackOperator.Push(opeThis);
                return;
            }

            // )
            if (opeThis.OperatorType == CalculatorOperatorBase.EnumOperatorType.Close)
            {
                while (true)
                {
                    CalculatorOperatorBase ope = this.mStackOperator.Pop();
                    ope.Calculation(this.mStackValue);

                    if (ope.OperatorType == CalculatorOperatorBase.EnumOperatorType.Open)
                    {
                        break;
                    }
                }
                return;
            }

            if (mStackOperator.Count == 0)
            {
                this.mStackOperator.Push(opeThis);
                return;
            }

            CalculatorOperatorBase opeBefore = mStackOperator.Peek();

            int priority = opeBefore.ComparePriority(opeThis);

            if (priority < 0)
            {
                this.mStackOperator.Push(opeThis);
                return;
            }

            opeBefore.Calculation(this.mStackValue);
            mStackOperator.Pop();

            this.mStackOperator.Push(opeThis);
        }
示例#5
0
        private void BuildTree()
        {
            while (OperatorStack.Count != 0)
            {
                TreeNode <string> temp_root = OperatorStack.Pop();

                temp_root.Right = NumberStack.Pop();
                temp_root.Left  = NumberStack.Pop();

                temp_root = CheckPrecedence(temp_root);

                NumberStack.Push(temp_root);
            }
        }
示例#6
0
        internal string Summerize()
        {
            Token tkn = null;

            Operator     opt  = null;
            List <Token> args = null;

            for (int i = 0; OperatorStack.Count > 0; i++)
            {
                opt  = OperatorStack.Pop();
                args = new List <Token>();
                for (int j = 0; j < 2; j++) //as these all are binary operators
                {
                    args.Insert(0, LiteralStack.Pop());
                }
                tkn = opt.Evalute(args);
                LiteralStack.Push(tkn as Literal);
            }
            //opt = OperatorStack.Pop();

            return((tkn as Literal).Value.ToString());
        }
        /// <summary>
        /// Performs the Shunting-Yard Algorithm
        /// </summary>
        public void Shunt()
        {
            // O(n)

            if (!ShuntValid)
            {
                throw new Exception("Shunt() was called without proper initialisation. Check ShuntValid first!");
            }

            var working = new List <Symbol>();

            foreach (var symbol in Input)
            {
                if (symbol.GetType() == typeof(Operand))
                {
                    working.Add(symbol);                                      // Add any numbers straight to output
                }
                else if (symbol.ToString() != "(" && symbol.ToString() != ")")
                { // Operators
                    var op = (Operator)symbol;

                    // If function, Push() to stack and continue;
                    if (op.Op == Operators.Function)
                    {
                        OperatorStack.Push(op);
                        continue;
                    }

                    while ((OperatorStack.Count != 0 && // Stack not empty!
                            (OperatorStack.Peek().Precedence >
                             op.Precedence || // Top operator has higher precedence than current one
                             (OperatorStack.Peek().Precedence == op.Precedence && !OperatorStack.Peek().IsRightAssociative))
                            ) && // Top op has equal precendence and is left associative
                           OperatorStack.Peek().Op != Operators.OpenBracket)    // Top op is not opening bracket
                    {
                        working.Add(OperatorStack.Pop());
                    }

                    OperatorStack.Push(op); // Add operator to stack
                }
                else
                {
                    switch (symbol.ToString())
                    {
                    case "(": // Opening Bracket
                        OperatorStack.Push((Operator)symbol);
                        break;

                    case ")": // Closing Bracket
                    {
                        while (OperatorStack.Peek().Op != Operators.OpenBracket)
                        {
                            if (OperatorStack.Count == 0)
                            {
                                throw new Exception("Ran out of stack while looking for left bracket: input had mismatched brackets.");
                            }
                            working.Add(OperatorStack.Pop());
                        }

                        if (OperatorStack.Peek().Op == Operators.OpenBracket)
                        {
                            OperatorStack.Pop();                                                   // Discard extra brackets
                        }
                        break;
                    }
                    }
                }
            }

            working.AddRange(OperatorStack); // Final step: pop out entire stack to output
            OperatorStack.Clear();           // Apparently AddRange() will Peek() instead of Pop() if the stack only has one element, failing to clear it

            Output = working.ToArray();
        }