Вам нужна система преобразования программ. Это инструменты, которые обычно позволяют вам выражать изменения в исходном коде, написанные в шаблонах исходного кода, которые, по сути, говорят:
if you see *this*, replace it by *that*
но работа с абстрактными синтаксическими деревьями, поэтому процесс сопоставления и замены гораздо более надежен, чем то, что вы получаете при взломе строк.
Такие инструменты должны иметь синтаксические анализаторы интересующего исходного языка. Исходный язык C++ делает это довольно сложным.
Clang подходит; в конце концов, он может анализировать C++. Объекты OP, он не может этого сделать без всего контекста среды. В той мере, в какой OP вводит (правильно сформированные) фрагменты программы (операторы и т. д.) в интерпретатор, Clang может [у меня нет большого опыта работы с этим] иметь проблемы с фокусировкой на том, что представляет собой фрагмент (оператор «выражение» объявление? ...). Наконец, Clang на самом деле не PTS; его процедуры модификации дерева не являются преобразованиями источника в источник. Это важно для удобства, но может не помешать OP использовать его; правило перезаписи синтаксиса поверхности удобно, но вы всегда можете заменить процедурный взлом дерева с большим усилием. Когда правил больше, чем несколько, это начинает иметь большое значение.
GCC с Melt квалифицируется так же, как и Clang. У меня сложилось впечатление, что Melt делает GCC в лучшем случае менее невыносимым для такой работы. YMMV.
Наш набор инструментов для реинжиниринга программного обеспечения DMS с его полный интерфейс C++14 [EDIT July 2018: C++17] абсолютно подходит. DMS использовался для выполнения массовых преобразований в крупномасштабных кодовых базах C++.
DMS может разбирать произвольные (правильно сформированные) фрагменты C++, не сообщая заранее, что такое синтаксическая категория, и возвращать AST надлежащего грамматического нетерминального типа, используя его механизм разбора шаблонов. [Вы можете получить несколько синтаксических анализов, например. двусмысленности, которые вы должны решить, как решить, см. 1004737">Почему C++ не может быть проанализирован с помощью синтаксического анализатора LR(1)? для более подробного обсуждения] Он может сделать это, не прибегая к «окружению», если вы готовы жить без раскрытия макросов во время синтаксического анализа, и настаивайте на том, чтобы директивы препроцессора (они тоже анализировались) были хорошо структурированы по отношению к фрагменту кода (#if foo{#endif не разрешено), но вряд ли это реальная проблема для фрагментов кода, введенных в интерактивном режиме.
Затем DMS предлагает полную процедурную библиотеку AST для манипулирования проанализированными деревьями (поиск, проверка, изменение, построение, замена), а затем может регенерировать поверхностный исходный код из модифицированного дерева, предоставляя текст OP для передачи интерпретатору.
В этом случае блестит то, что OP, вероятно, может написать большинство своих модификаций непосредственно в виде правил синтаксиса от источника к источнику. Для своего примера он может предоставить DMS правило перезаписи (непроверенное, но довольно близкое к правильному):
rule replace_Draw(A:primary,B1:expression,B2:expression):
primary->primary
"\A->Draw(\B1, \B2)" -- pattern
rewrites to
"MyFunc(\A, \B1, \B2)"; -- replacement
и DMS возьмет любой проанализированный AST, содержащий левосторонний шаблон "...Draw...", и заменит это поддерево правой частью после замены совпадений для A, B1 и B2. Кавычки являются метакавычками и используются, чтобы отличить текст C++ от текста правил синтаксиса; обратная косая черта — это метаэкранирование, используемое внутри метакавычек для обозначения метапеременных. Дополнительные сведения о том, что вы можете указать в синтаксисе правила, см. в правилах перезаписи DMS.
Если OP предоставляет набор таких правил, можно попросить DMS применить весь набор.
Так что я думаю, что это отлично сработает для OP. Это довольно тяжелый механизм для «дополнения» к пакету, который он хочет предоставить третьей стороне; DMS и его интерфейс C++ вряд ли можно назвать "маленькими" программами. Но тогда у современных машин много ресурсов, поэтому я думаю, что вопрос в том, насколько сильно OP нужно это делать.
person
Ira Baxter
schedule
28.01.2016
Draw
в одной и той же строке? (A->Draw(...)->...->Draw(...)
)? - person Alexander Feterman   schedule 26.08.2015A->Draw(B); C->Draw(D)
илиfunc(A->Draw(B), C->Draw(D))
. Повторных вызовов шаблона, который вы показали, не произойдет, так какDraw
возвращает целочисленное значение. - person Eldritch Cheese   schedule 28.08.2015A->Draw(B1, B2)
? - person serge-sans-paille   schedule 31.08.2015