bool IfTagOption::TryParseExpression(ParserContext& context) { Token* token, * lhsToken = NULL, * rhsToken = NULL, * unaryToken = NULL; ConditionalOperator conditionalOperator; UnaryOperator unaryOperator = UnaryAnd; // Evaluate the expressions do { // Get the LHS token if (!context.TryNext(token)) { context.Error.Description = "unexpected end of file while parsing condition"; return false; } // Ensure the type of the LHS if (!IsValidFragment(token)) return context.Error.Set(token, "invalid left hand side of expression: " + token->Value); // Save the LHS token lhsToken = token; // Get the operator token if (!context.TryNext(token)) return context.Error.Set(token, "unexpected end of file while parsing condition"); // Check the type if (token->Type & TokenOperator) { // Check the operator if (token->Value == "==") conditionalOperator = ConditionalEquals; else if ((token->Value == "!=") || (token->Value == "<>")) conditionalOperator = ConditionalNotEquals; else if (token->Value == ">") conditionalOperator = ConditionalGreaterThan; else if (token->Value == "<") conditionalOperator = ConditionalLessThan; else if (token->Value == ">=") conditionalOperator = ConditionalGreaterThanOrEquals; else if (token->Value == "<=") conditionalOperator = ConditionalLessThanOrEquals; else return context.Error.Set(token, "invalid expression operator: " + token->Value); // Get the RHS token if (!context.TryNext(token)) return context.Error.Set(token, "unexpected end of file while parsing condition"); // Check the type if (!IsValidFragment(token)) return context.Error.Set(token, "invalid right hand side of expression: " + token->Value); // Store the RHS token rhsToken = token; // Try to get the unary operator if (!context.TryNext(token)) return context.Error.Set(token, "unexpected end of file while parsing condition"); } else conditionalOperator = ConditionalImplicit; // Evaluate the unary operator if (token->Type & TokenIdentifier) { // Ensure that this is a unary operator if (token->Value == "and") unaryOperator = UnaryAnd; else if (token->Value == "or") unaryOperator = UnaryOr; else return context.Error.Set(token, "invalid unary operator: " + token->Value); // Store the unary operator token unaryToken = token; } else unaryToken = NULL; // Construct the condition Condition* condition = new Condition(lhsToken, conditionalOperator, rhsToken); if (this->_rootCondition) condition->Attach(this->_rootCondition, unaryOperator); this->_rootCondition = condition; // Reset the stored tokens lhsToken = NULL; rhsToken = NULL; } while (unaryToken != NULL); // Ensure that this is a closing tag if (!(token->Type & TokenTagClose)) return context.Error.Set(token, "expected end of tag but got " + token->Value); // Done return true; }