QapGen: Создаём мощные парсеры на C++
QapDSLv2 — это язык который транслируется в обычный C++ код. Он позволяет удобно и компактно задавать грамматики/правила разбора кода программ, значительно упрощая разработку компиляторов/анализаторов/трансляторов. QapGen — это генератор дерева_лексеров /парсеров описанных на QapDSLv2. Сама грамматика QapDSLv2 описана на QapDSLv2 на 100%. Поэтому QapGen как основной читатель этой грамматики сам генерирует часть своего кода(весь парсер QapDSLv2). Основные фишки QapDSLv2 + QapGen — это: 1) Отсутствие этапа токенизации — дерево лексеров разбивает входной поток на лексемы и сохраняет их в строго типизированных древовидных С++ структурах пропуская этап токенизации. 2) Генерация оптимизированного кода полиморфных лексеров . 3) Полное сохранение всех лексем(даже разделители сохраняются, такие как пробелы/переходы на новую строку и комментарии) в результирующем дереве. 4) Возможность сохранить как оригинальное дерево , так и модифицированное обратно в код/текст без потери разделителей/комментариев . 5) Автоматическая генерация кода посетителей (это такой паттерн проектирования). А теперь пример самой сочной части(рекурсивно самоописывающийся код): struct t_target_struct:i_target_item{ struct t_keyword{ string kw=any_str_from_vec(split("struct,class",",")); " "? // optional separator }; struct t_body_semicolon:i_struct_impl{";"}; struct t_body_impl:i_struct_impl{ "{" // жрём скобочку vector<TAutoPtr<i_target_item>> nested?; // рекурсия! " "? vector<TAutoPtr<i_struct_field>> arr?; // парсим поля " "? TAutoPtr<t_cpp_code> c?; // остальной С++ код " "? "}" }; struct t_parent{ string a_or_c=any_str_from_vec(split("=>,:",",")); " "? t_name name; }; //точка входа в парсер: TAutoPtr<t_keyword> kw?; //парсим struct/class t_name name; //парсим имя " "? TAutoPtr<t_parent> parent?; " "? TAutoPtr<i_struct_impl> body; };
https://habr.com/ru/articles/925420/
#parser #parsergenerator #lexers #c++ #tree #ast #gamedev #dsl #compiler