Example #1
0
        /// <summary>
        /// Parses a lexical token stream into an instance of the <see cref="UvssDocument"/> class.
        /// </summary>
        /// <param name="source">The source text.</param>
        /// <param name="tokens">The token stream to parse.</param>
        /// <returns>The new instance of <see cref="UvssDocument"/> that was created.</returns>
        public UvssDocument Parse(String source, IList<UvssLexerToken> tokens)
        {
            Contract.Require(source, "source");
            Contract.Require(tokens, "input");

            var state = new UvssParserState(source, tokens);

            var rules       = new List<UvssRule>();
            var rule        = default(UvssRule);
            var storyboards = new List<UvssStoryboard>();
            var storyboard  = default(UvssStoryboard);

            while (true)
            {
                if ((storyboard = ConsumeStoryboard(state)) != null)
                {
                    storyboards.Add(storyboard);
                    continue;
                }

                if ((rule = ConsumeRule(state)) != null)
                {
                    rules.Add(rule);
                    continue;
                }

                break;
            }

            return new UvssDocument(rules, storyboards);
        }
Example #2
0
        /// <summary>
        /// Gets the specified line of source code.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="line">The line of source code to retrieve.</param>
        /// <returns>The line of source code that was retrieved.</returns>
        private static String GetSourceLine(UvssParserState state, Int32 line)
        {
            var lineNumber  = state.CurrentToken.Line;
            var lineTokens  = state.Tokens.Where(x => !x.Value.StartsWith("\n") && x.Line == lineNumber);
            var errorLine   = String.Join(String.Empty, lineTokens.Select(x => x.Value)).Trim();

            return errorLine;
        }
Example #3
0
        /// <summary>
        /// Parses an Ultraviolet Style Sheet selector from the specified token stream.
        /// </summary>
        /// <param name="source">The source text.</param>
        /// <param name="tokens">The token stream to parse.</param>
        /// <returns>The new instance of <see cref="UvssSelector"/> that was created.</returns>
        public UvssSelector ParseSelector(String source, IList<UvssLexerToken> tokens)
        {
            Contract.Require(source, "source");
            Contract.Require(tokens, "input");

            var state = new UvssParserState(source, tokens);
            return ConsumeSelector(state, true);
        }
Example #4
0
        /// <summary>
        /// Throws an exception if the specified token does not match the specified parameters.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="token">The token to evaluate.</param>
        /// <param name="type">The desired token type.</param>
        /// <param name="value">The desired token value.</param>
        private static void MatchTokenOrFail(UvssParserState state, UvssLexerToken? token, UvssLexerTokenType type, String value = null)
        {
            if (token == null)
                ThrowUnexpectedEOF(state);

            if (token.Value.TokenType != type)
                ThrowExpectedToken(state, token.Value, type);

            if (value != null && !String.Equals(token.Value.Value, value, StringComparison.OrdinalIgnoreCase))
                ThrowExpectedValue(state, token.Value, value);
        }
Example #5
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS style list.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="styles">A <see cref="UvssStyleCollection"/> object representing the style list that was consumed.</param>
        /// <param name="triggers">A <see cref="UvssTriggerCollection"/> object representing the trigger list that was consumed.</param>
        private static void ConsumeStyleList(UvssParserState state, out UvssStyleCollection styles, out UvssTriggerCollection triggers)
        {
            state.AdvanceBeyondWhiteSpace();

            var styleListTokens = GetTokensBetweenCurlyBraces(state);
            var styleListState  = new UvssParserState(state.Source, styleListTokens);
            var tempStyles      = new List<UvssStyle>();
            var tempTriggers    = new List<Trigger>();

            while (ConsumeStyleOrTrigger(styleListState, tempStyles, tempTriggers))
            { }

            styles   = new UvssStyleCollection(tempStyles);
            triggers = new UvssTriggerCollection(tempTriggers);
        }
