访问C ++源文件的标记化 我建议改写自己的GCC plugin以上规范不明确

问题描述

我的理解是,程序编译的一个步骤(与语言无关,我想)是将源文件解析为某种由空格分隔的标记(此标记化将通过称为的方式进行) this answer中的扫描器。例如,我了解到在编译过程中的某个时刻,包含x += fun(nullptr);的行被分隔为类似

  • x
  • +=
  • fun
  • (
  • nullptr
  • )
  • ;

这是真的吗?如果是这样,是否有办法访问这种C ++源代码标记化?

我问这个问题主要是出于好奇,我打算自己写词法分析器

我想知道是否可以利用编译器的原因是,举个例子,在遇到[[noreturn]] & Co.之前,我从未考虑过[[是有效的令牌,如果我要自己写词法分析器。

我们是否一定需要一个真实的实际用例?如果我对是否存在现有工具感到好奇,我认为我们不会。

但是,如果我们真的需要用例,

假设我的目标是编写一个C ++函数,该函数读取C ++源文件并返回由其组成的词素的std::vector。显然,要求连接输出的要素应该再次构成整个文本,包括换行符和其中的每个其他字节。

解决方法

有了注释中提到的限制(令牌化保持__DATE__),这似乎很容易管理。您需要预处理令牌。 Boost :: Wave预处理器必须创建一个令牌列表,因为它必须处理这些令牌。

Basile正确地指出,很难为这些标记分配含义。

,

C ++是一种非常复杂的编程语言。

在尝试解析C ++代码之前,请务必先阅读C ++ 11草案标准n3337

查看现有开放源C ++编译器的源代码,例如GCC(2020年10月至少为GCC 10Clang(至少Clang 10在2020年10月)

如果您必须从头开始编写C ++解析器,请确保至少有一个完整的工作年预算。

还查看现有的 C ++静态源代码分析器,例如Frama-C++Clang static analyzer。考虑考虑使其中一种适应您的需求,但是在开始编码之前,请先编写需求书面文档。请注意Rice's theorem

我建议改写自己的GCC plugin

实际上,它将与某些主要版本的GCC绑定在一起,但您将赢得数月的工作。

这是真的吗?如果是这样,是否有办法访问这种C ++源代码的标记化?

是的,通过修补现有的一些 开源C ++编译器,或使用您的插件对其进行扩展(两种方法都有许可条件)。

假设我的目标是编写一个C ++函数,该函数读取C ++源文件并返回其组成的词素的std :: vector。

以上规范不明确。

您要在C ++预处理阶段之前还是之后使用词素吗?换句话说,例如__DATE____TIME__?阅读例如GNU cpp的文档...如果您碰巧在Linux上使用GCC(请参阅gcc(1))并拥有一些C ++ translation unit foo.cc,请尝试运行{{ 1}},然后(使用less(1) ...)查看生成的预处理形式g++ -C -E -Wall foo.cc > foo.ii?那么模板扩展,或者preprocessor conditionalspreprocessor stringizing呢?

我建议您编写适用于GENERIC表示形式的GCC插件。您还可以开始与您的目标相关的博士学位研究。

请注意,生成 C ++代码比解析它容易得多。

Qt中查找生成C ++代码的软件示例。您可以考虑使用GNU m4GNU gawkGNU autoconfGPP或您自己的C ++源生成器(也许借助GNU bisonANTLR)来生成您的某些C ++代码。

PS。在我的主页上,您会找到指向与您的问题相关的报告草稿的超链接,以及指向生成C ++代码的开源程序的另一个超链接。可悲的是,似乎我禁止在这里提供这些超链接,但是您可以通过单击两次鼠标来找到它们。您可能还会研究为该报告草案提供资金的两个欧洲H2020项目:CHARIOTDECODER