예제 #1
0
        /// <summary>
        /// 4.4.13. Number-rest state
        /// </summary>
        CssToken NumberRest(Char current)
        {
            while (true)
            {
                if (current.IsDigit())
                    _stringBuffer.Append(current);
                else if (current.IsNameStart())
                {
                    var number = FlushBuffer();
                    _stringBuffer.Append(current);
                    return Dimension(Next, number);
                }
                else if (IsValidEscape(current))
                {
                    current = Next;
                    var number = FlushBuffer();
                    _stringBuffer.Append(ConsumeEscape(current));
                    return Dimension(Next, number);
                }
                else
                    break;

                current = Next;
            }

            switch (current)
            {
                case Specification.Dot:
                    current = Next;

                    if (current.IsDigit())
                    {
                        _stringBuffer.Append(Specification.Dot).Append(current);
                        return NumberFraction(Next);
                    }

                    Back();
                    return CssToken.Number(FlushBuffer());

                case '%':
                    return CssUnitToken.Percentage(FlushBuffer());

                case 'e':
                case 'E':
                    return NumberExponential(current);

                case Specification.Minus:
                    return NumberDash(current);

                default:
                    Back();
                    return CssToken.Number(FlushBuffer());
            }
        }
예제 #2
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Specification.Minus)
            {
                current = Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Specification.Minus);
                    return IdentRest(current);
                }

                Back();
                return CssToken.Delim(Specification.Minus);
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return IdentRest(Next);
            }
            else if (current == Specification.ReverseSolidus)
            {
                if (IsValidEscape(current))
                {
                    current = Next;
                    _stringBuffer.Append(ConsumeEscape(current));
                    return IdentRest(Next);
                }
            }

            return Data(current);
        }
예제 #3
0
        /// <summary>
        /// Substate of several Number states.
        /// </summary>
        CssToken NumberDash(Char current)
        {
            current = Next;

            if (current.IsNameStart())
            {
                var number = FlushBuffer();
                _stringBuffer.Append(Specification.Minus).Append(current);
                return Dimension(Next, number);
            }
            else if (IsValidEscape(current))
            {
                current = Next;
                var number = FlushBuffer();
                _stringBuffer.Append(Specification.Minus).Append(ConsumeEscape(current));
                return Dimension(Next, number);
            }
            else
            {
                Back(2);
                return CssToken.Number(FlushBuffer());
            }
        }
