Exemplo n.º 1
0
            /// <summary>
            /// Advances by one character.
            /// </summary>
            public void Advance()
            {
                if (_texts.Count != 0)
                {
                    _pos.Push(_pos.Pop() + 1);

                    if (_pos.Peek() == _texts.Peek().Length)
                    {
                        _pos.Pop();
                        _texts.Pop();
                        _params.Pop();
                    }
                }
                else
                {
                    _base.Advance();
                }
            }
        /// <summary>
        /// 4.4.1. Data state
        /// </summary>
        CssToken Data(Char current)
        {
            switch (current)
            {
            case Specification.LF:
            case Specification.CR:
            case Specification.TAB:
            case Specification.SPACE:
                do
                {
                    current = src.Next;
                }while (Specification.IsSpaceCharacter(current));
                src.Back();
                return(CssSpecialCharacter.Whitespace);

            case Specification.DQ:
                return(StringDQ(src.Next));

            case Specification.NUM:
                return(HashStart(src.Next));

            case Specification.DOLLAR:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Suffix);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.SQ:
                return(StringSQ(src.Next));

            case '(':
                return(CssBracketToken.OpenRound);

            case ')':
                return(CssBracketToken.CloseRound);

            case Specification.ASTERISK:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Substring);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.PLUS:
            {
                var c1 = src.Next;

                if (c1 == Specification.EOF)
                {
                    src.Back();
                }
                else
                {
                    var c2 = src.Next;
                    src.Back(2);

                    if (Specification.IsDigit(c1) || (c1 == Specification.FS && Specification.IsDigit(c2)))
                    {
                        return(NumberStart(current));
                    }
                }

                return(CssToken.Delim(current));
            }

            case Specification.COMMA:
                return(CssSpecialCharacter.Comma);

            case Specification.FS:
            {
                var c = src.Next;

                if (Specification.IsDigit(c))
                {
                    return(NumberStart(src.Previous));
                }

                return(CssToken.Delim(src.Previous));
            }

            case Specification.DASH:
            {
                var c1 = src.Next;

                if (c1 == Specification.EOF)
                {
                    src.Back();
                }
                else
                {
                    var c2 = src.Next;
                    src.Back(2);

                    if (Specification.IsDigit(c1) || (c1 == Specification.FS && Specification.IsDigit(c2)))
                    {
                        return(NumberStart(current));
                    }
                    else if (Specification.IsNameStart(c1))
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Specification.RSOLIDUS && !Specification.IsLineBreak(c2) && c2 != Specification.EOF)
                    {
                        return(IdentStart(current));
                    }
                    else if (c1 == Specification.DASH && c2 == Specification.GT)
                    {
                        src.Advance(2);
                        return(CssCommentToken.Close);
                    }
                }

                return(CssToken.Delim(current));
            }

            case Specification.SOLIDUS:
                current = src.Next;

                if (current == Specification.ASTERISK)
                {
                    return(Comment(src.Next));
                }

                return(CssToken.Delim(src.Previous));

            case Specification.RSOLIDUS:
                current = src.Next;

                if (Specification.IsLineBreak(current) || current == Specification.EOF)
                {
                    RaiseErrorOccurred(current == Specification.EOF ? ErrorCode.EOF : ErrorCode.LineBreakUnexpected);
                    return(CssToken.Delim(src.Previous));
                }

                return(IdentStart(src.Previous));

            case Specification.COL:
                return(CssSpecialCharacter.Colon);

            case Specification.SC:
                return(CssSpecialCharacter.Semicolon);

            case Specification.LT:
                current = src.Next;

                if (current == Specification.EM)
                {
                    current = src.Next;

                    if (current == Specification.DASH)
                    {
                        current = src.Next;

                        if (current == Specification.DASH)
                        {
                            return(CssCommentToken.Open);
                        }

                        current = src.Previous;
                    }

                    current = src.Previous;
                }

                return(CssToken.Delim(src.Previous));

            case Specification.AT:
                return(AtKeywordStart(src.Next));

            case '[':
                return(CssBracketToken.OpenSquare);

            case ']':
                return(CssBracketToken.CloseSquare);

            case Specification.CA:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Prefix);
                }

                return(CssToken.Delim(src.Previous));

            case '{':
                return(CssBracketToken.OpenCurly);

            case '}':
                return(CssBracketToken.CloseCurly);

            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9':
                return(NumberStart(current));

            case 'U':
            case 'u':
                current = src.Next;

                if (current == Specification.PLUS)
                {
                    current = src.Next;

                    if (Specification.IsHex(current) || current == Specification.QM)
                    {
                        return(UnicodeRange(current));
                    }

                    current = src.Previous;
                }

                return(IdentStart(src.Previous));

            case Specification.PIPE:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Dash);
                }
                else if (current == Specification.PIPE)
                {
                    return(CssToken.Column);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.TILDE:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Include);
                }

                return(CssToken.Delim(src.Previous));

            case Specification.EOF:
                return(null);

            case Specification.EM:
                current = src.Next;

                if (current == Specification.EQ)
                {
                    return(CssMatchToken.Not);
                }

                return(CssToken.Delim(src.Previous));

            default:
                if (Specification.IsNameStart(current))
                {
                    return(IdentStart(current));
                }

                return(CssToken.Delim(current));
            }
        }