Branch data Line data Source code
1 : : #pragma once 2 : : 3 : : #include <mutable/lex/Token.hpp> 4 : : #include <mutable/lex/TokenType.hpp> 5 : : #include <mutable/util/Diagnostic.hpp> 6 : : #include <mutable/util/Pool.hpp> 7 : : #include <istream> 8 : : #include <unordered_map> 9 : : #include <vector> 10 : : 11 : : 12 : : namespace m { 13 : : 14 : : namespace ast { 15 : : 16 : : struct M_EXPORT Lexer 17 : : { 18 : : public: 19 : : Diagnostic &diag; 20 : : ThreadSafeStringPool &pool; 21 : : const char *filename; 22 : : std::istream ∈ 23 : : 24 : : private: 25 : : using Keywords_t = std::unordered_map<ThreadSafePooledString, TokenType>; 26 : : using buf_t = std::vector<char>; 27 : : Keywords_t keywords_; 28 : : int c_; 29 : : Position pos_, start_; 30 : : buf_t buf_; 31 : : 32 : : public: 33 : 4298 : explicit Lexer(Diagnostic &diag, ThreadSafeStringPool &pool, const char *filename, std::istream &in) 34 : 2149 : : diag(diag) 35 : 2149 : , pool(pool) 36 : 2149 : , filename(filename) 37 : 2149 : , in(in) 38 [ + - ]: 2149 : , pos_(filename) 39 : 2149 : , start_(pos_) 40 : : { 41 [ + - ]: 2149 : buf_.reserve(32); 42 [ + - ]: 2149 : initialize_keywords(); 43 : 2149 : c_ = '\n'; 44 : 2149 : } 45 : : 46 : : /** Initializes the set of all keywords. */ 47 : : void initialize_keywords(); 48 : : 49 : : /** Obtains the next token from the input stream. */ 50 : : Token next(); 51 : : 52 : : private: 53 : : /** Reads the next character from \p in to \p c_, and updates \p pos_ accordingly. */ 54 : 88993 : int step() { 55 [ + + ]: 88993 : switch (c_) { 56 : : case '\n': 57 : 2298 : pos_.column = 1; 58 : 2298 : pos_.line++; 59 : 2298 : break; 60 : : 61 : : default: 62 : 86695 : pos_.column++; 63 : 86695 : break; 64 : : } 65 : 88993 : return c_ = in.get(); 66 : : } 67 : : 68 : 53325 : void push() { 69 : 53325 : buf_.push_back(c_); 70 : 53325 : step(); 71 : 53325 : } 72 : : 73 : 330 : bool accept(const int c) { 74 [ + + ]: 330 : if (c == this->c_) { 75 : 227 : push(); 76 : 227 : return true; 77 : : } 78 : 103 : return false; 79 : 330 : } 80 : : 81 : 14324 : ThreadSafePooledString internalize() { 82 : 14324 : buf_.push_back('\0'); 83 : 14324 : return pool(buf_.data()); 84 : : } 85 : : 86 : : /* Lexer routines. */ 87 : : Token read_keyword_or_identifier(); 88 : : Token read_number(); 89 : : Token read_string_literal(); 90 : : Token read_date_or_datetime(); 91 : : Token read_instruction(); 92 : : }; 93 : : 94 : : } 95 : : 96 : : }