예제 #4
0
        /// <summary>
        /// 4.4.1. Data state
        /// </summary>
        CssToken Data(Char current)
        {
            switch (current)
            {
                case Specification.LineFeed:
                case Specification.CarriageReturn:
                case Specification.Tab:
                case Specification.Space:
                    do { current = Next; }
                    while (current.IsSpaceCharacter());

                    if (_ignoreWs)
                        return Data(current);

                    Back();
                    return CssSpecialCharacter.Whitespace;

                case Specification.DoubleQuote:
                    return StringDQ(Next);

                case Specification.Num:
                    return HashStart(Next);

                case Specification.Dollar:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Suffix;

                    return CssToken.Delim(Previous);

                case Specification.SingleQuote:
                    return StringSQ(Next);

                case Specification.RoundBracketOpen:
                    return CssBracketToken.OpenRound;

                case Specification.RoundBracketClose:
                    return CssBracketToken.CloseRound;

                case Specification.Asterisk:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Substring;

                    return CssToken.Delim(Previous);

                case Specification.Plus:
                {
                    var c1 = Next;

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

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

                    return CssToken.Delim(current);
                }

                case Specification.Comma:
                    return CssSpecialCharacter.Comma;

                case Specification.Dot:
                {
                    var c = Next;

                    if (c.IsDigit())
                        return NumberStart(Previous);

                    return CssToken.Delim(Previous);
                }

                case Specification.Minus:
                {
                    var c1 = Next;

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

                        if (c1.IsDigit() || (c1 == Specification.Dot && c2.IsDigit()))
                            return NumberStart(current);
                        else if (c1.IsNameStart())
                            return IdentStart(current);
                        else if (c1 == Specification.ReverseSolidus && !c2.IsLineBreak() && c2 != Specification.EndOfFile)
                            return IdentStart(current);
                        else if (c1 == Specification.Minus && c2 == Specification.GreaterThan)
                        {
                            Advance(2);

                            if (_ignoreCs)
                                return Data(Next);

                            return CssCommentToken.Close;
                        }
                    }

                    return CssToken.Delim(current);
                }

                case Specification.Solidus:
                    current = Next;

                    if (current == Specification.Asterisk)
                        return Comment(Next);

                    return CssToken.Delim(Previous);

                case Specification.ReverseSolidus:
                    current = Next;

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

                    return IdentStart(Previous);

                case Specification.Colon:
                    return CssSpecialCharacter.Colon;

                case Specification.Semicolon:
                    return CssSpecialCharacter.Semicolon;

                case Specification.LessThan:
                    current = Next;

                    if (current == Specification.ExclamationMark)
                    {
                        current = Next;

                        if (current == Specification.Minus)
                        {
                            current = Next;

                            if (current == Specification.Minus)
                            {
                                if (_ignoreCs)
                                    return Data(Next);

                                return CssCommentToken.Open;
                            }

                            current = Previous;
                        }

                        current = Previous;
                    }

                    return CssToken.Delim(Previous);

                case Specification.At:
                    return AtKeywordStart(Next);

                case Specification.SquareBracketOpen:
                    return CssBracketToken.OpenSquare;

                case Specification.SquareBracketClose:
                    return CssBracketToken.CloseSquare;

                case Specification.Accent:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Prefix;

                    return CssToken.Delim(Previous);

                case Specification.CurlyBracketOpen:
                    return CssBracketToken.OpenCurly;

                case Specification.CurlyBracketClose:
                    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 = Next;

                    if (current == Specification.Plus)
                    {
                        current = Next;

                        if (current.IsHex() || current == Specification.QuestionMark)
                            return UnicodeRange(current);

                        current = Previous;
                    }

                    return IdentStart(Previous);

                case Specification.Pipe:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Dash;
                    else if (current == Specification.Pipe)
                        return CssToken.Column;

                    return CssToken.Delim(Previous);

                case Specification.Tilde:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Include;

                    return CssToken.Delim(Previous);

                case Specification.EndOfFile:
                    return null;

                case Specification.ExclamationMark:
                    current = Next;

                    if (current == Specification.Equality)
                        return CssMatchToken.Not;

                    return CssToken.Delim(Previous);

                default:
                    if (current.IsNameStart())
                        return IdentStart(current);

                    return CssToken.Delim(current);
            }
        }
예제 #5
0
 /// <summary>
 /// 4.4.4. Hash state
 /// </summary>
 CssToken HashStart(Char current)
 {
     if (current.IsNameStart())
     {
         _stringBuffer.Append(current);
         return HashRest(Next);
     }
     else if (IsValidEscape(current))
     {
         current = Next;
         _stringBuffer.Append(ConsumeEscape(current));
         return HashRest(Next);
     }
     else if (current == Specification.ReverseSolidus)
     {
         RaiseErrorOccurred(ErrorCode.InvalidCharacter);
         Back();
         return CssToken.Delim(Specification.Num);
     }
     else
     {
         Back();
         return CssToken.Delim(Specification.Num);
     }
 }
