File indexing completed on 2024-05-12 04:39:43

0001 /*
0002     SPDX-FileCopyrightText: 2004 Roberto Raggi <roberto@kdevelop.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #ifndef MILEXER_H
0008 #define MILEXER_H
0009 
0010 #include <QVector>
0011 
0012 namespace KDevMI { namespace MI {
0013 
0014 class MILexer;
0015 struct TokenStream;
0016 
0017 using scan_fun_ptr = void (MILexer::*)(int*);
0018 
0019 struct Token
0020 {
0021     int kind;
0022     int position;
0023     int length;
0024 };
0025 
0026 struct FileSymbol
0027 {
0028     QByteArray contents;
0029     TokenStream *tokenStream = nullptr;
0030 
0031     inline FileSymbol() {}
0032 
0033     inline ~FileSymbol();
0034 
0035 private:
0036     Q_DISABLE_COPY(FileSymbol)
0037 };
0038 
0039 struct TokenStream
0040 {
0041     inline int lookAhead(int n = 0) const
0042     { return (m_currentToken + n)->kind; }
0043 
0044     inline int currentToken() const
0045     { return m_currentToken->kind; }
0046 
0047     inline QByteArray currentTokenText() const
0048     { return tokenText(-1); }
0049 
0050     QByteArray tokenText(int index = 0) const;
0051 
0052     inline int lineOffset(int line) const
0053     { return m_lines.at(line); }
0054 
0055     void positionAt(int position, int *line, int *column) const;
0056 
0057     inline void getTokenStartPosition(int index, int *line, int *column) const
0058     { positionAt((m_firstToken + index)->position, line, column); }
0059 
0060     inline void getTokenEndPosition(int index, int *line, int *column) const
0061     {
0062         Token *tk = m_firstToken + index;
0063         positionAt(tk->position + tk->length, line, column);
0064     }
0065 
0066     inline void rewind(int index)
0067     { m_currentToken = m_firstToken + index; }
0068 
0069     inline int cursor() const
0070     { return m_currentToken - m_firstToken; }
0071 
0072     inline void nextToken()
0073     { m_currentToken++; m_cursor++; }
0074 
0075 //private:
0076     QByteArray m_contents;
0077 
0078     QVector<int> m_lines;
0079     int m_line;
0080 
0081     QVector<Token> m_tokens;
0082     int m_tokensCount;
0083 
0084     Token *m_firstToken;
0085     Token *m_currentToken;
0086 
0087     int m_cursor;
0088 };
0089 
0090 class MILexer
0091 {
0092 public:
0093     MILexer();
0094     ~MILexer();
0095 
0096     TokenStream *tokenize(const FileSymbol *fileSymbol);
0097 
0098 private:
0099     int nextToken(int &position, int &len);
0100 
0101     void scanChar(int *kind);
0102     void scanUnicodeChar(int *kind);
0103     void scanNewline(int *kind);
0104     void scanWhiteSpaces(int *kind);
0105     void scanStringLiteral(int *kind);
0106     void scanNumberLiteral(int *kind);
0107     void scanIdentifier(int *kind);
0108 
0109     void setupScanTable();
0110 
0111 private:
0112     static bool s_initialized;
0113     static scan_fun_ptr s_scan_table[128 + 1];
0114 
0115     QByteArray m_contents;
0116     int m_ptr = 0;
0117     // Cached 'm_contents.length()'
0118     int m_length = 0;
0119 
0120     QVector<int> m_lines;
0121     int m_line = 0;
0122 
0123     QVector<Token> m_tokens;
0124     int m_tokensCount = 0;
0125 
0126     int m_cursor = 0;
0127 };
0128 
0129 inline FileSymbol::~FileSymbol()
0130 {
0131     delete tokenStream;
0132     tokenStream = nullptr;
0133 }
0134 
0135 } // end of MI
0136 } // end of KDevMI
0137 
0138  Q_DECLARE_TYPEINFO(KDevMI::MI::Token, Q_PRIMITIVE_TYPE);
0139 
0140 #endif