private ParseErrorType HandleOperator(ParseContext context, IAstNode parent, out bool isUnary) { ParseErrorType errorType = ParseErrorType.None; // If operands stack is empty the operator is unary. // If operator is preceded by another operator, // it is interpreted as unary. TokenOperator currentOperator = new TokenOperator(_operands.Count == 0); currentOperator.Parse(context, null); isUnary = currentOperator.IsUnary; IOperator lastOperator = _operators.Peek(); if (isUnary && lastOperator != null && lastOperator.IsUnary) { // !!!x is treated as !(!(!x))) // Step back and re-parse as expression context.Tokens.Position -= 1; var exp = new Expression(inGroup: false); if (exp.Parse(context, null)) { _operands.Push(exp); return ParseErrorType.None; } } if (currentOperator.Precedence <= lastOperator.Precedence && !(currentOperator.OperatorType == lastOperator.OperatorType && currentOperator.Association == Association.Right)) { // New operator has lower or equal precedence. We need to make a tree from // the topmost operator and its operand(s). Example: a*b+c. + has lower priority // and a and b should be on the stack along with * on the operator stack. // Repeat until there are no more higher precendece operators on the stack. errorType = this.ProcessHigherPrecendenceOperators(context, currentOperator); } if (errorType == ParseErrorType.None) { _operators.Push(currentOperator); } return errorType; }
private ParseErrorType HandleOperator(ParseContext context, IAstNode parent, out bool isUnary) { TokenOperator currentOperator = new TokenOperator(firstInExpression: (_operands.Count == 0)); currentOperator.Parse(context, null); isUnary = currentOperator.IsUnary; return HandleOperatorPrecedence(context, currentOperator); }