예제 #6
0
        /// <summary>
        /// 4.4.1. Data state
        /// </summary>
        CssToken Data(Char current)
        {
            _position = GetCurrentPosition();

            switch (current)
            {
                case Symbols.FormFeed:
                case Symbols.LineFeed:
                case Symbols.CarriageReturn:
                case Symbols.Tab:
                case Symbols.Space:
                    return NewWhitespace(current);

                case Symbols.DoubleQuote:
                    return StringDQ();

                case Symbols.Num:
                    return _valueMode ? ColorLiteral() : HashStart();

                case Symbols.Dollar:
                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewSuffix();

                    return NewDelimiter(GetPrevious());

                case Symbols.SingleQuote:
                    return StringSQ();

                case Symbols.RoundBracketOpen:
                    return NewOpenRound();

                case Symbols.RoundBracketClose:
                    return NewCloseRound();

                case Symbols.Asterisk:
                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewSubstring();

                    return NewDelimiter(GetPrevious());

                case Symbols.Plus:
                {
                    var c1 = GetNext();

                    if (c1 != Symbols.EndOfFile)
                    {
                        var c2 = GetNext();
                        Back(2);

                        if (c1.IsDigit() || (c1 == Symbols.Dot && c2.IsDigit()))
                            return NumberStart(current);
                    }
                    else
                        Back();
                        
                    return NewDelimiter(current);
                }

                case Symbols.Comma:
                    return NewComma();

                case Symbols.Dot:
                {
                    var c = GetNext();

                    if (c.IsDigit())
                        return NumberStart(GetPrevious());
                        
                    return NewDelimiter(GetPrevious());
                }

                case Symbols.Minus:
                {
                    var c1 = GetNext();

                    if (c1 != Symbols.EndOfFile)
                    {
                        var c2 = GetNext();
                        Back(2);

                        if (c1.IsDigit() || (c1 == Symbols.Dot && c2.IsDigit()))
                            return NumberStart(current);
                        else if (c1.IsNameStart())
                            return IdentStart(current);
                        else if (c1 == Symbols.ReverseSolidus && !c2.IsLineBreak() && c2 != Symbols.EndOfFile)
                            return IdentStart(current);
                        else if (c1 == Symbols.Minus && c2 == Symbols.GreaterThan)
                        {
                            Advance(2);
                            return NewCloseComment();
                        }
                    }
                    else
                        Back();
                        
                    return NewDelimiter(current);
                }

                case Symbols.Solidus:
                    current = GetNext();

                    if (current == Symbols.Asterisk)
                        return Comment();
                        
                    return NewDelimiter(GetPrevious());

                case Symbols.ReverseSolidus:
                    current = GetNext();

                    if (current.IsLineBreak())
                    {
                        RaiseErrorOccurred(CssParseError.LineBreakUnexpected);
                        return NewDelimiter(GetPrevious());
                    }
                    else if (current == Symbols.EndOfFile)
                    {
                        RaiseErrorOccurred(CssParseError.EOF);
                        return NewDelimiter(GetPrevious());
                    }

                    return IdentStart(GetPrevious());

                case Symbols.Colon:
                    return NewColon();

                case Symbols.Semicolon:
                    return NewSemicolon();

                case Symbols.LessThan:
                    current = GetNext();

                    if (current == Symbols.ExclamationMark)
                    {
                        current = GetNext();

                        if (current == Symbols.Minus)
                        {
                            current = GetNext();

                            if (current == Symbols.Minus)
                                return NewOpenComment();

                            current = GetPrevious();
                        }

                        current = GetPrevious();
                    }

                    return NewDelimiter(GetPrevious());

                case Symbols.At:
                    return AtKeywordStart();

                case Symbols.SquareBracketOpen:
                    return NewOpenSquare();

                case Symbols.SquareBracketClose:
                    return NewCloseSquare();

                case Symbols.Accent:
                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewPrefix();

                    return NewDelimiter(GetPrevious());

                case Symbols.CurlyBracketOpen:
                    return NewOpenCurly();

                case Symbols.CurlyBracketClose:
                    return NewCloseCurly();

                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 = GetNext();

                    if (current == Symbols.Plus)
                    {
                        current = GetNext();

                        if (current.IsHex() || current == Symbols.QuestionMark)
                            return UnicodeRange(current);

                        current = GetPrevious();
                    }

                    return IdentStart(GetPrevious());

                case Symbols.Pipe:
                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewDash();
                    else if (current == Symbols.Pipe)
                        return NewColumn();

                    return NewDelimiter(GetPrevious());

                case Symbols.Tilde:
                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewInclude();

                    return NewDelimiter(GetPrevious());

                case Symbols.EndOfFile:
                    return NewEof();

                case Symbols.ExclamationMark:

                    current = GetNext();

                    if (current == Symbols.Equality)
                        return NewNot();

                    return NewDelimiter(GetPrevious());

                default:
                    if (current.IsNameStart())
                        return IdentStart(current);

                    return NewDelimiter(current);
            }
        }
