diff options
Diffstat (limited to 'parser/lexer.h')
-rw-r--r-- | parser/lexer.h | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/parser/lexer.h b/parser/lexer.h new file mode 100644 index 000000000..874805325 --- /dev/null +++ b/parser/lexer.h @@ -0,0 +1,290 @@ +/* + * This file is part of the API Extractor project. + * + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * Copyright (C) 2002-2005 Roberto Raggi <roberto@kdevelop.org> + * + * Contact: PySide team <contact@pyside.org> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#ifndef LEXER_H +#define LEXER_H + +#include "symbol.h" + +#include <QtCore/QString> +#include <cstdlib> +#include <cassert> + +struct NameSymbol; +class Lexer; +class Control; + +typedef void (Lexer::*scan_fun_ptr)(); + +class Token +{ +public: + int kind; + std::size_t position; + std::size_t size; + char const *text; + + union { + const NameSymbol *symbol; + std::size_t right_brace; + } extra; +}; + +class LocationTable +{ +private: + LocationTable(const LocationTable &source); + void operator = (const LocationTable &source); + +public: + inline LocationTable(std::size_t size = 1024) + : lines(0), + line_count(0), + current_line(0) { + resize(size); + } + + inline ~LocationTable() { + free(lines); + } + + inline std::size_t size() const { + return line_count; + } + + void resize(std::size_t size) { + Q_ASSERT(size > 0); + lines = (std::size_t*) ::realloc(lines, sizeof(std::size_t) * size); + line_count = size; + } + + void positionAt(std::size_t offset, int *line, int *column) const { + positionAt(offset, (int) current_line, line, column); + } + + void positionAt(std::size_t offset, int max_line, int *line, int *column) const; + + inline std::size_t &operator[](int index) { + return lines[index]; + } + +private: + std::size_t *lines; + std::size_t line_count; + std::size_t current_line; + + friend class Lexer; +}; + +class TokenStream +{ +private: + TokenStream(const TokenStream &); + void operator = (const TokenStream &); + +public: + inline TokenStream(std::size_t size = 1024) + : tokens(0), + index(0), + token_count(0) { + resize(size); + } + + inline ~TokenStream() { + ::free(tokens); + } + + inline std::size_t size() const { + return token_count; + } + + inline std::size_t cursor() const { + return index; + } + + inline void rewind(int i) { + index = i; + } + + void resize(std::size_t size) { + Q_ASSERT(size > 0); + tokens = (Token*) ::realloc(tokens, sizeof(Token) * size); + token_count = size; + } + + inline std::size_t nextToken() { + return index++; + } + + inline int lookAhead(std::size_t i = 0) const { + return tokens[index + i].kind; + } + + inline int kind(std::size_t i) const { + return tokens[i].kind; + } + + inline std::size_t position(std::size_t i) const { + return tokens[i].position; + } + + inline const NameSymbol *symbol(std::size_t i) const { + return tokens[i].extra.symbol; + } + + inline std::size_t matchingBrace(std::size_t i) const { + return tokens[i].extra.right_brace; + } + + inline Token &operator[](int index) { + return tokens[index]; + } + + inline const Token &token(int index) const { + return tokens[index]; + } + +private: + Token *tokens; + std::size_t index; + std::size_t token_count; + +private: + friend class Lexer; +}; + +class LocationManager +{ + LocationManager(LocationManager const &__other); + void operator = (LocationManager const &__other); + +public: + LocationManager(TokenStream &__token_stream, + LocationTable &__location_table, + LocationTable &__line_table): + token_stream(__token_stream), + location_table(__location_table), + line_table(__line_table) {} + + void positionAt(std::size_t offset, int *line, int *column, + QString *filename) const; + + void extract_line(int offset, int *line, QString *filename) const; + + TokenStream &token_stream; + LocationTable &location_table; + LocationTable &line_table; +}; + +class Lexer +{ +public: + Lexer(LocationManager &__location, Control *__control): + _M_location(__location), + token_stream(_M_location.token_stream), + location_table(_M_location.location_table), + line_table(_M_location.line_table), + control(__control) {} + + void tokenize(const char *contents, std::size_t size); + + LocationManager &_M_location; + TokenStream &token_stream; + LocationTable &location_table; + LocationTable &line_table; + +private: + void reportError(const QString& msg); + + void initialize_scan_table(); + void scan_newline(); + void scan_white_spaces(); + void scan_identifier_or_keyword(); + void scan_identifier_or_literal(); + void scan_int_constant(); + void scan_char_constant(); + void scan_string_constant(); + void scan_invalid_input(); + void scan_preprocessor(); + + // keywords + void scanKeyword0(); + void scanKeyword2(); + void scanKeyword3(); + void scanKeyword4(); + void scanKeyword5(); + void scanKeyword6(); + void scanKeyword7(); + void scanKeyword8(); + void scanKeyword9(); + void scanKeyword10(); + void scanKeyword11(); + void scanKeyword12(); + void scanKeyword13(); + void scanKeyword14(); + void scanKeyword16(); + + // operators + void scan_not(); + void scan_remainder(); + void scan_and(); + void scan_left_paren(); + void scan_right_paren(); + void scan_star(); + void scan_plus(); + void scan_comma(); + void scan_minus(); + void scan_dot(); + void scan_divide(); + void scan_colon(); + void scan_semicolon(); + void scan_less(); + void scan_equal(); + void scan_greater(); + void scan_question(); + void scan_left_bracket(); + void scan_right_bracket(); + void scan_xor(); + void scan_left_brace(); + void scan_or(); + void scan_right_brace(); + void scan_tilde(); + void scan_EOF(); + +private: + Control *control; + const unsigned char *cursor; + const unsigned char *begin_buffer; + const unsigned char *end_buffer; + std::size_t index; + + static scan_fun_ptr s_scan_table[]; + static scan_fun_ptr s_scan_keyword_table[]; + static bool s_initialized; +}; + +#endif // LEXER_H + +// kate: space-indent on; indent-width 2; replace-tabs on; |