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