예제 #7
0
        /// <summary>
        /// 4.4.7. At-keyword state
        /// </summary>
        CssToken AtKeywordStart(Char current)
        {
            if (current == Specification.Minus)
            {
                current = Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Specification.Minus);
                    return AtKeywordRest(current);
                }

                Back(2);
                return CssToken.Delim(Specification.At);
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return AtKeywordRest(Next);
            }
            else if (IsValidEscape(current))
            {
                current = Next;
                _stringBuffer.Append(ConsumeEscape(current));
                return AtKeywordRest(Next);
            }
            else
            {
                Back();
                return CssToken.Delim(Specification.At);
            }
        }
예제 #8
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Specification.MINUS)
            {
                current = _src.Next;

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Specification.MINUS);
                    return IdentRest(current);
                }

                _src.Back();
                return CssToken.Delim(Specification.MINUS);
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return IdentRest(_src.Next);
            }
            else if (current == Specification.RSOLIDUS)
            {
                if (IsValidEscape(current))
                {
                    current = _src.Next;
                    _stringBuffer.Append(ConsumeEscape(current));
                    return IdentRest(_src.Next);
                }
            }

            return Data(current);
        }
예제 #9
0
        /// <summary>
        /// 4.4.9. Ident state
        /// </summary>
        CssToken IdentStart(Char current)
        {
            if (current == Symbols.Minus)
            {
                current = GetNext();

                if (current.IsNameStart() || IsValidEscape(current))
                {
                    _stringBuffer.Append(Symbols.Minus);
                    return IdentRest(current);
                }

                Back();
                return NewDelimiter(Symbols.Minus);
            }
            else if (current.IsNameStart())
            {
                _stringBuffer.Append(current);
                return IdentRest(GetNext());
            }
            else if (current == Symbols.ReverseSolidus)
            {
                if (IsValidEscape(current))
                {
                    current = GetNext();
                    _stringBuffer.Append(ConsumeEscape(current));
                    return IdentRest(GetNext());
                }
            }

            return Data(current);
        }
예제 #10
0
        /// <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 (current.IsSpaceCharacter());

                    if (_ignoreWs)
                        return Data(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 Specification.RBO:
                    return CssBracketToken.OpenRound;

                case Specification.RBC:
                    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 (c1.IsDigit() || (c1 == Specification.DOT && c2.IsDigit()))
                                return NumberStart(current);
                        }

                        return CssToken.Delim(current);
                    }

                case Specification.COMMA:
                    return CssSpecialCharacter.Comma;

                case Specification.DOT:
                    {
                        var c = _src.Next;

                        if (c.IsDigit())
                            return NumberStart(_src.Previous);

                        return CssToken.Delim(_src.Previous);
                    }

                case Specification.MINUS:
                    {
                        var c1 = _src.Next;

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

                            if (c1.IsDigit() || (c1 == Specification.DOT && c2.IsDigit()))
                                return NumberStart(current);
                            else if (c1.IsNameStart())
                                return IdentStart(current);
                            else if (c1 == Specification.RSOLIDUS && !c2.IsLineBreak() && c2 != Specification.EOF)
                                return IdentStart(current);
                            else if (c1 == Specification.MINUS && c2 == Specification.GT)
                            {
                                _src.Advance(2);

                                if (_ignoreCs)
                                    return Data(_src.Next);

                                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 (current.IsLineBreak() || current == Specification.EOF)
                    {
                        RaiseErrorOccurred(current == Specification.EOF ? ErrorCode.EOF : ErrorCode.LineBreakUnexpected);
                        return CssToken.Delim(_src.Previous);
                    }

                    return IdentStart(_src.Previous);

                case Specification.COLON:
                    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.MINUS)
                        {
                            current = _src.Next;

                            if (current == Specification.MINUS)
                            {
                                if (_ignoreCs)
                                    return Data(_src.Next);

                                return CssCommentToken.Open;
                            }

                            current = _src.Previous;
                        }

                        current = _src.Previous;
                    }

                    return CssToken.Delim(_src.Previous);

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

                case Specification.SBO:
                    return CssBracketToken.OpenSquare;

                case Specification.SBC:
                    return CssBracketToken.CloseSquare;

                case Specification.ACCENT:
                    current = _src.Next;

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

                    return CssToken.Delim(_src.Previous);

                case Specification.CBO:
                    return CssBracketToken.OpenCurly;

                case Specification.CBC:
                    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 (current.IsHex() || 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 (current.IsNameStart())
                        return IdentStart(current);

                    return CssToken.Delim(current);
            }
        }
