File indexing completed on 2024-05-12 05:46:50
0001 /*************************************************************************** 0002 * Copyright (C) 2004 by Roberto Raggi * 0003 * roberto@kdevelop.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU Library General Public License as * 0007 * published by the Free Software Foundation; either version 2 of the * 0008 * License, or (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU Library General Public * 0016 * License along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #ifndef MILEXER_H 0021 #define MILEXER_H 0022 0023 #include <QVector> 0024 0025 namespace KDevMI { namespace MI { 0026 0027 class MILexer; 0028 struct TokenStream; 0029 0030 using scan_fun_ptr = void (MILexer::*)(int*); 0031 0032 struct Token 0033 { 0034 int kind; 0035 int position; 0036 int length; 0037 }; 0038 0039 struct FileSymbol 0040 { 0041 QByteArray contents; 0042 TokenStream *tokenStream = nullptr; 0043 0044 inline FileSymbol() {} 0045 0046 inline ~FileSymbol(); 0047 0048 private: 0049 Q_DISABLE_COPY(FileSymbol) 0050 }; 0051 0052 struct TokenStream 0053 { 0054 inline int lookAhead(int n = 0) const 0055 { return (m_currentToken + n)->kind; } 0056 0057 inline int currentToken() const 0058 { return m_currentToken->kind; } 0059 0060 inline QByteArray currentTokenText() const 0061 { return tokenText(-1); } 0062 0063 QByteArray tokenText(int index = 0) const; 0064 0065 inline int lineOffset(int line) const 0066 { return m_lines.at(line); } 0067 0068 void positionAt(int position, int *line, int *column) const; 0069 0070 inline void getTokenStartPosition(int index, int *line, int *column) const 0071 { positionAt((m_firstToken + index)->position, line, column); } 0072 0073 inline void getTokenEndPosition(int index, int *line, int *column) const 0074 { 0075 Token *tk = m_firstToken + index; 0076 positionAt(tk->position + tk->length, line, column); 0077 } 0078 0079 inline void rewind(int index) 0080 { m_currentToken = m_firstToken + index; } 0081 0082 inline int cursor() const 0083 { return m_currentToken - m_firstToken; } 0084 0085 inline void nextToken() 0086 { m_currentToken++; m_cursor++; } 0087 0088 //private: 0089 QByteArray m_contents; 0090 0091 QVector<int> m_lines; 0092 int m_line; 0093 0094 QVector<Token> m_tokens; 0095 int m_tokensCount; 0096 0097 Token *m_firstToken; 0098 Token *m_currentToken; 0099 0100 int m_cursor; 0101 }; 0102 0103 class MILexer 0104 { 0105 public: 0106 MILexer(); 0107 ~MILexer(); 0108 0109 TokenStream *tokenize(const FileSymbol *fileSymbol); 0110 0111 private: 0112 int nextToken(int &position, int &len); 0113 0114 void scanChar(int *kind); 0115 void scanUnicodeChar(int *kind); 0116 void scanNewline(int *kind); 0117 void scanWhiteSpaces(int *kind); 0118 void scanStringLiteral(int *kind); 0119 void scanNumberLiteral(int *kind); 0120 void scanIdentifier(int *kind); 0121 0122 void setupScanTable(); 0123 0124 private: 0125 static bool s_initialized; 0126 static scan_fun_ptr s_scan_table[128 + 1]; 0127 0128 QByteArray m_contents; 0129 int m_ptr = 0; 0130 // Cached 'm_contents.length()' 0131 int m_length = 0; 0132 0133 QVector<int> m_lines; 0134 int m_line = 0; 0135 0136 QVector<Token> m_tokens; 0137 int m_tokensCount = 0; 0138 0139 int m_cursor = 0; 0140 }; 0141 0142 inline FileSymbol::~FileSymbol() 0143 { 0144 delete tokenStream; 0145 tokenStream = nullptr; 0146 } 0147 0148 } // end of MI 0149 } // end of KDevMI 0150 0151 Q_DECLARE_TYPEINFO(KDevMI::MI::Token, Q_PRIMITIVE_TYPE); 0152 0153 #endif