Вы можете сделать это с помощью DMS Software Reengineering Toolkit и его внешнего интерфейса C ++.
DMS может читать исходный код в соответствии с явным определением грамматики C ++ (обрабатывает C ++ 17 в диалектах GCC и MS), создает AST, применяет правила перезаписи, предоставленные для изменения дерева, а затем распечатывает AST обратно к исходному тексту, сохраняя комментарии, выравнивания текста, радикальные числа и т. д.
Для этого вам понадобится всего одна DMSправило (см. Правила перезаписи DMS для получения подробной информации):
rule wrap_string_in_macro(s:string_literal):primary_expression->primary_expression
= "\s" -> " my_macro_name(\s) ";
Нетерминал string_literal охватывает широкий спектр строк C ++ (8 бит, ISO, широкий, необработанный,последовательность строк, ...) так что вам не нужно беспокоиться о них, это правило подберет их.Но ваш макрос может беспокоиться о них.Таким образом, вы могли бы написать более широкий набор правил, чтобы вы могли специализировать вызов макроса:
rule wrap_ISO_string_in_macro(s:ISO_STRING_LITERAL):primary_expression->primary_expression
= "\s" -> " my_macro_name_for_ISO_string(\s) ";
rule wrap_ISO_string_in_macro(s:WIDE_STRING_LITERAL):primary_expression->primary_expression
= "\s" -> " my_macro_name_for_wide_string(\s) ";
...
Эти правила будут подбирать отдельные строки, но это оставляет проблему обработки последовательностей строк:
rule wrap_ISO_string_list_in_macro(seq: string_literal_list,s:ISO_STRING_LITERAL):primary_expression->primary_expression
= " \string_literal_list \s" -> " my_macro_name_for_ISO_string_list(\s) ";
...