Бизон хорош в разборе, и с некоторой ручной помощью, хорош в построении собственного синтаксического дерева.После этого вам решать, что вы хотите с деревом.Хорошая новость в том, что вы можете делать все, что захотите.Плохая новость заключается в том, что вам все равно придется создавать множество механизмов, чтобы делать то, что вы хотите.Ваша основная проблема восстановления исходного кода называется «prettyprinting»;см. мой SO ответ о том, как довольно распечатать , чтобы понять, что нужно для этого, включая все peccadillos лексического синтаксиса (вы не потеряете escape-символы в своих строковых строках, верно?).Вы вообще не задались вопросом, как найти конструкцию, которую вы хотите изменить в дереве, или как разбить дерево, чтобы изменить его.
Если вы не хотите делать все это,тогда вам действительно нужна система преобразования программ , которая хороша в разборе, построении синтаксического дерева для вас (так что вам не нужно об этом думать, SQL - довольно большая грамматика), позволитвы находите шаблоны в дереве с точки зрения используемого вами синтаксиса SQL, вносите изменения в дерево, не зная много о форме дерева, и, наконец, можете восстановить действительный исходный текст с помощью prettyprint, как я описал в моей ссылке на ответ выше.(Системы преобразования программ по существу включают в себя синтаксический анализатор в качестве подпрограммы.)
Наш набор инструментов для реинжиниринга программного обеспечения DMS является такой системой преобразования программ.Он имеет набор предопределенных определений языка , включая SQL2011 и средства для настройки для определенного диалекта.Используя синтаксические правила от источника к источнику DMS, вы можете выполнить изменение в вашем примере с помощью следующего правила:
domain SQL;
rule trim_c_members(f: identifier, s: string):condition->condition
= " c.\f = \s " -> " c.\f = trim(\s) ";
Это синтаксис языка (мета) правил DMS для описания перезаписи на ("домен")SQL-кодУ правила есть имя (потому что в сложном приложении есть много правил), и это как синтаксические заполнители "f" и "s";он переписывает только условия в коде.Кавычки являются мета-кавычками RSL;внутри есть SQL с метавариями RSL "\ f" и "\ s";вещи вне синтаксиса правила RSL.Правило гласит: «для любого условия в переменной, явно названной« c », с любым полем f, если это поле сравнивается по равенству с некоторой литеральной строкой, то замените литеральную строку на« trim », примененную к литеральной строке».
Я пропустил некоторый код, который в основном говорит: «Примени это правило ко всему дереву и не применяй его дважды в одном и том же месте».Эта «стратегия» является одной из многих встроенных в DMS.
Существует вопрос о том, как работает правило.это достигается с помощью DMS, применяющей синтаксический анализатор SQL к строкам мета-кавычек, для создания синтаксических деревьев «шаблонов» с заполнителями, в которые записываются мета-переменные.Затем дерево шаблонов левой стороны сопоставляется с целевым деревом, а заполнитель ссылается на поддеревья;правое дерево объединяется в том месте, где левое дерево совпадает, а поддерево перемещается.Итак, вы, программист, видите поверхностный синтаксис, который вы знаете и любите;инструмент работает с деревьями, поэтому его не смущает текст.
Так вот, я не думаю, что мое правило точно соответствует вашим намерениям, но это отчасти потому, что я не могу угадать ваши настоящие намерения.Вы можете написать другие правила, если это не то, что вы хотели.
Это правило основано исключительно на синтаксисе;Можно добавить семантический предикат (не показан), если вы хотите, чтобы к правилу применялись более сложные условия (например, переменные должны быть единицами только в определенных областях, которые вы определяете), и это становится более беспорядочным.Но это намного проще и намного проще для чтения, чем код C, который поднимается по AST (заметьте, что вы не видели AST здесь?) И пытается все это выяснить.
Анализ и симпатичная печать происходят раньшеи после применения правила;для реализации всего этого требуется много механизмов, но этот механизм встроен в DMS (например, он имеет нечто вроде [но более мощного], чем встроенный Bison), а для предопределенных доменов, таких как SQL, все симпатичные печатные работы имеютбыл предварительно настроен тоже.
Если вы хотите лучше понять, что нужно для полного цикла с DMS (определите свой собственный анализатор языка, определите симпатичный принтер, определите сложные правила), вот хороший и полный пример определениясимволически упрощенное исчисление с использованием DMS.