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