Esempio n. 1
0
        public virtual ParseItem CreateNextChild(ParseItem previousChild, ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            if (IsNestedBlock)
            {
                if (tokens.CurrentToken.IsScopeBlocker())
                {
                    return(null);
                }

                // Only nested stylesheets (like in @media) should look for braces

                if (previousChild is TokenItem && ((TokenItem)previousChild).TokenType == CssTokenType.CloseCurlyBrace)
                {
                    // No more children after the close curly brace
                    return(null);
                }

                if (previousChild == null && tokens.CurrentToken.TokenType != CssTokenType.OpenCurlyBrace)
                {
                    // First child must be a curly brace
                    return(null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace)
                {
                    return((previousChild == null) ? new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace) : null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.CloseCurlyBrace)
                {
                    return(new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace));
                }
            }

            ParseItem newChild = null;

            switch (tokens.CurrentToken.TokenType)
            {
            case CssTokenType.EndOfFile:
                break;

            case CssTokenType.ScopeBlocker:
                newChild = UnknownItem.ParseUnknown(this, itemFactory, text, tokens);
                break;

            case CssTokenType.At:
                newChild = AtDirective.ParseDirective(this, itemFactory, text, tokens);
                break;

            default:
                newChild = ParseDefaultChild(itemFactory, text, tokens);
                break;
            }

            return(newChild);
        }
Esempio n. 2
0
        public virtual ParseItem CreateNextChild(ParseItem previousChild, ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            if (!IsInlineStyle)
            {
                // Look for curly braces

                if (previousChild is TokenItem && ((TokenItem)previousChild).TokenType == CssTokenType.CloseCurlyBrace)
                {
                    // No more children after the close curly brace
                    return(null);
                }

                if (previousChild == null && tokens.CurrentToken.TokenType != CssTokenType.OpenCurlyBrace)
                {
                    // First child must be a curly brace
                    return(null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace)
                {
                    return((previousChild == null) ? new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace) : null);
                }

                if (tokens.CurrentToken.TokenType == CssTokenType.CloseCurlyBrace)
                {
                    return(new TokenItem(tokens.AdvanceToken(), CssClassifierContextType.CurlyBrace));
                }
            }

            if (tokens.CurrentToken.IsScopeBlocker())
            {
                return(null);
            }

            ParseItem newChild;

            switch (tokens.CurrentToken.TokenType)
            {
            case CssTokenType.At:
                newChild = CreateDirective(itemFactory, text, tokens);
                break;

            default:
                newChild = CreateDefaultChild(itemFactory, text, tokens);
                break;
            }

            return(newChild);
        }
Esempio n. 3
0
        internal TokenItem AddCurrentAndAdvance(TokenStream tokens, IClassifierContext context)
        {
            TokenItem item = new TokenItem(tokens.AdvanceToken(), context);

            Add(item);

            return(item);
        }
Esempio n. 4
0
        public override bool Parse(ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            if (tokens != null)
            {
                Token = tokens.AdvanceToken();
            }

            return(Token != null);
        }
        protected override ParseItem CreateDefaultChild(ItemFactory itemFactory, ITextProvider text, TokenStream tokens)
        {
            // http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems?id=468547 - The contents of unknown directives could be rules or declarations.
            // Make a good guess for which one to create.

            int       startTokenPosition = tokens.Position;
            bool      childIsDeclaration = true;
            ParseItem newChild;

            for (bool done = false; !done && !tokens.CurrentToken.IsBlockTerminator();)
            {
                // If I see a curly brace before a semicolon, then this child is probably a RuleSet

                switch (tokens.CurrentToken.TokenType)
                {
                case CssTokenType.OpenCurlyBrace:
                    childIsDeclaration = false;
                    done = true;
                    break;

                case CssTokenType.Semicolon:
                    done = true;
                    break;

                default:
                    tokens.AdvanceToken();
                    break;
                }
            }

            tokens.Position = startTokenPosition;

            if (childIsDeclaration)
            {
                newChild = base.CreateDefaultChild(itemFactory, text, tokens);
            }
            else
            {
                newChild = itemFactory.Create <RuleSet>(this);

                if (!newChild.Parse(itemFactory, text, tokens))
                {
                    newChild = UnknownItem.ParseUnknown(this, itemFactory, text, tokens, ParseErrorType.UnexpectedToken);
                }
            }

            Debug.Assert(newChild != null);
            return(newChild);
        }