Example #6
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS selector part.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="allowEOF">A value indicating whether hitting the end of file is valid.</param>
        /// <param name="allowPseudoClass">A value indicating whether parts with pseduo classes are valid.</param>
        /// <param name="allowChild">A value indicating whether this selector part can be an immediate child.</param>
        /// <returns>A new <see cref="UvssSelectorPart"/> object representing the selector part that was consumed.</returns>
        private static UvssSelectorPart ConsumeSelectorPart(UvssParserState state, Boolean allowEOF, Boolean allowPseudoClass, Boolean allowChild)
        {
            var element = default(String);
            var id = default(String);
            var pseudoClass = default(String);
            var classes = new List<String>();
            var valid = false;
            var qualifier = UvssSelectorPartQualifier.None;
            var universal = false;
            var elementIsExact = false;

            while (true)
            {
                if (state.IsPastEndOfStream)
                {
                    if (allowEOF && (qualifier == UvssSelectorPartQualifier.None || valid))
                    {
                        break;
                    }
                    ThrowUnexpectedEOF(state);
                }

                var token = state.CurrentToken;

                if (token.TokenType == UvssLexerTokenType.WhiteSpace ||
                    token.TokenType == UvssLexerTokenType.Comma ||
                    token.TokenType == UvssLexerTokenType.OpenCurlyBrace ||
                    token.TokenType == UvssLexerTokenType.Pipe)
                {
                    if (qualifier != UvssSelectorPartQualifier.None && !valid)
                    {
                        ThrowUnexpectedToken(state, token);
                    }
                    break;
                }

                if (token.TokenType == UvssLexerTokenType.ChildSelector || token.TokenType == UvssLexerTokenType.LogicalChildSelector || token.TokenType == UvssLexerTokenType.TemplatedChildSelector)
                {
                    if (!allowChild)
                        ThrowUnexpectedToken(state, token);

                    switch (token.TokenType)
                    {
                        case UvssLexerTokenType.ChildSelector:
                            qualifier = UvssSelectorPartQualifier.VisualChild;
                            break;

                        case UvssLexerTokenType.LogicalChildSelector:
                            qualifier = UvssSelectorPartQualifier.LogicalChild;
                            break;

                        case UvssLexerTokenType.TemplatedChildSelector:
                            qualifier = UvssSelectorPartQualifier.TemplatedChild;
                            break;
                    }

                    state.Advance();
                    state.AdvanceBeyondWhiteSpace();

                    continue;
                }

                if (token.TokenType == UvssLexerTokenType.Identifier || token.TokenType == UvssLexerTokenType.UniversalSelector)
                {
                    if (!String.IsNullOrEmpty(pseudoClass))
                        ThrowUnexpectedToken(state, token);

                    state.Advance();

                    if (token.TokenType == UvssLexerTokenType.UniversalSelector)
                    {
                        valid = true;
                        universal = true;
                        continue;
                    }
                    else
                    {
                        var typename = default(String);
                        var specific = false;

                        if (IsSelectorForElement(token.Value, out typename, out specific))
                        {
                            if (element != null || universal)
                                ThrowUnexpectedValue(state, token);

                            valid = true;
                            element = typename;
                            elementIsExact = specific;
                            continue;
                        }
                    }

                    if (IsSelectorForID(token.Value))
                    {
                        if (id != null)
                            ThrowUnexpectedValue(state, token);

                        valid = true;
                        id = token.Value;
                        continue;
                    }

                    valid = true;
                    classes.Add(token.Value);
                    continue;
                }

                if (token.TokenType == UvssLexerTokenType.Colon)
                {
                    if (!valid)
                        ThrowUnexpectedToken(state, token);

                    state.Advance();

                    var identifier = state.TryConsume();
                    if (identifier == null)
                        ThrowUnexpectedEOF(state);

                    if (identifier.Value.TokenType != UvssLexerTokenType.Identifier)
                        ThrowExpectedToken(state, identifier.Value, UvssLexerTokenType.Identifier);

                    pseudoClass = identifier.Value.Value;
                    break;
                }

                if (valid)
                    break;

                ThrowUnexpectedToken(state, token);
            }

            return valid ? new UvssSelectorPart(qualifier, element, elementIsExact, id, pseudoClass, classes) : null;
        }