예제 #11
0
 /// <summary>
 /// 4.4.4. Hash state
 /// </summary>
 CssToken HashStart(Char current)
 {
     if (current.IsNameStart())
     {
         _stringBuffer.Append(current);
         return HashRest(_src.Next);
     }
     else if (IsValidEscape(current))
     {
         current = _src.Next;
         _stringBuffer.Append(ConsumeEscape(current));
         return HashRest(_src.Next);
     }
     else if (current == Specification.RSOLIDUS)
     {
         RaiseErrorOccurred(ErrorCode.InvalidCharacter);
         _src.Back();
         return CssToken.Delim(Specification.NUM);
     }
     else
     {
         _src.Back();
         return CssToken.Delim(Specification.NUM);
     }
 }
예제 #12
0
        ElementDeclarationEntry TypeDeclarationChildren(Char c)
        {
            var entries = new List<ElementDeclarationEntry>();
            var connection = Specification.NULL;

            while (true)
            {
                if (entries.Count > 0)
                {
                    if (c != Specification.PIPE && c != Specification.COMMA)
                        throw new ArgumentException("Invalid content specification in element type declaration.");

                    if (entries.Count == 1)
                        connection = c;
                    else if (connection != c)
                        throw new ArgumentException("Invalid content specification in element type declaration.");

                    c = _src.Next;
                }

                while (c.IsSpaceCharacter())
                    c = _src.Next;

                if (c.IsNameStart())
                {
                    var name = TypeDeclarationName(c);
                    entries.Add(name);
                }
                else if (c == Specification.RBO)
                    entries.Add(TypeDeclarationChildren(_src.Next));
                else
                    throw new ArgumentException("Invalid content specification in element type declaration.");

                c = _src.Current;

                while (c.IsSpaceCharacter())
                    c = _src.Next;

                if (c == Specification.RBC)
                    break;
            }

            c = _src.Next;

            if (entries.Count == 1)
                return entries[0];
            else if (entries.Count == 0)
                throw new ArgumentException("Invalid content specification in element type declaration.");
            else if (connection == Specification.COMMA)
            {
                var sequence = new ElementSequenceDeclarationEntry();
                sequence.Sequence.AddRange(entries);
                sequence.Quantifier = TypeDeclarationQuantifier(c);
                return sequence;
            }

            var choice = new ElementChoiceDeclarationEntry();
            choice.Choice.AddRange(entries);
            choice.Quantifier = TypeDeclarationQuantifier(c);
            return choice;
        }
