4
Copyright (c) 2021 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,
6
https://bmstu.codes/lsx/simodo
9
/*! \file Утилита тестирования средств лексического анализа библиотеки SIMODO core. Проект SIMODO.
12
#include "simodo/inout/token/FileStream.h"
13
#include "simodo/inout/token/RefBufferStream.h"
14
#include "simodo/inout/token/Tokenizer.h"
15
#include "simodo/inout/convert/functions.h"
24
using namespace simodo;
29
int produceLexicalAnalysis (const std::string & file_name, bool use_string_buffer, const inout::LexicalParameters & lex_param)
31
std::ifstream in(file_name);
32
std::u16string string_buffer;
33
std::unique_ptr<inout::InputStream_interface> stream;
37
std::cout << "Ошибка при открытии файла '" << file_name << "'" << std::endl;
41
if (use_string_buffer)
43
inout::InputStream in_stream(in);
47
char16_t ch = in_stream.get();
48
if (ch == std::char_traits<char16_t>::eof())
53
stream = std::make_unique<inout::RefBufferStream>(string_buffer.data());
56
stream = std::make_unique<inout::InputStream>(in);
58
inout::Tokenizer tzer(0, *stream, lex_param);
60
uint32_t comment_n = 0;
61
uint32_t annotation_n = 0;
62
uint32_t punctuation_n = 0;
63
uint32_t keyword_n = 0;
65
uint32_t word_national_mix_error_n = 0;
66
uint32_t word_national_use_error_n = 0;
67
uint32_t number_n = 0;
68
uint32_t number_wrong_n = 0;
71
uint32_t token_count = 0;
73
inout::Token t = tzer.getAnyToken();
75
while (t.type() != inout::LexemeType::Empty)
81
case inout::LexemeType::Punctuation:
83
if (t.qualification() == inout::TokenQualification::Keyword)
86
case inout::LexemeType::Id:
88
if (t.qualification() == inout::TokenQualification::NationalCharacterMix)
89
word_national_mix_error_n ++;
91
case inout::LexemeType::Annotation:
94
case inout::LexemeType::Number:
96
if (t.qualification() == inout::TokenQualification::NotANumber)
99
case inout::LexemeType::Comment:
102
case inout::LexemeType::Error:
104
if (t.qualification() == inout::TokenQualification::NationalCharacterMix)
105
word_national_mix_error_n ++;
106
if (t.qualification() == inout::TokenQualification::NationalCharacterUse)
107
word_national_use_error_n ++;
114
inout::Location loc = t.makeLocation({file_name});
116
std::cout << loc.uri()
117
<< ":" << loc.range().start().line() << "/" << loc.range().start().character()
118
<< "-" << loc.range().end().line() << "/" << loc.range().end().character() << ", token: \""
119
<< simodo::inout::toU8(t.token()) << "\"";
121
if (t.token() != t.lexeme())
122
std::cout << ", lexeme: \"" << inout::toU8(t.lexeme()) << "\"";
124
std::cout << ", type: " << getLexemeTypeName(t.type());
126
if (t.qualification() != inout::TokenQualification::None)
127
std::cout << ", qualification: " << getQualificationName(t.qualification());
129
std::cout << std::endl;
131
t = tzer.getAnyToken();
134
std::cout << "ИТОГО: токенов ..... " << token_count << std::endl
135
<< " комментариев. " << comment_n << std::endl
136
<< " аннотаций ... " << annotation_n << std::endl
137
<< " пунктуаций .. " << punctuation_n << " (из них ключевых слов: " << keyword_n << ")" << std::endl
138
<< " слов ........ " << word_n << " (из них с перемешанными алфавитами: " << word_national_mix_error_n << ")" << std::endl
139
<< " чисел ....... " << number_n << " (из них с ошибками: " << number_wrong_n << ")" << std::endl
140
<< " ошибок ...... " << error_n <<
141
" (из них с недопустимым алфавитом: " << word_national_use_error_n << "," <<
142
" c перемешанными алфавитами: " << word_national_mix_error_n << ")" << std::endl
143
<< " сбоев ....... " << unknown << std::endl
150
int main(int argc, char *argv[])
152
/// @todo Переделать работу с аргументами командной строки на использование
153
/// класса utility::SafeParameters
155
std::vector<std::string> arguments(argv + 1, argv + argc);
157
std::string file_name = "";
158
bool use_char16_buffer = false;
163
std::vector<inout::NumberMask> masks;
165
for(size_t i=0; i < arguments.size(); ++i)
167
const std::string & arg = arguments[i];
171
if (arg == "--help" || arg == "-h")
173
else if (arg == "--use-char16-buffer")
174
use_char16_buffer = true;
175
else if (arg == "--number_mask" || arg == "-n")
177
if (i+2 >= arguments.size())
180
masks.push_back({inout::toU16(arguments[i+1]),
181
inout::LexemeType::Number,
182
static_cast<inout::number_system_t>(stoi(arguments[i+2]))});
189
else if (file_name.empty())
195
if (!help && file_name.empty())
200
std::cout << "Ошибка в параметрах запуска" << std::endl;
205
std::cout << "Утилита лексического анализа. Проект SIMODO." << std::endl
206
<< "Формат запуска:" << std::endl
207
<< " <имя утилиты> [<параметры>] <файл>" << std::endl
208
<< "Параметры:" << std::endl
209
<< " -h | --help - отображение подсказки по запуску программы" << std::endl
210
<< " --use-char16-buffer - провести лексический анализ заданного файла с использованием строкового буфера" << std::endl
211
<< " -n | --number_mask <маска> <система счисления> - добавить маску числа" << std::endl
217
if (file_name.empty())
220
inout::LexicalParameters lex_param {
222
{u"/*", u"*/", u"", inout::LexemeType::Comment},
223
{u"//", u"", u"", inout::LexemeType::Comment},
224
{u"\"", u"\"", u"\\", inout::LexemeType::Annotation},
225
{u"'", u"'", u"\\", inout::LexemeType::Annotation},
229
{u"_",u"_Nebuchadnezzar_II",u"ФУ_"},
231
u"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
232
u"абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",
239
for(const inout::NumberMask & m : masks)
240
lex_param.masks.push_back(m);
242
return produceLexicalAnalysis(file_name, use_char16_buffer, lex_param);