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