示例#1
0
 private bool ParseNumeric(int start)
 {
     if ((_expression.Length - _parsePoint) > 2 && _expression[_parsePoint] == '0' && (_expression[_parsePoint + 1] == 'x' || _expression[_parsePoint + 1] == 'X'))
     {
         // Hex number
         _parsePoint += 2;
         SkipHexDigits();
         _lookahead = new Token(Token.TokenType.Numeric, _expression.Substring(start, _parsePoint - start));
     }
     else if (CharacterUtilities.IsNumberStart(_expression[_parsePoint]))
     {
         // Decimal number
         if (_expression[_parsePoint] == '+')
         {
             _parsePoint++;
         }
         else if (_expression[_parsePoint] == '-')
         {
             _parsePoint++;
         }
         do
         {
             SkipDigits();
             if (_parsePoint < _expression.Length && _expression[_parsePoint] == '.')
             {
                 _parsePoint++;
             }
             if (_parsePoint < _expression.Length)
             {
                 SkipDigits();
             }
         } while (_parsePoint < _expression.Length && _expression[_parsePoint] == '.');
         // Do we need to error on malformed input like 0.00.00)? or will the conversion handle it?
         // For now, let the conversion generate the error.
         _lookahead = new Token(Token.TokenType.Numeric, _expression.Substring(start, _parsePoint - start));
     }
     else
     {
         // Unreachable
         _errorState = true;
         _errorPosition = start + 1;
         return false;
     }
     return true;
 }
示例#2
0
 internal bool IsNext(Token.TokenType type)
 {
     return _lookahead.IsToken(type);
 }
示例#3
0
        /// <summary>
        /// Parse any part of the conditional expression that is quoted. It may contain a property, item, or 
        /// metadata element that needs expansion during evaluation.
        /// </summary>
        private bool ParseQuotedString()
        {
            _parsePoint++;
            int start = _parsePoint;
            bool expandable = false;
            while (_parsePoint < _expression.Length && _expression[_parsePoint] != '\'')
            {
                // Standalone percent-sign must be allowed within a condition because it's
                // needed to escape special characters.  However, percent-sign followed
                // by open-parenthesis is an indication of an item metadata reference, and
                // that is only allowed in certain contexts.
                if ((_expression[_parsePoint] == '%') && ((_parsePoint + 1) < _expression.Length) && (_expression[_parsePoint + 1] == '('))
                {
                    expandable = true;
                    string name = String.Empty;

                    int endOfName = _expression.IndexOf(')', _parsePoint) - 1;
                    if (endOfName < 0)
                    {
                        endOfName = _expression.Length - 1;
                    }

                    // If it's %(a.b) the name is just 'b'
                    if (_parsePoint + 3 < _expression.Length)
                    {
                        name = _expression.Substring(_parsePoint + 2, (endOfName - _parsePoint - 2 + 1));
                    }

                    if (!CheckForUnexpectedMetadata(name))
                    {
                        return false;
                    }
                }
                else if (_expression[_parsePoint] == '@' && ((_parsePoint + 1) < _expression.Length) && (_expression[_parsePoint + 1] == '('))
                {
                    expandable = true;

                    // If the caller specified that he DOESN'T want to allow item lists ...
                    if ((_options & ParserOptions.AllowItemLists) == 0)
                    {
                        _errorPosition = start + 1;
                        _errorState = true;
                        _errorResource = "ItemListNotAllowedInThisConditional";
                        return false;
                    }

                    // Item lists have to be parsed because of the replacement syntax e.g. @(Foo,'_').
                    // I have to know how to parse those so I can skip over the tic marks.  I don't
                    // have to do that with other things like propertygroups, hence itemlists are
                    // treated specially.

                    ParseInternalItemList();
                    continue;
                }
                else if (_expression[_parsePoint] == '$' && ((_parsePoint + 1) < _expression.Length) && (_expression[_parsePoint + 1] == '('))
                {
                    expandable = true;
                }
                else if (_expression[_parsePoint] == '%')
                {
                    // There may be some escaped characters in the expression
                    expandable = true;
                }
                _parsePoint++;
            }

            if (_parsePoint >= _expression.Length)
            {
                // Quoted string wasn't closed
                _errorState = true;
                _errorPosition = start; // The message is going to say "expected after position n" so don't add 1 here.
                _errorResource = "IllFormedQuotedStringInCondition";
                // Not useful to set unexpectedlyFound here. By definition it got to the end of the string.
                return false;
            }
            string originalTokenString = _expression.Substring(start, _parsePoint - start);

            _lookahead = new Token(Token.TokenType.String, originalTokenString, expandable);
            _parsePoint++;
            return true;
        }
