Наш инструментарий реинжиниринга программного обеспечения DMS с C ++ Front End может сделать это довольно легко.Да, он коммерческий, но я не думаю, что есть много некоммерческих реальных решений для вашей задачи.
DMS - это механизм преобразования программ , который анализирует, анализирует и преобразует код в соответствии спредоставленное определение языка.Его интерфейс C ++ является определением языка для различных диалектов C ++.Как часть процесса синтаксического анализа для C ++, DMS может создавать таблицы символов с точностью до компилятора.Это необходимо для задачи OP, чтобы отличить неоднозначный синтаксис, который может быть заявлением, от альтернативных объявлений, которые может представлять такой синтаксис.(См. Почему C ++ не может быть проанализирован с помощью синтаксического анализатора LR (1)? для примеров этого).
Значение в DMS для этой задачи состоит в том, что она разрешает источник висходные преобразования, применяемые к абстрактным синтаксическим деревьям, создаваемым синтаксическим анализом.Следующее правило DMS, написанное в синтаксисе DMS rule , вероятно, будет очень близко к тому, что нужно OP:
domain Cpp~ANSI;
rule instrument_statements(s: executable_statement):
executable_statement->executable_statement
" \s " -> " { \s ; post_statement_call(); } "
Текст внутри meta quotes " ... " - это целевой домен синтаксис, в данном случае ANSI C ++. \ - это meta escape; \ s представляет любой исполняемый оператор .Это правило выполняет сопоставление всех синтаксических executeable_statements и заменяет их блоком из двух операторов, первый из которых является исходным оператором, а второй - тем, что OP хочет сделать после каждого оператора.Я предполагал, что OP просто хотел вызвать функцию, но он может захотеть чего-то более сложного, например, печати номеров строк, имен функций или параметров функций [требующих некоторых дополнительных правил преобразования].
Сопоставление с шаблоном и преобразование выполняются с использованием синтаксических синтаксических деревьев, поэтому его нельзя спутать с наличием чего-либо, похожего на код в строке, или комментария, или на самом деле не исполняемого и не исполняемогооператор (например, декларация) и т. д. [Есть небольшая деталь, которую я замаскировал, чтобы предотвратить рекурсивное применение этого правила к его результатам, но эта деталь легко управляется с помощью API-интерфейсов DMS]. После преобразования измененное синтаксическое деревопреобразован в скомпилированный исходный текст C ++.OP скомпилирует и запустит этот код вместо своего исходного кода.
Обратите внимание, что post_statement фактически не должен ничего печатать.Если он вызывает центральную функцию, OP может кодировать любые предикаты / операторы печати, которые он хочет контролировать, количество вывода / накладных расходов, которое использует post_statement.По сути, это может выступать в качестве программируемой точки останова.
Эта базовая идея вставки проб с помощью трансформационных методов используется в нашей линейке инструментов для тестирования покрытия и профилирования COTS, все из которых основаны непосредственно на DMS, включая нашу C ++ Test Coverage Tool .Для получения более подробной информации см. http://www.semdesigns.com/Company/Publications/TestCoverage.pdf
OP, вероятно, может найти использование нашего инструмента покрытия теста простым способом сделать что-то довольно близкое, но более легкое в выполнении. Инструмент тестирования покрытия вставляет специальные операторы захвата данных трассировки в начало каждого блока (безусловного) кода, а не после каждого отдельного оператора. Этот сбор данных трассировки на самом деле является вызовом макроса, код которого мы предоставляем в виде исходного кода как часть продукта покрытия тестирования. Хотя это и не предполагаемое использование, можно просто заменить этот макро-вызов на желаемую трассировку, и инструмент покрытия тестов фактически вставит желаемый код туда, где он поместил бы зонды. Вероятно, он все еще может зафиксировать имя функции и уникальную кодовую точку [инструмент тестирования покрытия производит их] в качестве замены для номера строки. То, что он не мог сделать, - это более сложные задачи, которые были бы возможны с собственно DMS. Например, нет никакого способа, которым макрос трассировки может получить в свои руки исходный номер строки; это теряется к тому времени, когда макрос вводится инструментом покрытия теста. (С DMS это не потеряно). Но есть способ преобразовать «уникальную кодовую точку» обратно в точную информацию о местоположении источника.
РЕДАКТИРОВАТЬ 7/10/2011: ОП может даже обнаружить, что запуск тестового покрытия в качестве инструмента тестового покрытия также может помочь ему. Если приложение, скомпилированное с тестовым покрытием, выполняется и не дает сбоя, «покрытый код» этого выполнения выполнялся хотя бы один раз и, следовательно, с меньшей вероятностью является источником проблемы. (Никаких гарантий: просто потому, что вы казнили, это не значит, что это правильно). Но намек на то, что проблема в другом месте; это может привести к устранению кода, который не является проблемой.