Example #7
0
        /// <summary>
        /// Consumes an optional token which represents an easing function.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A string which represents one of the standard easing functions.</returns>
        private static String ConsumeOptionalEasingFunction(UvssParserState state)
        {
            if (state.CurrentToken.TokenType == UvssLexerTokenType.Identifier)
            {
                var easing = state.CurrentToken.Value;

                state.Advance();
                state.AdvanceBeyondWhiteSpace();

                return easing;
            }
            return null;
        }
Example #8
0
        /// <summary>
        /// Consumes a sequence of tokens representing a list of storyboard animation keyframes.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardKeyframeCollection"/> object representing the collection of keyframes that was consumed.</returns>
        private static UvssStoryboardKeyframeCollection ConsumeStoryboardKeyframeList(UvssParserState state)
        {
            var keyframe        = default(UvssStoryboardKeyframe);
            var keyframes       = new UvssStoryboardKeyframeCollection();
            var keyframesTokens = GetTokensBetweenCurlyBraces(state);
            var keyframesState = new UvssParserState(state.Source, keyframesTokens);

            while ((keyframe = ConsumeStoryboardKeyframe(keyframesState)) != null)
            {
                keyframes.Add(keyframe);
            }

            return keyframes;
        }
Example #9
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS rule.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssRule"/> object representing the rule that was consumed.</returns>
        private static UvssRule ConsumeRule(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return null;

            var selectors = ConsumeSelectorList(state);
            var navigation = ConsumeOptionalNavigationExpression(state);
            var styles    = default(UvssStyleCollection);
            var triggers  = default(UvssTriggerCollection);
            ConsumeStyleList(state, out styles, out triggers);

            return new UvssRule(selectors, navigation, styles, triggers);
        }
Example #10
0
        /// <summary>
        /// Advances the parser state beyond any current white space. If the end of the stream is reached,
        /// a syntax exception is thrown.
        /// </summary>
        /// <param name="state">The parser state.</param>
        private static void AdvanceBeyondWhiteSpaceOrFail(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
            {
                ThrowUnexpectedEOF(state);
            }
        }
Example #11
0
        /// <summary>
        /// Gets the source string between a matching pair of curly braces.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>The source string between the specified matching pair of tokens.</returns>
        private static String GetStringBetweenCurlyBraces(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            var valueTokens = GetTokensBetweenCurlyBraces(state);
            var value       = String.Join(String.Empty, valueTokens.Select(x => x.Value)).Trim();

            return value;
        }
Example #12
0
 /// <summary>
 /// Retrieves all of the tokens between a matching pair of parentheses.
 /// </summary>
 /// <param name="state">The parser state.</param>
 /// <returns>A collection containing the tokens between the specified matching pair of tokens.</returns>
 private static IList<UvssLexerToken> GetTokensBetweenParentheses(UvssParserState state)
 {
     return GetTokensBetweenMatchingPair(state, UvssLexerTokenType.OpenParenthesis, UvssLexerTokenType.CloseParenthesis);
 }
Example #13
0
 /// <summary>
 /// Retrieves all of the tokens between a matching pair of curly braces.
 /// </summary>
 /// <param name="state">The parser state.</param>
 /// <returns>A collection containing the tokens between the specified matching pair of tokens.</returns>
 private static IList<UvssLexerToken> GetTokensBetweenCurlyBraces(UvssParserState state)
 {
     return GetTokensBetweenMatchingPair(state, UvssLexerTokenType.OpenCurlyBrace, UvssLexerTokenType.CloseCurlyBrace);
 }