Esempio n. 6
0
        /// <summary>
        /// Extracts comment items from the supplied token collection
        /// </summary>
        /// <param name="textProvider">Text provider</param>
        /// <param name="tokens">Token array that matches the supplied text</param>
        /// <param name="startToken">Index into the token array at which parser should start</param>
        /// <param name="tokenCount">Number of tokens to process</param>
        /// <returns></returns>
        public IList <Comment> ExtractComments(
            ITextProvider text,
            TokenList tokens,
            int startToken,
            int tokenCount)
        {
            TokenStream     tokenIter   = new TokenStream(tokens);
            ItemFactory     itemFactory = new ItemFactory(ExternalItemFactory, text, tokenIter);
            IList <Comment> comments    = new List <Comment>();

            for (tokenIter.Position = startToken;
                 tokenIter.Position < startToken + tokenCount && tokenIter.Position < tokens.Count;)
            {
                CssToken token   = tokenIter.CurrentToken;
                Comment  comment = null;

                switch (token.TokenType)
                {
                case CssTokenType.OpenHtmlComment:
                case CssTokenType.CloseHtmlComment:
                    comment = itemFactory.CreateSpecific <HtmlComment>(null);
                    break;

                case CssTokenType.OpenCComment:
                    comment = itemFactory.CreateSpecific <CComment>(null);
                    break;

                case CssTokenType.CommentText:
                case CssTokenType.SingleTokenComment:
                case CssTokenType.SingleLineComment:
                    comment = itemFactory.CreateSpecific <CommentTokenItem>(null);
                    break;

                default:
                    tokenIter.AdvanceToken();
                    break;
                }

                if (comment != null && comment.Parse(itemFactory, text, tokenIter))
                {
                    comments.Add(comment);
                }
            }

            return(comments);
        }
        public static ParseItem ParseUnknown(
            ComplexItem parent,
            ItemFactory itemFactory,
            ITextProvider text,
            TokenStream tokens,
            ParseErrorType?errorType = null)
        {
            ParseItem pi            = null;
            bool      alreadyParsed = false;

            // For a single unknown token, let this switch fall through where a
            // ParseErrorItem will get created. For multiple unknown tokens, deal with
            // them in this switch and let them automatically get wrapped in an unknown block.

            CssClassifierContextType contextType = CssClassifierContextType.Default;

            switch (tokens.CurrentToken.TokenType)
            {
            case CssTokenType.Url:
                pi = itemFactory.Create <UrlItem>(parent);
                break;

            case CssTokenType.Function:
                pi            = Function.ParseFunction(parent, itemFactory, text, tokens);
                alreadyParsed = true;
                break;

            case CssTokenType.OpenFunctionBrace:
            case CssTokenType.OpenSquareBracket:
            case CssTokenType.OpenCurlyBrace:
                pi = itemFactory.Create <UnknownBlock>(parent);
                break;

            case CssTokenType.String:
            case CssTokenType.MultilineString:
            case CssTokenType.InvalidString:
                contextType = CssClassifierContextType.String;
                break;
            }

            if (pi == null)
            {
                pi = new TokenItem(tokens.CurrentToken, contextType);
            }

            if (!alreadyParsed && !pi.Parse(itemFactory, text, tokens))
            {
                Debug.Fail("Parse of an unknown item failed.");

                // I've done all I can do to deal with this unknown token, but now
                // it must be totally ignored so that parsing doesn't get into an infinite loop.
                tokens.AdvanceToken();
                pi = null;
            }

            if (pi != null && errorType.HasValue)
            {
                pi.AddParseError(errorType.Value, ParseErrorLocation.WholeItem);
            }

            return(pi);
        }
        /// <summary>
        /// Returns true if the token stream was moved forward at all
        /// </summary>
        internal static bool SkipBlock(TokenStream tokens, bool allowCurlyBraces)
        {
            Stack <CssTokenType> endMatches = new Stack <CssTokenType>();

            if ((tokens.CurrentToken.TokenType == CssTokenType.OpenCurlyBrace && allowCurlyBraces) ||
                tokens.CurrentToken.TokenType == CssTokenType.OpenFunctionBrace ||
                tokens.CurrentToken.TokenType == CssTokenType.OpenSquareBracket ||
                tokens.CurrentToken.TokenType == CssTokenType.Function)
            {
                endMatches.Push(GetMatchingTokenType(tokens.CurrentToken.TokenType));
                tokens.AdvanceToken();
            }
            else
            {
                Debug.Fail("Called UnknownItem.SkipBlock at somewhere other than a block");
                return(false);
            }

            while (!tokens.CurrentToken.IsScopeBlocker() && endMatches.Count > 0)
            {
                switch (tokens.CurrentToken.TokenType)
                {
                case CssTokenType.OpenCurlyBrace:
                    if (!allowCurlyBraces)
                    {
                        // stop at the first open curly brace
                        endMatches.Clear();
                    }
                    else
                    {
                        endMatches.Push(GetMatchingTokenType(tokens.CurrentToken.TokenType));
                        tokens.AdvanceToken();
                    }
                    break;

                case CssTokenType.OpenSquareBracket:
                case CssTokenType.OpenFunctionBrace:
                case CssTokenType.Function:
                    endMatches.Push(GetMatchingTokenType(tokens.CurrentToken.TokenType));
                    tokens.AdvanceToken();
                    break;

                case CssTokenType.CloseCurlyBrace:
                case CssTokenType.CloseSquareBracket:
                case CssTokenType.CloseFunctionBrace:
                    if (tokens.CurrentToken.TokenType == endMatches.Peek())
                    {
                        endMatches.Pop();
                        tokens.AdvanceToken();
                    }
                    else
                    {
                        // bad nesting, so bail out
                        endMatches.Clear();
                    }
                    break;

                default:
                    tokens.AdvanceToken();
                    break;
                }
            }

            return(true);
        }