Убедитесь, что каждый строковый литерал заключен в макрос - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу обернуть каждый строковый литерал в моем проекте макросом.Я хочу убедиться, что каждый строковый литерал в моем проекте обернут макросом, и какой-то внешний инструмент поможет мне определить местоположение строкового литерала, не обернутого макросом.

Есть ли способ, которым яМожно ли использовать плагины Clang, чтобы гарантировать, что каждый строковый литерал обернут внутри макроса?

Случаи, которые я хочу обработать:

  1. #define MY_ASSERT(Y) {if(!(Y)) throw Exception(#Y); }
    

    Знак #Y должен быть предупрежден как развернутыйстроковый литерал.

  2. "a" "b" "c"
    

    Потребуется, чтобы все это было внутри макроса, например:

    MY_STR("a" "b" "c")
    

КакМогу ли я сделать это с помощью плагина Clang, или вообще есть другой способ сделать это?

1 Ответ

0 голосов
/ 27 февраля 2019

Вы можете сделать это с помощью 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) ";

...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...