如何添加自定义关键字以 clang 格式被视为"class"?



我想用clang-format来格式化specc代码(<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++ 编译器编译它。

您是否考虑过将 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((似乎令人困惑 clang 格式

通过此更改(并在 Lexing 期间调用它(,我能够让 clang 格式认为"行为"关键字是"class"关键字,而不仅仅是返回类型(我认为它是这样认为的(

这意味着当它看到行为时,它将应用任何正在寻找类的格式规则,这将倾向于做更多正确的事情。

你需要更多的管道来允许一些 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"并添加它。

只是一个想法

正如@Jason在对我问题的评论中所建议的那样,我可以使用sed来替换关键字。因此,我最终所做的是将以下命令包装在 shell 脚本中:

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

最新更新