Beispiel #1
0
        public Token GetNextToken()
        {
            var token = new Token();

            do
            {
                if (_cursor == _data.Length)
                {
                    token.Type = TokenType.EOF;
                    return(token);
                }

                if (_data[_cursor] == '\r')
                {
                    _cursor++;
                    _lineCursor++;
                    _colCursor = 1;
                    if (_cursor < _data.Length && _data[_cursor] == '\n')
                    {
                        _cursor++;
                    }
                }
                else if (_data[_cursor] == '\n')
                {
                    _cursor++;
                    _lineCursor++;
                    _colCursor = 1;
                }
                else if (char.IsWhiteSpace(_data[_cursor]))
                {
                    _cursor++;
                    _colCursor++;
                }
                else
                {
                    break;
                }
            } while (true);


            token.Start  = _cursor;
            token.Line   = _lineCursor;
            token.Column = _colCursor;

            switch (_data[_cursor])
            {
            case '%': {
                var line = SegmentUntilEOL(_cursor + 1);
                if (line.Count > 0 && line[0] == '!')
                {
                    token.Type = TokenType.PDF_TAG;
                }
                else
                {
                    token.Type = TokenType.COMMENT;
                }
                token.Content = line;
                token.Length  = line.Count + 1;

                _cursor += line.Count + 1;
            } break;

            case '+':
            case '-':
            case '.':
            case '0':
            case '1':
            case '2':
            case '3':
            case '4':
            case '5':
            case '6':
            case '7':
            case '8':
            case '9': {
                var number = SegmentUntilDelimiter(_cursor);
                if (Ext.FirstIndexOf(number, '.') > -1)
                {
                    token.Type = TokenType.LITERAL_DECIMAL;
                }
                else
                {
                    token.Type = TokenType.LITERAL_INTEGER;
                }
                token.Content = number;
                token.Length  = number.Count;

                _cursor    += token.Length;
                _colCursor += token.Length;
            }
            break;

            case '{':
            case '}': {
                token.Type    = TokenType.BRACE;
                token.Content = new ArraySegment <char>(_data, _cursor, 1);
                token.Length  = 1;

                _cursor++;
                _colCursor++;
            } break;

            case '[':
            case ']': {
                token.Type    = TokenType.BRACKET;
                token.Content = new ArraySegment <char>(_data, _cursor, 1);
                token.Length  = 1;

                _cursor++;
                _colCursor++;
            } break;

            case '(': {
                token.Type    = TokenType.LITERAL_STRING;
                token.Content = SegmentUntil(_cursor + 1, ')');
                token.Length  = token.Content.Count + 2;

                _cursor    += token.Length;
                _colCursor += token.Length;
            } break;

            case '<': {
                token.Type    = TokenType.LITERAL_STRING_HEX;
                token.Content = SegmentUntil(_cursor + 1, '>');
                token.Length  = token.Content.Count + 2;

                _cursor    += token.Length;
                _colCursor += token.Length;
            } break;

            case '/': {
                token.Type    = TokenType.LITERAL_NAME;
                token.Content = SegmentUntilDelimiter(_cursor + 1);
                token.Length  = token.Content.Count + 1;

                _cursor    += token.Length;
                _colCursor += token.Length;
            } break;

            default: {
                token.Content = SegmentUntilDelimiter(_cursor);

                var contentSpan = (ReadOnlySpan <char>)token.Content;
                if (contentSpan.Equals("true", StringComparison.Ordinal))
                {
                    token.Type    = TokenType.LITERAL_BOOLEAN;
                    token.Keyword = Keyword.LITERAL_TRUE;
                }
                else if (contentSpan.Equals("false", StringComparison.Ordinal))
                {
                    token.Type    = TokenType.LITERAL_BOOLEAN;
                    token.Keyword = Keyword.LITERAL_TRUE;
                }
                else if (KeywordMap.TryGetValue(contentSpan, out var keyword))
                {
                    token.Type    = TokenType.KEYWORD;
                    token.Keyword = keyword;
                }

                token.Length = token.Content.Count;

                _cursor    += token.Length;
                _colCursor += token.Length;
            } break;
            }

            return(token);
        }
Beispiel #2
0
 public override string ToString()
 {
     return($"[{Line:D4}:{Column:D3}] Type: {Type}, Keyword: {Keyword}, Content: {Ext.Dump(Content)}");
 }