示例#4
0
 // There is a bug here that spaces are not required around 'and' and 'or'. For example,
 // this works perfectly well:
 // Condition="%(a.Identity)!=''and%(a.m)=='1'"
 // Since people now depend on this behavior, we must not change it.
 private bool ParseSimpleStringOrFunction(int start)
 {
     SkipSimpleStringChars();
     if (0 == string.Compare(_expression.Substring(start, _parsePoint - start), "and", StringComparison.OrdinalIgnoreCase))
     {
         _lookahead = Token.And;
     }
     else if (0 == string.Compare(_expression.Substring(start, _parsePoint - start), "or", StringComparison.OrdinalIgnoreCase))
     {
         _lookahead = Token.Or;
     }
     else
     {
         int end = _parsePoint;
         SkipWhiteSpace();
         if (_parsePoint < _expression.Length && _expression[_parsePoint] == '(')
         {
             _lookahead = new Token(Token.TokenType.Function, _expression.Substring(start, end - start));
         }
         else
         {
             string tokenValue = _expression.Substring(start, end - start);
             _lookahead = new Token(Token.TokenType.String, tokenValue);
         }
     }
     return true;
 }
示例#5
0
 private bool ParseItemList()
 {
     int start = _parsePoint;
     if (!ParseInternalItemList())
     {
         return false;
     }
     _lookahead = new Token(Token.TokenType.ItemList, _expression.Substring(start, _parsePoint - start));
     return true;
 }
示例#6
0
        /// <summary>
        /// Parses a string of the form %(itemmetadataname).
        /// </summary>
        /// <returns></returns>
        private bool ParseItemMetadata()
        {
            string itemMetadataExpression = this.ParsePropertyOrItemMetadata();

            if (itemMetadataExpression == null)
            {
                // The ParsePropertyOrItemMetadata method returns the correct error resources
                // for parsing properties such as $(propertyname).  At this stage in the Whidbey
                // cycle, we're not allowed to add new string resources, so I can't add a new
                // resource specific to item metadata, so here, we just change the error to
                // the generic "UnexpectedCharacter".
                _errorResource = "UnexpectedCharacterInCondition";
                return false;
            }

            _lookahead = new Token(Token.TokenType.ItemMetadata, itemMetadataExpression);

            if (!CheckForUnexpectedMetadata(itemMetadataExpression))
            {
                return false;
            }

            return true;
        }
示例#7
0
        /// <summary>
        /// Parses a string of the form $(propertyname).
        /// </summary>
        /// <returns></returns>
        private bool ParseProperty()
        {
            string propertyExpression = this.ParsePropertyOrItemMetadata();

            if (propertyExpression == null)
            {
                return false;
            }
            else
            {
                _lookahead = new Token(Token.TokenType.Property, propertyExpression);
                return true;
            }
        }
