Пример #1
0
        public IEnumerable <CssToken> Tokenize()
        {
            CssToken token = default(CssToken);

            int ch;

            while ((ch = _reader.Peek()) >= 0)
            {
                switch (ch)
                {
                case ' ':
                case '\t':
                case '\f':
                case '\r':
                case '\n':
                    yield return(ConsumeWhitespaceToken());

                    continue;

                case ',':
                case ':':
                case ';':
                case '(':
                case '[':
                case '{':
                case ')':
                case ']':
                case '}':
                    yield return(TokenFactory.CreateToken((char)_reader.Read()));

                    continue;

                case '\'':
                case '"':
                    yield return(ConsumeStringToken());

                    continue;

                case '#':
                    _reader.Read();

                    string hashNameOrIdentifier;
                    if (TryConsumeIdentifier(out hashNameOrIdentifier))
                    {
                        yield return(TokenFactory.CreateHashToken(hashNameOrIdentifier, true));
                    }
                    else if (TryConsumeName(out hashNameOrIdentifier))
                    {
                        yield return(TokenFactory.CreateHashToken(hashNameOrIdentifier, false));
                    }
                    else
                    {
                        yield return(TokenFactory.CreateToken((char)ch));
                    }
                    continue;

                case '^':
                case '$':
                case '*':
                case '~':
                    _reader.Read();
                    yield return(_reader.TryRead("=")
                                                        ? TokenFactory.CreateOperatorToken((char)ch)
                                                        : TokenFactory.CreateToken((char)ch));

                    continue;

                case '+':
                case '.':
                    if (TryConsumeNumericToken(ref token))
                    {
                        yield return(token);

                        continue;
                    }

                    yield return(TokenFactory.CreateToken((char)_reader.Read()));

                    continue;

                case '-':
                    if (TryConsumeNumericToken(ref token) || TryConsumeIdentifierToken(ref token))
                    {
                        yield return(token);

                        continue;
                    }

                    yield return(_reader.TryRead("-->")
                                                        ? TokenFactory.CreateCdcToken()
                                                        : TokenFactory.CreateToken((char)_reader.Read()));

                    continue;

                case '/':
                    string comment;
                    if (!TryConsumeComment(out comment))
                    {
                        yield return(TokenFactory.CreateToken((char)_reader.Read()));
                    }
                    continue;

                case '<':
                    yield return(_reader.TryRead("<!--")
                                                        ? TokenFactory.CreateCdoToken()
                                                        : TokenFactory.CreateToken((char)_reader.Read()));

                    continue;

                case '@':
                    _reader.Read();

                    string identifier;
                    yield return(TryConsumeIdentifier(out identifier)
                                                        ? TokenFactory.CreateAtKeywordToken(identifier)
                                                        : TokenFactory.CreateToken((char)ch));

                    continue;

                case '\\':
                    if (TryConsumeIdentifierToken(ref token))
                    {
                        yield return(token);

                        continue;
                    }

                    NotifyError("Invalid escape sequence.");

                    yield return(TokenFactory.CreateToken((char)_reader.Read()));

                    continue;

                case '|':
                    _reader.Read();
                    switch (_reader.Peek())
                    {
                    case '=':
                        yield return(TokenFactory.CreateOperatorToken((char)ch));

                        _reader.Read();
                        break;

                    case '|':
                        yield return(TokenFactory.CreateColumnToken());

                        _reader.Read();
                        break;

                    default:
                        yield return(TokenFactory.CreateToken((char)ch));

                        break;
                    }
                    continue;

                default:
                    if (TryConsumeNumericToken(ref token))
                    {
                        yield return(token);

                        continue;
                    }
                    if (IsNameStartCodePoint((char)ch))
                    {
                        yield return(ConsumeIdentifierLikeToken());

                        continue;
                    }

                    yield return(TokenFactory.CreateToken((char)_reader.Read()));

                    continue;
                }
            }
        }