2014-06-06 01:55:36 +00:00
|
|
|
/*
|
|
|
|
Copyright (c) 2014 Microsoft Corporation. All rights reserved.
|
|
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
|
|
|
|
|
|
Author: Leonardo de Moura
|
|
|
|
*/
|
|
|
|
#include <string>
|
|
|
|
#include <iostream>
|
|
|
|
#include "util/name.h"
|
|
|
|
#include "util/numerics/mpq.h"
|
2014-06-10 17:59:12 +00:00
|
|
|
#include "kernel/environment.h"
|
2014-06-10 16:11:45 +00:00
|
|
|
#include "frontends/lean/token_table.h"
|
2014-06-06 01:55:36 +00:00
|
|
|
|
2014-06-10 17:59:12 +00:00
|
|
|
|
2014-06-06 01:55:36 +00:00
|
|
|
namespace lean {
|
|
|
|
/**
|
|
|
|
\brief Scanner. The behavior of the scanner is controlled using a token set.
|
|
|
|
|
|
|
|
The scanner has builtin support for comments, script blocks,
|
|
|
|
identifiers, numerals, decimals, strings. Everything else is only
|
|
|
|
accepted if they are in the token set.
|
|
|
|
*/
|
|
|
|
class scanner {
|
|
|
|
public:
|
2014-06-15 05:13:25 +00:00
|
|
|
enum class token_kind {Keyword, CommandKeyword, ScriptBlock, Identifier, Numeral, Decimal, String, QuotedSymbol, Eof};
|
2014-06-06 01:55:36 +00:00
|
|
|
protected:
|
2014-06-10 17:59:12 +00:00
|
|
|
token_table const * m_tokens;
|
|
|
|
std::istream & m_stream;
|
|
|
|
std::string m_stream_name;
|
2014-06-06 01:55:36 +00:00
|
|
|
|
2014-06-10 17:59:12 +00:00
|
|
|
int m_spos; // current position
|
2014-08-02 02:58:02 +00:00
|
|
|
int m_upos; // current position taking into account utf-8 encoding
|
|
|
|
int m_uskip; // hack for decoding utf-8, it marks how many units to skip
|
2014-06-10 17:59:12 +00:00
|
|
|
int m_sline; // current line
|
|
|
|
char m_curr; // current char;
|
2014-06-06 01:55:36 +00:00
|
|
|
|
2014-06-10 17:59:12 +00:00
|
|
|
int m_pos; // start position of the token
|
|
|
|
int m_line; // line of the token
|
2014-06-06 01:55:36 +00:00
|
|
|
|
2014-06-10 17:59:12 +00:00
|
|
|
name m_name_val;
|
|
|
|
token_info const * m_token_info;
|
|
|
|
mpq m_num_val;
|
|
|
|
std::string m_buffer;
|
|
|
|
std::string m_aux_buffer;
|
2014-06-06 01:55:36 +00:00
|
|
|
|
2014-06-15 05:13:25 +00:00
|
|
|
[[ noreturn ]] void throw_exception(char const * msg);
|
2014-06-06 01:55:36 +00:00
|
|
|
void next();
|
|
|
|
char curr() const { return m_curr; }
|
|
|
|
char curr_next() { char c = curr(); next(); return c; }
|
2014-08-02 02:58:02 +00:00
|
|
|
void new_line() { m_sline++; m_spos = 0; m_upos = 0; }
|
2014-06-06 01:55:36 +00:00
|
|
|
void update_line() { if (curr() == '\n') new_line(); }
|
2014-06-15 05:13:25 +00:00
|
|
|
void check_not_eof(char const * error_msg);
|
2014-06-06 01:55:36 +00:00
|
|
|
bool is_next_digit();
|
|
|
|
bool is_next_id_rest();
|
2014-08-02 02:58:02 +00:00
|
|
|
void move_back(unsigned offset, unsigned u_offset);
|
2014-06-06 01:55:36 +00:00
|
|
|
bool consume(char const * str, char const * error_msg);
|
|
|
|
void read_single_line_comment();
|
|
|
|
void read_comment_block();
|
|
|
|
void read_until(char const * end_str, char const * error_msg);
|
2014-08-02 02:58:02 +00:00
|
|
|
unsigned get_utf8_size(unsigned char c);
|
|
|
|
void next_utf_core(char c, buffer<char> & cs);
|
|
|
|
void next_utf(buffer<char> & cs);
|
2014-06-06 01:55:36 +00:00
|
|
|
|
|
|
|
token_kind read_string();
|
|
|
|
token_kind read_number();
|
|
|
|
token_kind read_script_block();
|
|
|
|
token_kind read_key_cmd_id();
|
2014-06-15 05:13:25 +00:00
|
|
|
token_kind read_quoted_symbol();
|
2014-06-06 01:55:36 +00:00
|
|
|
|
|
|
|
public:
|
2014-06-10 17:59:12 +00:00
|
|
|
scanner(std::istream & strm, char const * strm_name = nullptr);
|
2014-06-06 01:55:36 +00:00
|
|
|
|
|
|
|
int get_line() const { return m_line; }
|
|
|
|
int get_pos() const { return m_pos; }
|
2014-06-10 17:59:12 +00:00
|
|
|
token_kind scan(environment const & env);
|
2014-06-14 14:28:56 +00:00
|
|
|
void set_line(unsigned p);
|
2014-06-06 01:55:36 +00:00
|
|
|
|
|
|
|
mpq const & get_num_val() const { return m_num_val; }
|
|
|
|
name const & get_name_val() const { return m_name_val; }
|
|
|
|
std::string const & get_str_val() const { return m_buffer; }
|
|
|
|
token_info const & get_token_info() const { lean_assert(m_token_info); return *m_token_info; }
|
2014-06-11 00:02:06 +00:00
|
|
|
|
|
|
|
std::string const & get_stream_name() const { return m_stream_name; }
|
2014-06-06 01:55:36 +00:00
|
|
|
};
|
|
|
|
std::ostream & operator<<(std::ostream & out, scanner::token_kind k);
|
|
|
|
}
|