File: milexer.h

package info (click to toggle)
kdevelop 4%3A24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 71,888 kB
  • sloc: cpp: 290,869; python: 3,626; javascript: 3,518; sh: 1,316; ansic: 703; xml: 401; php: 95; lisp: 66; makefile: 31; sed: 12
file content (140 lines) | stat: -rw-r--r-- 2,739 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*
    SPDX-FileCopyrightText: 2004 Roberto Raggi <roberto@kdevelop.org>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#ifndef MILEXER_H
#define MILEXER_H

#include <QVector>

namespace KDevMI { namespace MI {

class MILexer;
struct TokenStream;

using scan_fun_ptr = void (MILexer::*)(int*);

struct Token
{
    int kind;
    int position;
    int length;
};

struct FileSymbol
{
    QByteArray contents;
    TokenStream *tokenStream = nullptr;

    inline FileSymbol() {}

    inline ~FileSymbol();

private:
    Q_DISABLE_COPY(FileSymbol)
};

struct TokenStream
{
    inline int lookAhead(int n = 0) const
    { return (m_currentToken + n)->kind; }

    inline int currentToken() const
    { return m_currentToken->kind; }

    inline QByteArray currentTokenText() const
    { return tokenText(-1); }

    QByteArray tokenText(int index = 0) const;

    inline int lineOffset(int line) const
    { return m_lines.at(line); }

    void positionAt(int position, int *line, int *column) const;

    inline void getTokenStartPosition(int index, int *line, int *column) const
    { positionAt((m_firstToken + index)->position, line, column); }

    inline void getTokenEndPosition(int index, int *line, int *column) const
    {
        Token *tk = m_firstToken + index;
        positionAt(tk->position + tk->length, line, column);
    }

    inline void rewind(int index)
    { m_currentToken = m_firstToken + index; }

    inline int cursor() const
    { return m_currentToken - m_firstToken; }

    inline void nextToken()
    { m_currentToken++; m_cursor++; }

//private:
    QByteArray m_contents;

    QVector<int> m_lines;
    int m_line;

    QVector<Token> m_tokens;
    int m_tokensCount;

    Token *m_firstToken;
    Token *m_currentToken;

    int m_cursor;
};

class MILexer
{
public:
    MILexer();
    ~MILexer();

    TokenStream *tokenize(const FileSymbol *fileSymbol);

private:
    int nextToken(int &position, int &len);

    void scanChar(int *kind);
    void scanUnicodeChar(int *kind);
    void scanNewline(int *kind);
    void scanWhiteSpaces(int *kind);
    void scanStringLiteral(int *kind);
    void scanNumberLiteral(int *kind);
    void scanIdentifier(int *kind);

    void setupScanTable();

private:
    static bool s_initialized;
    static scan_fun_ptr s_scan_table[128 + 1];

    QByteArray m_contents;
    int m_ptr = 0;
    // Cached 'm_contents.length()'
    int m_length = 0;

    QVector<int> m_lines;
    int m_line = 0;

    QVector<Token> m_tokens;
    int m_tokensCount = 0;

    int m_cursor = 0;
};

inline FileSymbol::~FileSymbol()
{
    delete tokenStream;
    tokenStream = nullptr;
}

} // end of MI
} // end of KDevMI

 Q_DECLARE_TYPEINFO(KDevMI::MI::Token, Q_PRIMITIVE_TYPE);

#endif