19 марта состоялся выпуск C++ библиотеки Lug, реализующей встраиваемый предметно-ориентированный язык для выражения синтаксических анализаторов в виде расширенных грамматик синтаксических выражений, и распространяемой по лицензии MIT.
Возможности библиотеки:
- Естественный синтаксис, напоминающий языки внешних генераторов парсеров, с поддержкой атрибутов и семантических действий.
- Возможность работы с контекстно-зависимыми грамматиками с таблицами символов, условиями и синтаксическими предикатами.
- Сгенерированные парсеры компилируются в байткод и выполняются в виртуальной машине синтаксического анализа.
- Чёткое разделение синтаксических и лексических правил с возможностью настройки неявного пропуска пробельных символов.
- Поддержка прямой и косвенной левой рекурсии, с уровнями старшинства для разграничения подвыражений со смешанными левой и правой рекурсиями.
- Полная поддержка разбора текста в формате UTF-8, включая уровень 1 и частичное соответствие уровню 2 технического стандарта UTS #18 Unicode Regular Expressions.
- Обработка ошибок и восстановление с помощью помеченных сбоев, правил восстановления и обработчиков ошибок.
- Автоматическое отслеживание номеров строк и колонок, настраиваемая ширина и выравнивание табуляции.
- Header-only-библиотека, использующая только стандартную библиотеку и возможности стандарта C++17. Перспективно совместима со стандартами C++20 и C++23.
- Относительно небольшой размер библиотеки, с целью содержания общего количества строк во всех заголовочных файлах на уровне менее 6000 строк лаконичного кода.
Список изменений:
- Реализованы директивы коллекций и атрибутов объектов. Новая директива
collect<C>[e]
синтезирует последовательность или ассоциативный контейнер типаC
, состоящий из элементов, собранных из унаследованных или синтезированных атрибутов в выраженииe
. Аналогично, появились новые директивыsynthesize<C,A...>[e], synthesize_shared<C,A...>[e]
иsynthesize_unique<C,A...>[e]
для синтеза объектов, общих указателей и уникальных указателей соответственно, построенных из атрибутов компонентов в выраженииe
. - Реализована директива
synthesize_collect
, которая объединяет директивыcollect
иsynthesize
для улучшения читаемости кода и уменьшения количества шаблонов при построении сложных структур данных из разобранных элементов. Это особенно полезно для создания вложенных коллекций, таких как массивы объектов или ассоциативные контейнеры со сложными типами значений. - Добавлен шаблонный класс
lug::recursive_wrapper
для обработки циклических зависимостей в деревьях абстрактного синтаксиса, в частности, использующихstd::variant
. - Реализована поддержка стандарта Unicode 16.0.0 и добавлена поддержка инструментов сборки в
CMakeLists.txt
. - Оптимизировано сопоставление диапазона и набора ASCII-символов, что привело к значительному увеличению производительности при выполнении распространённых операций обработки текста. Добавлены специализированные быстрые способы для обработки только ASCII-символов, которые значительно быстрее кода обработки Unicode.
- Реализованы опкоды
test
для оптимизации ошибок и опкодыrepeat
для оптимизации пропуска пробельных символов. Эти оптимизации будут полностью включены в следующем выпуске после запланированных преобразований дерева выражений. - Улучшена обработка источников ввода с улучшенной буферизацией и отчетом об ошибках для
std::istream
, а также улучшена поддержка интерактивного режима, которая корректно обрабатывает построчный ввод для терминальных сессий или для линейно-ориентированных грамматик. - Поддержка
std::istream
перемещена в отдельный заголовочный файл<lug/iostream.hpp>
. Это сокращает время компиляции и минимизирует зависимости от заголовков для проектов, которым не требуется функциональность потокового ввода/вывода. - Переработана логика фиксации парсера путем инлайнинга инструкций в
lug::basic_parser
для лучшего соответствия изменениям архитектуры стекового фрейма, представленным в версии 0.4.0, что улучшило организацию кода и производительность. - Исправлена проблема в примере парсера BASIC, когда пользовательские функции (например,
FNA(X))
завершались во время оценки. Это было вызвано изменениями в версии 0.4.0, которые сбрасывалиlug::environment
во время вложенных операций синтаксического анализа. Добавлена новая функцияlug::environment::should_reset_on_parse
для обеспечения тонкого контроля над этим поведением, позволяя окружению сохраняться во время вложенных операций разбора, когда это необходимо. - Добавлена комплексная инфраструктура тестирования примеров программ.
- Перестроена иерархия каталогов
include
. - Для обеспечения более широкой совместимости в GitHub CI добавлена поддержка дополнительных компиляторов (GCC 9/10/11/12, Clang 14/15/16/17).
- В GitHub CI добавлены статические анализаторы Clang и MSVC.
- В GitHub CI добавлены Address Sanitizer (ASan), Undefined Behavior Sanitizer (UBSan) и Memory Sanitizer (MSan).
- В GitHub CI добавлена интеграция
clang-tidy
. - В GitHub CI удалено использование Ubuntu 20.04.