Example #14
0
        /// <summary>
        /// Retrieves all of the tokens between a matching pair of tokens.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="start">The type of the first token in the matching pair.</param>
        /// <param name="end">The type of the second token in the matching pair.</param>
        /// <returns>A collection containing the tokens between the specified matching pair of tokens.</returns>
        private static IList<UvssLexerToken> GetTokensBetweenMatchingPair(UvssParserState state, UvssLexerTokenType start, UvssLexerTokenType end)
        {
            if (state.CurrentToken.TokenType != start)
                ThrowExpectedToken(state, state.CurrentToken, start);

            var level  = 1;
            var tokens = new List<UvssLexerToken>();

            state.Advance();

            while (true)
            {
                if (state.IsPastEndOfStream)
                    ThrowUnterminatedSequence(state);

                var token = state.Consume();
                if (token.TokenType == start)
                {
                    level++;
                }
                else if (token.TokenType == end)
                {
                    level--;
                }

                if (level == 0)
                {
                    break;
                }

                tokens.Add(token);
            }

            return tokens;
        }
Example #15
0
        /// <summary>
        /// Consumes a sequence of tokens representing a list of storyboard animations.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardAnimationCollection"/> object representing the animation collection that was consumed.</returns>
        private static UvssStoryboardAnimationCollection ConsumeStoryboardAnimationList(UvssParserState state)
        {
            var animation        = default(UvssStoryboardAnimation);
            var animations       = new UvssStoryboardAnimationCollection();
            var animationsTokens = GetTokensBetweenCurlyBraces(state);
            var animationsState  = new UvssParserState(state.Source, animationsTokens);

            while ((animation = ConsumeStoryboardAnimation(animationsState)) != null)
            {
                animations.Add(animation);
            }

            return animations;
        }
Example #16
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboard"/> object representing the storyboard that was consumed.</returns>
        private static UvssStoryboard ConsumeStoryboard(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return null;

            if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier)
                return null;

            if (!state.CurrentToken.Value.StartsWith("@"))
                return null;

            var id           = state.Consume();
            var loopBehavior = ConsumeOptionalLoopBehavior(state);
            var targets      = ConsumeStoryboardTargetList(state);

            return new UvssStoryboard(id.Value.Substring(1), loopBehavior, targets);
        }
Example #17
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard animation.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardAnimation"/> object representing the animation that was consumed.</returns>
        private static UvssStoryboardAnimation ConsumeStoryboardAnimation(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return null;

            var animationToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, animationToken, UvssLexerTokenType.Identifier, "animation");

            var propertyToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, propertyToken, UvssLexerTokenType.Identifier);

            var propertyNameStart  = propertyToken.Value.Start;
            var propertyNameLength = propertyToken.Value.Length;

            while (true)
            {
                if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier)
                    break;

                propertyNameLength += state.CurrentToken.Length;

                state.Consume();
            }

            AdvanceBeyondWhiteSpaceOrFail(state);

            var navigationExpression = ConsumeOptionalNavigationExpression(state);
            var keyframes = ConsumeStoryboardKeyframeList(state);
            return new UvssStoryboardAnimation(state.Source.Substring(propertyNameStart, propertyNameLength), navigationExpression, keyframes);
        }
Example #18
0
        /// <summary>
        /// Optionally consumes a token which represents a loop behavior, if such a token exists at
        /// the current position within the token stream.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>The <see cref="LoopBehavior"/> value which the consumed token represents.</returns>
        private static LoopBehavior ConsumeOptionalLoopBehavior(UvssParserState state)
        {
            AdvanceBeyondWhiteSpaceOrFail(state);

            if (state.CurrentToken.TokenType == UvssLexerTokenType.Identifier)
            {
                return ConsumeLoopBehavior(state);
            }

            return LoopBehavior.None;
        }
