首页 > 解决方案 > 如何添加自定义关键字以在 clang 格式中被视为“类”?

问题描述

我想用clang-format格式化规范代码<file>.sc

Specc有一些预定义的关键字,可以像class在 C++ 中格式化 a 一样格式化:

我可以在.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++ 编译器编译它。

标签: c++cclang-format

解决方案


您是否考虑过将 SpecC 支持开发/贡献到 clang 格式作为一流的语言?

由于它主要是一种 C 风格的语言,我认为它不会那么难添加。

我最近开始努力添加 C# 支持(我猜这可能更糟),并且在格式方面遇到了类似的问题,我希望关键字在 C# 和 C++ 中的行为不同(公共是其中之一)

例如,一种机制是将关键字转换为其他关键字类型(或 Token 类型),然后可以在以后用于为不同的语言设置不同的代码格式。

在此示例中,我将“行为”标记转换为认为它们是“类”

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;
}

虽然我无法让您的确切示例起作用,但 (the Main(void)) 似乎令人困惑的 clang-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”并添加它。

只是一个想法


推荐阅读