## tokenizer Токенайзер - простой пакет для разбиения строки на токены. Задача, которую он решает - разбиение строки на токены, по определенной спецификации. ### Примеры использования Разбиение простой строки `1,2,3` на токены: ```bsl Строка = "1,2,3"; Спека = Новый Массив(); Спека.Добавить(Новый СпецификацияТокенЧисло()); Спека.Добавить(Новый СпецификацияТокенСимвол(",", "Запятая")); Токенайзер = Новый Токенайзер(Спека); Токенайзер.Инит(Строка); Результат = Новый Массив(); Пока Токенайзер.ЕстьЕщеТокены() Цикл Результат.Добавить(Токенайзер.СледующийТокен()); КонецЦикла; ``` В результате выполнения этого кода массив `Результат` будет содержать пять элементов с типом `Токен`. ### API #### API объекта `Токен` следующий: 1. `Значение()` - возвращает значение токена. 2. `ТипТокена()` - возвращает тип токена. 3. `Начало()` - возвращает позицию токена в тексте. 4. `Размер()` - возвращает длину токена в тексте. #### API объекта `Токенайзер` следующий: 1. `Инит(Строка)` - инициализирует Токенайзер строкой. 2. `СледующийТокен()` - возвращает следующий токен. 3. `ЕстьЕщеТокены()` - возвращает `Истина`, если есть еще токены. В конструктор `Токенайзер` передается спецификация токенов. Спецификация токенов - это массив объектов, реализующих интерфейс `СпецификацияТокена`. Интерфейс `СпецификацияТокена` описывает следующие методы: ```bsl Функция Проверить(Знач Строка) Экспорт Если УдалосьНайтиТокенВСтроке Тогда Возврат Новый Структура("Значение, Размер", "ЗначениеТокена", ДлинаТокена); КонецЕсли; Возврат Неопределено; КонецФункции Функция ТипТокена() Экспорт Возврат "МойКастомныйТипТокена"; КонецФункции ``` ### "Типовые" токены Поставляемые вместе с пакетом спецификации токенов: 1. `СпецификацияТокенСимвол` - спецификация токена, который содержит один символ. В конструктуор передается символ и тип токена. 2. `СпецификацияТокенЧисло` - спецификация токена, который содержит целое число. 3. `СпецификацияТокенСтрока` - спецификация токена, который содержит строку. В конструктор передается экранирующий внутренние ковычки символ. Поддерживаемые экранируемые символы: `\`, `""""`. 4. `СпецификацияТокенИдентификатор` - спецификация токена, который содержит идентификатор, т.е. строка начинающаяся с буквы и содержит буквы и цифры. 5. `СпецификацияТокенПробелы` - спецификация токена, который содержит пробел. В конструктор передается флаг, который указывает, нужно ли пропускать пробелы или нет. 6. `СпецификацияТокенРегулярноеВыражение` - спецификация токена, который содержит строку, соответствующую регулярному выражению. В конструктор передается регулярное выражение и тип токена. ### Пример токенизации и парсинга журнала регистрации `small.lgp` ``` 1CV8LOG(ver 2.0) 758d6f0a-476f-468b-80ac-48773092049c {20221110000049,N, {2444a6a24da10,3d},1,1,1,1803214,81,I,"Первое событие",599, {"U"},"Представление данных",1,1,9,3,0, {0} }, {20221110000049,U, {2444a6a24da10,3d},1,1,1,1803214,81,E,"Второе ""событие"" многострочное ",599, {"U"},"Представление данных2",1,1,9,3,0, {2,1,31,2,31} } ``` `ПарсерСкобки.os` ```bsl Перем _Токенайзер; Перем ПрошлиЗаголовок; Процедура ПриСозданииОбъекта(Токенайзер) _Токенайзер = Токенайзер; ПрошлиЗаголовок = Ложь; КонецПроцедуры Функция Распарсить() Экспорт ТекущийМассив = Новый Массив(); Пока _Токенайзер.ЕстьЕщеТокены() Цикл Токен = _Токенайзер.СледующийТокен(); Если ПрошлиЗаголовок = Ложь И Не Токен.ТипТокена() = "Открыть" Тогда Продолжить; КонецЕсли; ПрошлиЗаголовок = Истина; Если Токен.ТипТокена() = "Открыть" Тогда ТекущийМассив.Добавить(Распарсить()); Продолжить; КонецЕсли; Если Токен.ТипТокена() = "Идентификатор" ИЛИ Токен.ТипТокена() = "Число" ИЛИ Токен.ТипТокена() = "Строка" Тогда ТекущийМассив.Добавить(Токен.Значение()); КонецЕсли; Если Токен.ТипТокена() = "Закрыть" Тогда Возврат ТекущийМассив; КонецЕсли; КонецЦикла; Возврат ТекущийМассив; КонецФункции ``` `Main.os` ```bsl Спека = Новый Массив(); Спека.Добавить(Новый СпецификацияТокенПробелы(Истина)); Спека.Добавить(Новый СпецификацияТокенСимвол("{", "Открыть")); Спека.Добавить(Новый СпецификацияТокенСимвол("}", "Закрыть")); Спека.Добавить(Новый СпецификацияТокенСимвол(",", "Запятая")); Спека.Добавить(Новый СпецификацияТокенРегулярноеВыражение(Новый РегулярноеВыражение("(1CV8LOG)|(\(\w+ \d.\d\))"), "Версия")); Спека.Добавить(Новый СпецификацияТокенРегулярноеВыражение(Новый РегулярноеВыражение("[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$"), "Гуид")); Спека.Добавить(Новый СпецификацияТокенРегулярноеВыражение(Новый РегулярноеВыражение("[\da-z]+"), "Идентификатор")); Спека.Добавить(Новый СпецификацияТокенСтрока()); Спека.Добавить(Новый СпецификацияТокенЧисло()); Спека.Добавить(Новый СпецификацияТокенСимвол(Символы.ПС, "ПереносСтроки")); Токенайзер = Новый Токенайзер(Спека); ЧтениеТекста = Новый ЧтениеТекста("small.lgp"); Текст = ЧтениеТекста.Прочитать(); ЧтениеТекста.Закрыть(); Токенайзер.Инит(Текст); Скобарь = Новый ПарсерСкобки(Токенайзер); Результат = Скобарь.Распарсить(); ``` Результатом парсинга будет массив, содержащий записи ЖР, каждая запись - массив, содержащий поля записи. С поддержкой вложенности массивов.