예제 #13
0
        /// <summary>
        /// More http://www.w3.org/TR/REC-xml/#attdecls.
        /// </summary>
        /// <param name="c">The next input character.</param>
        DtdAttributeToken AttributeDeclaration(Char c)
        {
            var decl = new DtdAttributeToken();
            var canContinue = false;

            if (c.IsSpaceCharacter())
                canContinue = DeclarationNameBefore(_src.Next, decl);
            else if (c == Specification.EOF)
                throw new ArgumentException("The document ended unexpectedly.");
            else
            {
                RaiseErrorOccurred(ErrorCode.UndefinedMarkupDeclaration);
                canContinue = DeclarationNameBefore(c, decl);
            }

            c = _src.Current;

            if (canContinue)
            {
                while (true)
                {
                    while (c.IsSpaceCharacter())
                        c = _src.Next;

                    if (c.IsNameStart())
                    {
                        _stringBuffer.Clear();
                        decl.Attributes.Add(AttributeDeclarationName(c));
                        c = _src.Current;
                        continue;
                    }

                    break;
                }
            }

            return AttributeDeclarationAfter(c, decl);
        }
예제 #14
0
        DtdToken EntityDeclarationAfter(Char c, DtdEntityToken decl)
        {
            while (c.IsSpaceCharacter())
                c = _src.Next;

            if (c == Specification.EOF)
                throw new ArgumentException("The document ended unexpectedly.");
            else if (c == Specification.GT)
                return decl;
            else if (decl.IsExtern && String.IsNullOrEmpty(decl.ExternNotation))
            {
                if (_src.ContinuesWith("NDATA"))
                {
                    _src.Advance(4);
                    c = _src.Next;

                    while (c.IsSpaceCharacter())
                        c = _src.Next;

                    if (c.IsNameStart())
                    {
                        _stringBuffer.Clear();

                        do
                        {
                            _stringBuffer.Append(c);
                            c = _src.Next;
                        }
                        while (c.IsName());

                        decl.ExternNotation = _stringBuffer.ToString();
                        return EntityDeclarationAfter(c, decl);
                    }
                }
            }

            throw new ArgumentException("Declaration invalid.");
        }
예제 #15
0
        ElementMixedDeclarationEntry TypeDeclarationMixed(Char c)
        {
            var entry = new ElementMixedDeclarationEntry();

            while (true)
            {
                while (c.IsSpaceCharacter())
                    c = _src.Next;

                if (c == Specification.RBC)
                {
                    c = _src.Next;

                    if (c == Specification.ASTERISK)
                    {
                        entry.Quantifier = ElementDeclarationEntry.ElementQuantifier.ZeroOrMore;
                        _src.Advance();
                        return entry;
                    }

                    if (entry.Names.Count > 0)
                        RaiseErrorOccurred(ErrorCode.QuantifierMissing);

                    break;
                }
                else if (c == Specification.PIPE)
                {
                    c = _src.Next;

                    while (c.IsSpaceCharacter())
                        c = _src.Next;

                    _stringBuffer.Clear();

                    if (c.IsNameStart())
                    {
                        _stringBuffer.Append(c);

                        while ((c = _src.Next).IsName())
                            _stringBuffer.Append(c);

                        entry.Names.Add(_stringBuffer.ToString());
                    }
                    else
                        throw new ArgumentException("Invalid content specification in element type declaration.");
                }
            }

            return entry;
        }
예제 #16
0
        XmlEntityToken CharacterReference(Char c)
        {
            _stringBuffer.Clear();

            if (c == Specification.NUM)
            {
                c = _src.Next;

                while (c.IsHex())
                {
                    _stringBuffer.Append(c);
                    c = _src.Next;
                }

                if (_stringBuffer.Length > 0 && c == Specification.SC)
                    return new XmlEntityToken { Value = _stringBuffer.ToString(), IsNumeric = true };
            }
            else if (c.IsNameStart())
            {
                do
                {
                    _stringBuffer.Append(c);
                    c = _src.Next;
                }
                while (c.IsName());

                if (c == Specification.SC)
                    return new XmlEntityToken { Value = _stringBuffer.ToString() };
            }

            throw new ArgumentException("Invalid entity reference.");
        }