19 marca wydano bibliotekę C++ Lug, implementującą wbudowany język ukierunkowany na przedmioty do wyrażania parserów w postaci rozszerzonych gramatyk wyrażeń syntaktycznych, dostępną na licencji MIT.
Możliwości biblioteki:
- Naturalna składnia przypominająca języki zewnętrznych generatorów parserów, z obsługą atrybutów i działań semantycznych.
- Możliwość pracy z gramatykami kontekstowo-zależnymi z tabelami symboli, warunkami i predykatami syntaktycznymi.
- Wygenerowane parsery są kompilowane do bajtowego kodu i wykonywane w maszynie wirtualnej analizy składni.
- Wyraźny podział reguł syntaktycznych i leksykalnych z możliwością dostosowania niejawnego pomijania białych znaków.
- Wsparcie dla bezpośredniej i pośredniej lewej rekursji, z priorytetami do rozgraniczenia podwyrażeń z mieszanymi lewymi i prawymi rekursjami.
- Pełne wsparcie dla analizy tekstu w formacie UTF-8, w tym poziom 1 oraz częściowe pokrycie poziomu 2 normy technicznej UTS #18 Wyrażenia regularne Unicode.
- Obsługa błędów i odzyskiwanie za pomocą oznaczonych błędów, zasad odzyskiwania i obsługujących błędy.
- Automatyczne śledzenie numerów linii i kolumn, konfigurowalna szerokość i wyrównanie tabulatorów.
- Biblioteka tylko nagłówkowa, korzystająca wyłącznie z standardowej biblioteki i możliwości standardu C++17. Dobrze współpracuje ze standardami C++20 i C++23.
- Relatywnie mały rozmiar biblioteki, z celem utrzymania ogólnej liczby linii we wszystkich plikach nagłówkowych poniżej 6000 linii zwięzłego kodu.
Lista zmian:
- Zrealizowano dyrektywy kolekcji i atrybutów obiektów. Nowa dyrektywa collect<C>[e] syntetyzuje sekwencję lub asocjacyjny kontener typu C, składający się z elementów zebranych z odziedziczonych lub syntetyzowanych atrybutów w wyrażeniu e. Podobnie, pojawiły się nowe dyrektywy synthesize<C,A…>[e], synthesize_shared<C,A…>[e] oraz synthesize_unique<C,A…>[e] do syntezy obiektów, współdzielonych wskaźników i unikalnych wskaźników odpowiednio, budowanych z atrybutów komponentów w wyrażeniu e.
- Wprowadzono dyrektywę synthesize_collect, która łączy dyrektywy collect i synthesize, aby poprawić czytelność kodu i zmniejszyć liczbę szablonów podczas budowania złożonych struktur danych z analizowanych elementów. Jest to szczególnie przydatne w tworzeniu zagnieżdżonych kolekcji, takich jak tablice obiektów lub asocjacyjne kontenery ze złożonymi typami wartości.
- Dodana została klasowa szablonowa lug::recursive_wrapper do obsługi cyklicznych zależności w drzewach abstrakcyjnej składni, szczególnie korzystających z std::variant.
- Wdrożono wsparcie dla standardu Unicode 16.0.0 i dodano wsparcie dla narzędzi budowy w CMakeLists.txt.
- Optymalizacja dopasowania zakresu i zestawów znaków ASCII, co doprowadziło do znacznego wzrostu wydajności podczas wykonywania powszechnych operacji przetwarzania tekstu. Dodano specjalizowane szybkie metody do przetwarzania tylko znaków ASCII, które są znacznie szybsze niż kod przetwarzający Unicode.
- Wdrożono kody operacyjne test do optymalizacji błędów oraz kody operacyjne repeat do optymalizacji pomijania znaków białych. Te optymalizacje zostaną w pełni wprowadzone w następnej wersji po zaplanowanych transformacjach drzewa wyrażeń.
- Udoskonalono przetwarzanie źródeł wejściowych z ulepszonym buforowaniem i raportowaniem błędów dla std::istream, a także poprawiono wsparcie dla trybu interaktywnego, które poprawnie obsługuje wprowadzanie linii dla sesji terminalowych lub dla gramatyk liniowo-orientowanych.
- Wsparcie dla std::istream przeniesiono do osobnego pliku nagłówkowego . Skraca to czas kompilacji i minimalizuje zależności od nagłówków dla projektów, które nie wymagają funkcjonalności strumieni wejścia/wyjścia.
- Przeprojektowano logikę zatrzymywania parsera poprzez inline'owanie instrukcji w lug::basic_parser, aby lepiej dostosować się do zmian w architekturze stosu, przedstawionych w wersji 0.4.0, co poprawiło organizację kodu i wydajność.
- Naprawiono problem w przykładzie parsera BASIC, gdy funkcje użytkownika (np. FNA(X)) kończyły się podczas oceny. Było to spowodowane zmianami w wersji 0.4.0, które resetowały lug::environment podczas zagnieżdżonych operacji analizy składni. Dodano nową funkcję lug::environment::should_reset_on_parse, aby zapewnić precyzyjną kontrolę nad tym zachowaniem, umożliwiając zachowanie środowiska podczas zagnieżdżonych operacji analizy, gdy jest to konieczne.
- Dodano złożoną infrastrukturę testowania przykładów programów.
- Przebudowano hierarchię katalogów include.
- Aby zapewnić szerszą kompatybilność w GitHub CI, dodano wsparcie dla dodatkowych kompilatorów (GCC 9/10/11/12, Clang 14/15/16/17).
- Do GitHub CI dodano statyczne analizatory Clang i MSVC.
- W GitHub CI dodano Address Sanitizer (ASan), Undefined Behavior Sanitizer (UBSan) oraz Memory Sanitizer (MSan).
- W GitHub CI dodano integrację clang-tidy.
- W GitHub CI usunięto użycie Ubuntu 20.04.
Źródło: linux.org.ru