Example #19
0
        /// <summary>
        /// Consumes a sequence of tokens representing an optional navigation expression.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssNavigationExpression"/> object representing the animation that was consumed.</returns>
        private static UvssNavigationExpression ConsumeOptionalNavigationExpression(UvssParserState state)
        {
            if (state.CurrentToken.TokenType == UvssLexerTokenType.Pipe)
            {
                var navigationProperty = default(String);
                var navigationPropertyType = default(String);
                var navigationPropertyIndex = default(Int32?);

                state.Consume();
                state.AdvanceBeyondWhiteSpace();

                var propertyToken = state.TryConsumeNonWhiteSpace();
                MatchTokenOrFail(state, propertyToken, UvssLexerTokenType.Identifier);

                navigationProperty = propertyToken.Value.Value;

                state.AdvanceBeyondWhiteSpace();

                if (state.CurrentToken.TokenType == UvssLexerTokenType.IndexOperator)
                {
                    var indexToken = state.Consume();
                    state.AdvanceBeyondWhiteSpace();

                    var indexValue = indexToken.Value;
                    navigationPropertyIndex = Int32.Parse(indexValue.Substring(1, indexValue.Length - 2));
                }

                if (state.CurrentToken.TokenType == UvssLexerTokenType.AsOperator)
                {
                    state.Consume();

                    var propertyTypeToken = state.TryConsumeNonWhiteSpace();
                    MatchTokenOrFail(state, propertyTypeToken, UvssLexerTokenType.Identifier);

                    navigationPropertyType = propertyTypeToken.Value.Value;
                }

                AdvanceBeyondWhiteSpaceOrFail(state);

                return new UvssNavigationExpression(navigationProperty, navigationPropertyType, navigationPropertyIndex);
            }

            return null;
        }
Example #20
0
        /// <summary>
        /// Consumes a token which represents a loop behavior.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>The <see cref="LoopBehavior"/> value which the consumed token represents.</returns>
        private static LoopBehavior ConsumeLoopBehavior(UvssParserState state)
        {
            if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier)
                ThrowExpectedToken(state, state.CurrentToken, UvssLexerTokenType.Identifier);

            if (String.Equals(state.CurrentToken.Value, "none", StringComparison.OrdinalIgnoreCase))
            {
                state.Consume();
                return LoopBehavior.None;
            }
            else if (String.Equals(state.CurrentToken.Value, "loop", StringComparison.OrdinalIgnoreCase))
            {
                state.Consume();
                return LoopBehavior.Loop;
            }
            else if (String.Equals(state.CurrentToken.Value, "reverse", StringComparison.OrdinalIgnoreCase))
            {
                state.Consume();
                return LoopBehavior.Reverse;
            }

            ThrowExpectedValue(state, state.CurrentToken, "none|loop|reverse");
            return LoopBehavior.None;
        }
Example #21
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard keyframe.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardKeyframe"/> object representing the keyframe that was consumed.</returns>
        private static UvssStoryboardKeyframe ConsumeStoryboardKeyframe(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return null;

            var keyframeToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, keyframeToken, UvssLexerTokenType.Identifier, "keyframe");

            var timeToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, timeToken, UvssLexerTokenType.Number);

            AdvanceBeyondWhiteSpaceOrFail(state);

            var easing      = ConsumeOptionalEasingFunction(state);
            var valueTokens = GetTokensBetweenCurlyBraces(state);
            var value       = String.Join(String.Empty, valueTokens.Select(x => x.Value));
            var time        = Double.Parse(timeToken.Value.Value);

            return new UvssStoryboardKeyframe(easing, value, time);
        }
