Как добавить пользовательское ключевое слово, которое будет обрабатываться как «класс» в формате clang? - PullRequest
2 голосов
/ 30 сентября 2019

Я хотел бы использовать clang-format для форматирования код спецификации (<file>.sc)

Specc имеет несколько предопределенных ключевых слов, которые могут быть отформатированы таким же образомclass отформатирован в C ++:

  • behavior
  • interface

Можно ли это сделать в файле .clang-format?

Входной файл с ключевым словом behavior:

#include <stdio.h>

behavior Main(void)
{
        int main(void)
        {
        printf("Hello World!\n");
        return(0);
        }
};

Вывод clang-format -style=Mozilla hello.sc

#include <stdio.h>

behavior Main(void) { int main(void) { printf("Hello World!\n");
return (0);
}
}
;

Если бы я использовал ключевое слово class вместоbehavior, это вывод, который я получаю:

#include <stdio.h>

class Main(void) {
  int main(void) {
    printf("Hello World!\n");
    return (0);
  }
};

TLDR: я бы хотел, чтобы clang-format обработал ключевое слово behavior из specc , поскольку он обрабатывает ключевое слово class.

Обратите внимание, я просто хочу отформатировать файл. Я не планирую компилировать его с помощью компилятора C / C ++.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Рассматривали ли вы разработку / внесение поддержки SpecC в формат clang в качестве первоклассного языка?

Поскольку это в основном язык C-стиля, я не думаю, что его будет так сложно добавить.

Недавно я начал пытаться добавить поддержку C # (что, я думаю, вероятно, еще хуже) и столкнулся с похожими проблемами в отношении форматирования, когда я хотел, чтобы ключевые слова вели себя по-разному в C # и C ++ (публичный - один из них)

Например, один из механизмов заключается в преобразовании ключевых слов в другие типы ключевых слов (или типы токенов), которые затем можно использовать позже для различного форматирования кода для разных языков.

В этом примереЯ превращаю жетоны «поведения» в мысли, что они «класс»

bool FormatTokenLexer::tryMergeSpeccCBehavior() {
  if (Tokens.size() < 1)
    return false;
  auto &Identifier = *(Tokens.end() - 1);
  if (!Identifier->is(tok::identifier))
    return false;

  if ((Identifier->TokenText == "behavior"))
    Identifier->Tok.setKind(tok::kw_class);
  return true;
}

Хотя я не мог заставить ваш конкретный пример работать с (Main (void)), казалось, сбивает с толку лязг-format

Только с этим изменением (и вызывая его во время Lexing) я смог заставить clang-format думать, что ключевое слово «поведение» было ключевым словом «класс», а не просто возвращаемым типом (который являетсяя думаю, что так оно и есть)

Это означает, что когда он видит поведение, он применяет любое из правил форматирования, которое ищет класс, и этоимеет тенденцию делать больше правильных вещей.

Вам понадобится немного больше сантехники, чтобы учесть некоторые специфические правила SpecC, но это не будет выходить за пределы возможностей.

$ clang-format -style=Mozilla hello.sc
#include <stdio.h>

behavior Main
{
  int main(void)
  {
    printf("Hello World!\n");
    return (0);
  }
};

behavior B(in int p1, out int p2)
{

  int a, b;

  int f(int x) { return (x * x); }

  void main(void)
  {
    a = p1;
    b = f(a);
    p2 = b;
  }
};

У LLVM довольно высокая планка в отношении того, что они впускают, но я думаю, если бы это был стандартный язык, и у него был значительный интерес, и кто-то был готов поддержать его, вы можете, по крайней мере, попросить его рассмотреть его (особенно есликто-то поставил исправления), или вы всегда можете «просто разветвить LLVM» и добавить его.

Просто мысль

0 голосов
/ 30 сентября 2019

Как предложил @Jason в комментарии к моему вопросу, я могу использовать sed для замены ключевых слов. Таким образом, в итоге я обернул следующую команду в сценарий оболочки:

sed "s/behavior/class/g" <file>.sc | clang-format -style=Mozilla | sed "s/class/behavior/g" > <file>.sc
...