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); } }
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); } }
/// <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); } }
/// <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); }
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); } }
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(); }