4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo
9
#include "simodo/inout/token/Scanner.h"
14
namespace simodo::inout
17
bool Scanner::putCharToBuffer()
19
if (_is_end_of_file_reached)
22
// ВАЖНО! Предполагается, что входной поток содержит коды текста длиной не более двух байт
23
/// \todo При чтении символов из входного потока потенциально возможно искажение (если размер кода текста > 16 бит).
24
/// Кроме того, это приводит к слабости кода перед изменениями, например, при переходе на строки по 32 бита в символе.
25
/// Решение: сделать класс с параметрическим типом на размер символа в потоке и строке.
26
char16_t ch = _input.get();
28
if (ch == std::char_traits<char16_t>::eof())
30
_is_end_of_file_reached = true;
34
_buffer.push_back(ch);
38
Scanner::Scanner(uri_index_t uri_index, InputStream_interface &input_stream, context_index_t context_index)
39
: _uri_index(uri_index)
40
, _input(input_stream)
41
, _context_index(context_index)
44
, _current_character(0)
45
, _is_end_of_file_reached(false)
50
bool Scanner::shift(size_t length)
52
assert(_buffer.size() >= length); // Нельзя сдвигать за пределы буфера (откуда токенайзеру знать то, чего он не видел?)
55
for(size_t i=0; i < length; ++i)
57
char16_t ch = _buffer[i];
62
_current_character = 0;
65
_current_character ++;
68
// Выпиливаем неактуальное
69
_buffer = _buffer.substr(length);
72
return putCharToBuffer();
77
TokenLocation Scanner::makeTokenLocation() const
79
return {_uri_index,{_token_start_line,_token_start_character,_current_line,_current_character}};
82
void Scanner::fixLocation(context_index_t context_index)
84
_token_start_line = _current_line;
85
_token_start_character = _current_character;
86
_token_context_index = context_index;
89
bool Scanner::startsWith(char16_t ch)
93
if (_is_end_of_file_reached || _input.eof())
96
bool ok = putCharToBuffer();
98
return false; // Достигли конца потока
101
return (_buffer[0] == ch);
104
bool Scanner::startsWith(const std::u16string &str)
109
while(_buffer.size() < str.size())
111
if (_is_end_of_file_reached || _input.eof())
114
bool ok = putCharToBuffer();
116
return false; // Достигли конца потока
119
return (_buffer.compare(0,str.size(),str) == 0);
122
bool Scanner::startsWithAnyOf(const std::u16string &str)
129
if (_is_end_of_file_reached || _input.eof())
132
bool ok = putCharToBuffer();
134
return false; // Достигли конца потока
137
return (str.find(_buffer[0]) != std::u16string::npos);
140
char16_t Scanner::getFirstChar(void)
145
char16_t Scanner::getChar(size_t pos)
147
while(_buffer.size() < pos+1)
149
if (_is_end_of_file_reached || _input.eof())
150
return std::char_traits<char16_t>::eof();
152
bool ok = putCharToBuffer();
154
return std::char_traits<char16_t>::eof(); // Достигли конца потока