Example #22
0
        /// <summary>
        /// Consumes a sequence of tokens representing a list of storyboard targets.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardTargetCollection"/> object representing the target collection that was consumed.</returns>
        private static UvssStoryboardTargetCollection ConsumeStoryboardTargetList(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            var target        = default(UvssStoryboardTarget);
            var targets       = new UvssStoryboardTargetCollection();
            var targetsTokens = GetTokensBetweenCurlyBraces(state);
            var targetsState  = new UvssParserState(state.Source, targetsTokens);

            while ((target = ConsumeStoryboardTarget(targetsState)) != null)
            {
                targets.Add(target);
            }

            return targets;
        }
Example #23
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS selector list.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssSelectorCollection"/> object representing the selector list that was consumed.</returns>
        private static UvssSelectorCollection ConsumeSelectorList(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            var selectors = new List<UvssSelector>();

            while (true)
            {
                var selector = ConsumeSelector(state);
                selectors.Add(selector);

                AdvanceBeyondWhiteSpaceOrFail(state);

                if (state.CurrentToken.TokenType != UvssLexerTokenType.Comma)
                    break;

                state.Advance();
            }

            return new UvssSelectorCollection(selectors);
        }
Example #24
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard target.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardTarget"/> object representing the target that was consumed.</returns>
        private static UvssStoryboardTarget ConsumeStoryboardTarget(UvssParserState state)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return null;

            var targetToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, targetToken, UvssLexerTokenType.Identifier, "target");

            var filter     = ConsumeStoryboardTargetFilter(state);
            var selector   = ConsumeStoryboardTargetSelector(state);
            var animations = ConsumeStoryboardAnimationList(state);

            return new UvssStoryboardTarget(selector, filter, animations);
        }
Example #25
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS selector.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="allowEOF">A value indicating whether hitting the end of file is valid.</param>
        /// <returns>A new <see cref="UvssSelector"/> object representing the selector that was consumed.</returns>
        private static UvssSelector ConsumeSelector(UvssParserState state, Boolean allowEOF = false)
        {
            state.AdvanceBeyondWhiteSpace();

            var parts       = new List<UvssSelectorPart>();
            var pseudoClass = false;
            
            while (true)
            {
                var part = ConsumeSelectorPart(state, allowEOF, !pseudoClass, parts.Any());
                if (part != null)
                {
                    if (!String.IsNullOrEmpty(part.PseudoClass))
                        pseudoClass = true;

                    parts.Add(part);
                }

                if (state.IsPastEndOfStream)
                {
                    if (allowEOF)
                    {
                        break;
                    }
                    ThrowUnexpectedEOF(state);
                }

                if (state.CurrentToken.TokenType == UvssLexerTokenType.Comma)
                    break;

                if (state.CurrentToken.TokenType != UvssLexerTokenType.WhiteSpace)
                    break;

                state.Advance();
            }

            return new UvssSelector(parts);
        }
Example #26
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard target filter.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssStoryboardTargetFilter"/> object representing the filter that was consumed.</returns>
        private static UvssStoryboardTargetFilter ConsumeStoryboardTargetFilter(UvssParserState state)
        {
            AdvanceBeyondWhiteSpaceOrFail(state);

            var filter = new UvssStoryboardTargetFilter();

            if (state.CurrentToken.TokenType != UvssLexerTokenType.Identifier)
            {
                filter.Add("FrameworkElement");
            }
            else
            {
                while (state.CurrentToken.TokenType == UvssLexerTokenType.Identifier)
                {
                    if (state.IsPastEndOfStream)
                        ThrowUnexpectedEOF(state);

                    var type = state.CurrentToken.Value;
                    filter.Add(type);

                    state.Consume();
                    state.AdvanceBeyondWhiteSpace();
                }
            }

            return filter;
        }
Example #27
0
 /// <summary>
 /// Throws an exception indicating that an expected token was not found.
 /// </summary>
 /// <param name="state">The parser state.</param>
 /// <param name="token">The invalid token.</param>
 /// <param name="expected">The expected token type.</param>
 private static void ThrowExpectedToken(UvssParserState state, UvssLexerToken token, UvssLexerTokenType expected)
 {
     var lineNumber = token.Line;
     throw new UvssException(PresentationStrings.StyleSheetSyntaxExpectedToken.Format(lineNumber, token.TokenType, expected));
 }
