public UnknownOperationException(Operator op):base(op.ToString()) { }
/// <summary> Here's where the good stuff happens... /// /// 1. If we get an open parenthesis or open bracket, then we push it. /// 2. If we get a close parenthesis or close bracket, the we pop the stack /// growing our tree, until we find an open parenthesis or open bracket. /// The type must match, e.g. if we are processing a close parenthesis /// but encounter an open bracket, that indicates a syntax error in the /// expression, and we throw an exception. /// 3. If our op has lower precedence then the current TOS op /// we grow the tree and repeat (3). /// /// Note we are using a trick, whereby the opType constants /// are number in order of precedence (that is lower precedence /// = lower numeric value). The exception to this rule is /// the open parenthesis which is highest precedence but is /// lowest numerically. This is to allow (3) to work correctly, /// since we want to make sure that a open parenthesis only gets /// popped by a close parenthesis. /// </summary> private void addOp(Operator opType) { if (opType == Operator.OPEN_PAREN) { m_opStack.Push(opType); } else if (opType == Operator.OPEN_BRACKET) { // This is tricky: for an array index, e.g. "a[k]", we treat it // like "a SUBSCRIPT k". So first we push SUBSCRIPT, and // then we push the open-bracket op. addOp(Operator.SUBSCRIPT); // recursive call m_opStack.Push(opType); } else if (opType == Operator.CLOSE_PAREN || opType == Operator.CLOSE_BRACKET) { Operator openingOpType; if (opType == Operator.CLOSE_PAREN) openingOpType = Operator.OPEN_PAREN; else openingOpType = Operator.OPEN_BRACKET; while (m_opStack.Peek() != Operator.OPEN_PAREN && m_opStack.Peek() != Operator.OPEN_BRACKET) { popOperation(); } // If we saw "(x]" or "[x)", then indicate a syntax error if (m_opStack.Peek() != openingOpType) throw new ParseException(LocalizationManager.getLocalizedTextString("key1"), m_parsePos); //$NON-NLS-1$ popOperation(); // pop the "(" or "[" } else { while (m_opStack.Count != 0 && ((Operator)m_opStack.Peek()).precedence >= opType.precedence) popOperation(); m_opStack.Push(opType); } }