// // Main entry point for parser. // You pass in the expression you want to parse, and you get an // ExpressionTree out the back end. // internal GenericExpressionNode Parse(string expression, ParserOptions optionSettings, ElementLocation elementLocation) { // We currently have no support (and no scenarios) for disallowing property references // in Conditions. ErrorUtilities.VerifyThrow(0 != (optionSettings & ParserOptions.AllowProperties), "Properties should always be allowed."); _options = optionSettings; _elementLocation = elementLocation; _lexer = new Scanner(expression, _options); if (!_lexer.Advance()) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound); } GenericExpressionNode node = Expr(expression); if (!_lexer.IsNext(Token.TokenType.EndOfInput)) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } return(node); }
private GenericExpressionNode BooleanTermPrime(string expression, GenericExpressionNode lhs) { if (_lexer.IsNext(Token.TokenType.EndOfInput)) { return(lhs); } else if (Same(expression, Token.TokenType.And)) { GenericExpressionNode rhs = RelationalExpr(expression); if (null == rhs) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } OperatorExpressionNode andNode = new AndExpressionNode(); andNode.LeftChild = lhs; andNode.RightChild = rhs; return(BooleanTermPrime(expression, andNode)); } else { // Should this be error case? return(lhs); } }
// // Top node of grammar // See grammar for how the following methods relate to each // other. // private GenericExpressionNode Expr(string expression) { GenericExpressionNode node = BooleanTerm(expression); if (!_lexer.IsNext(Token.TokenType.EndOfInput)) { node = ExprPrime(expression, node); } #region REMOVE_COMPAT_WARNING // Check for potential change in behavior if (LoggingServices != null && !_warnedForExpression && node.PotentialAndOrConflict()) { // We only want to warn once even if there multiple () sub expressions _warnedForExpression = true; // Log a warning regarding the fact the expression may have been evaluated // incorrectly in earlier version of MSBuild LoggingServices.LogWarning(_logBuildEventContext, null, new BuildEventFileInfo(_elementLocation), "ConditionMaybeEvaluatedIncorrectly", expression); } #endregion return(node); }
/// <summary> /// Expands properties and items in the argument, and verifies that the result is consistent /// with a scalar parameter type. /// </summary> /// <param name="function">Function name for errors</param> /// <param name="argumentNode">Argument to be expanded</param> /// <param name="state"></param> /// <param name="isFilePath">True if this is afile name and the path should be normalized</param> /// <returns>Scalar result</returns> private static string ExpandArgumentForScalarParameter(string function, GenericExpressionNode argumentNode, ConditionEvaluator.IConditionEvaluationState state, bool isFilePath = true) { string argument = argumentNode.GetUnexpandedValue(state); // Fix path before expansion if (isFilePath) { argument = FileUtilities.FixFilePath(argument); } IList <TaskItem> items = state.ExpandIntoTaskItems(argument); string expandedValue = String.Empty; if (items.Count == 0) { // Empty argument, that's fine. } else if (items.Count == 1) { expandedValue = items[0].ItemSpec; } else // too many items for the function { // We only allow a single item to be passed into a scalar parameter. ProjectErrorUtilities.ThrowInvalidProject( state.ElementLocation, "CannotPassMultipleItemsIntoScalarFunction", function, argument, state.ExpandIntoString(argument)); } return(expandedValue); }
private void Args(string expression, List <GenericExpressionNode> arglist) { GenericExpressionNode arg = Arg(expression); arglist.Add(arg); if (Same(expression, Token.TokenType.Comma)) { Args(expression, arglist); } }
private GenericExpressionNode BooleanTerm(string expression) { GenericExpressionNode node = RelationalExpr(expression); if (null == node) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } if (!_lexer.IsNext(Token.TokenType.EndOfInput)) { node = BooleanTermPrime(expression, node); } return(node); }
private GenericExpressionNode RelationalExpr(string expression) { { GenericExpressionNode lhs = Factor(expression); if (null == lhs) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } OperatorExpressionNode node = RelationalOperation(expression); if (node == null) { return(lhs); } GenericExpressionNode rhs = Factor(expression); node.LeftChild = lhs; node.RightChild = rhs; return(node); } }
private GenericExpressionNode ExprPrime(string expression, GenericExpressionNode lhs) { if (Same(expression, Token.TokenType.EndOfInput)) { return(lhs); } else if (Same(expression, Token.TokenType.Or)) { OperatorExpressionNode orNode = new OrExpressionNode(); GenericExpressionNode rhs = BooleanTerm(expression); orNode.LeftChild = lhs; orNode.RightChild = rhs; return(ExprPrime(expression, orNode)); } else { // I think this is ok. ExprPrime always shows up at // the rightmost side of the grammar rhs, the EndOfInput case // takes care of things return(lhs); } }
private List <string> ExpandArgumentAsFileList(GenericExpressionNode argumentNode, ConditionEvaluator.IConditionEvaluationState state, bool isFilePath = true) { string argument = argumentNode.GetUnexpandedValue(state); // Fix path before expansion if (isFilePath) { argument = FileUtilities.FixFilePath(argument); } IList <TaskItem> expanded = state.ExpandIntoTaskItems(argument); var expandedCount = expanded.Count; if (expandedCount == 0) { return(null); } var list = new List <string>(capacity: expandedCount); for (var i = 0; i < expandedCount; i++) { var item = expanded[i]; if (state.EvaluationDirectory != null && !Path.IsPathRooted(item.ItemSpec)) { list.Add(Path.GetFullPath(Path.Combine(state.EvaluationDirectory, item.ItemSpec))); } else { list.Add(item.ItemSpec); } } return(list); }
private GenericExpressionNode Factor(string expression) { // Checks for TokenTypes String, Numeric, Property, ItemMetadata, and ItemList. GenericExpressionNode arg = this.Arg(expression); // If it's one of those, return it. if (arg != null) { return(arg); } // If it's not one of those, check for other TokenTypes. Token current = _lexer.CurrentToken; if (Same(expression, Token.TokenType.Function)) { if (!Same(expression, Token.TokenType.LeftParenthesis)) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", _lexer.IsNextString(), errorPosition); return(null); } var arglist = new List <GenericExpressionNode>(); Arglist(expression, arglist); if (!Same(expression, Token.TokenType.RightParenthesis)) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); return(null); } return(new FunctionCallExpressionNode(current.String, arglist)); } else if (Same(expression, Token.TokenType.LeftParenthesis)) { GenericExpressionNode child = Expr(expression); if (Same(expression, Token.TokenType.RightParenthesis)) { return(child); } else { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } } else if (Same(expression, Token.TokenType.Not)) { OperatorExpressionNode notNode = new NotExpressionNode(); GenericExpressionNode expr = Factor(expression); if (expr == null) { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } notNode.LeftChild = expr; return(notNode); } else { errorPosition = _lexer.GetErrorPosition(); ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, "UnexpectedTokenInCondition", expression, _lexer.IsNextString(), errorPosition); } return(null); }