Example #28
0
        /// <summary>
        /// Consumes a sequence of tokens representing a storyboard target selector.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <returns>A new <see cref="UvssSelector"/> object representing the selector that was consumed.</returns>
        private static UvssSelector ConsumeStoryboardTargetSelector(UvssParserState state)
        {
            var selector = default(UvssSelector);

            if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis)
            {
                var tokens      = GetTokensBetweenParentheses(state);
                var tokensState = new UvssParserState(state.Source, tokens);
                selector        = ConsumeSelector(tokensState, true);
            }
            
            state.AdvanceBeyondWhiteSpace();

            return selector;
        }
Example #29
0
        /// <summary>
        /// Consumes a sequence of tokens representing a UVSS style or UVSS trigger.
        /// </summary>
        /// <param name="state">The parser state.</param>
        /// <param name="styles">The list containing the styles being created.</param>
        /// <param name="triggers">The list containing the triggers being created.</param>
        /// <returns><c>true</c> if a style or trigger was successfully consumed; otherwise, <c>false</c>.</returns>
        private static Boolean ConsumeStyleOrTrigger(UvssParserState state, List<UvssStyle> styles, List<Trigger> triggers)
        {
            state.AdvanceBeyondWhiteSpace();

            if (state.IsPastEndOfStream)
                return false;

            var qualifierImportant = false;

            var nameToken = state.TryConsumeNonWhiteSpace();
            if (nameToken.HasValue && nameToken.Value.TokenType == UvssLexerTokenType.TriggerKeyword)
            {
                return ConsumeTrigger(state, triggers);
            }
            MatchTokenOrFail(state, nameToken, UvssLexerTokenType.StyleName);

            AdvanceBeyondWhiteSpaceOrFail(state);

            UvssStyleArgumentsCollection arguments;
            if (state.CurrentToken.TokenType == UvssLexerTokenType.OpenParenthesis)
            {
                arguments = ConsumeStyleArguments(state);
                ValidateStyleArguments(state, nameToken.Value.Value, arguments);
            }
            else
            {
                arguments = new UvssStyleArgumentsCollection(null);
            }

            var colonToken = state.TryConsumeNonWhiteSpace();
            MatchTokenOrFail(state, colonToken, UvssLexerTokenType.Colon);

            var valueTokens = new List<UvssLexerToken>();
            while (!state.IsPastEndOfStream)
            {
                var token = state.Consume();
                if (token.TokenType == UvssLexerTokenType.Semicolon)
                {
                    break;
                }
                if (token.TokenType == UvssLexerTokenType.StyleQualifier)
                {
                    if (String.Equals("!important", token.Value, StringComparison.OrdinalIgnoreCase))
                    {
                        qualifierImportant = true;
                    }
                    continue;
                }
                valueTokens.Add(token);
            }

            var container = default(String);
            var name      = nameToken.Value.Value;
            var value     = String.Join(String.Empty, valueTokens.Select(x => x.Value)).Trim();

            if (name.Contains('.'))
            {
                var nameParts = name.Split('.');
                container     = nameParts[0];
                name          = nameParts[1];
            }

            var style = new UvssStyle(arguments, container, name, value, qualifierImportant);
            styles.Add(style);

            return true;
        }
Example #30
0
 /// <summary>
 /// Throws an exception indicating that a style has an invalid argument list.
 /// </summary>
 /// <param name="state">The parser state.</param>
 /// <param name="style">The name of the style with invalid arguments.</param>
 private static void ThrowInvalidStyleArguments(UvssParserState state, String style)
 {
     var lineNumber = state.Tokens.Last().Line;
     throw new UvssException(PresentationStrings.StyleSheetSyntaxInvalidStyleArgs.Format(lineNumber, style));
 }