示例#8
0
        /// <summary>
        /// Advance
        /// returns true on successful advance
        ///     and false on an erroneous token
        ///
        /// Doesn't return error until the bogus input is encountered.
        /// Advance() returns true even after EndOfInput is encountered.
        /// </summary>
        internal bool Advance()
        {
            if (_errorState)
                return false;

            if (_lookahead != null && _lookahead.IsToken(Token.TokenType.EndOfInput))
                return true;

            SkipWhiteSpace();

            // Update error position after skipping whitespace
            _errorPosition = _parsePoint + 1;

            if (_parsePoint >= _expression.Length)
            {
                _lookahead = Token.EndOfInput;
            }
            else
            {
                switch (_expression[_parsePoint])
                {
                    case ',':
                        _lookahead = Token.Comma;
                        _parsePoint++;
                        break;
                    case '(':
                        _lookahead = Token.LeftParenthesis;
                        _parsePoint++;
                        break;
                    case ')':
                        _lookahead = Token.RightParenthesis;
                        _parsePoint++;
                        break;
                    case '$':
                        if (!ParseProperty())
                            return false;
                        break;
                    case '%':
                        if (!ParseItemMetadata())
                            return false;
                        break;
                    case '@':
                        int start = _parsePoint;
                        // If the caller specified that he DOESN'T want to allow item lists ...
                        if ((_options & ParserOptions.AllowItemLists) == 0)
                        {
                            if ((_parsePoint + 1) < _expression.Length && _expression[_parsePoint + 1] == '(')
                            {
                                _errorPosition = start + 1;
                                _errorState = true;
                                _errorResource = "ItemListNotAllowedInThisConditional";
                                return false;
                            }
                        }
                        if (!ParseItemList())
                            return false;
                        break;
                    case '!':
                        // negation and not-equal
                        if ((_parsePoint + 1) < _expression.Length && _expression[_parsePoint + 1] == '=')
                        {
                            _lookahead = Token.NotEqualTo;
                            _parsePoint += 2;
                        }
                        else
                        {
                            _lookahead = Token.Not;
                            _parsePoint++;
                        }
                        break;
                    case '>':
                        // gt and gte
                        if ((_parsePoint + 1) < _expression.Length && _expression[_parsePoint + 1] == '=')
                        {
                            _lookahead = Token.GreaterThanOrEqualTo;
                            _parsePoint += 2;
                        }
                        else
                        {
                            _lookahead = Token.GreaterThan;
                            _parsePoint++;
                        }
                        break;
                    case '<':
                        // lt and lte
                        if ((_parsePoint + 1) < _expression.Length && _expression[_parsePoint + 1] == '=')
                        {
                            _lookahead = Token.LessThanOrEqualTo;
                            _parsePoint += 2;
                        }
                        else
                        {
                            _lookahead = Token.LessThan;
                            _parsePoint++;
                        }
                        break;
                    case '=':
                        if ((_parsePoint + 1) < _expression.Length && _expression[_parsePoint + 1] == '=')
                        {
                            _lookahead = Token.EqualTo;
                            _parsePoint += 2;
                        }
                        else
                        {
                            _errorPosition = _parsePoint + 2; // expression[parsePoint + 1], counting from 1
                            _errorResource = "IllFormedEqualsInCondition";
                            if ((_parsePoint + 1) < _expression.Length)
                            {
                                // store the char we found instead
                                _unexpectedlyFound = Convert.ToString(_expression[_parsePoint + 1], CultureInfo.InvariantCulture);
                            }
                            else
                            {
                                _unexpectedlyFound = EndOfInput;
                            }
                            _parsePoint++;
                            _errorState = true;
                            return false;
                        }
                        break;
                    case '\'':
                        if (!ParseQuotedString())
                            return false;
                        break;
                    default:
                        // Simple strings, function calls, decimal numbers, hex numbers
                        if (!ParseRemaining())
                            return false;
                        break;
                }
            }
            return true;
        }
示例#9
0
 private bool Same(string expression, Token.TokenType token)
 {
     if (_lexer.IsNext(token))
     {
         if (!_lexer.Advance())
         {
             errorPosition = _lexer.GetErrorPosition();
             if (null != _lexer.UnexpectedlyFound)
             {
                 ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, _lexer.GetErrorResource(), expression, errorPosition, _lexer.UnexpectedlyFound);
             }
             else
             {
                 ProjectErrorUtilities.VerifyThrowInvalidProject(false, _elementLocation, _lexer.GetErrorResource(), expression, errorPosition);
             }
         }
         return true;
     }
     else
     {
         return false;
     }
 }