我需要构建一个自动化系统来解析C++ .h文件,其中包含大量的#define
语句,并使用每个#define
可用的值进行操作。除了#define
声明之外,.h文件还有很多其他垃圾。评估C++头文件中的所有宏
目标是创建一个键值列表,其中键是所有由#define
语句定义的关键字,值是对应于这些定义的宏的评估。 #defines
使用一系列嵌套宏定义关键字,这些宏最终解析为编译时的整型常量。有一些不能解决编译时整数常量,并且这些必须被跳过。
.h文件将随着时间的推移发展,所以该工具不能是一个长的硬编码程序,它实例化一个变量以等于每个关键字。我无法控制.h文件的内容。唯一的保证是它可以用一个标准的C++编译器构建,并且更多的#defines
将被添加,但从不删除。宏公式可能随时改变。
我看到这种情况的选项是:
- 实现的局部(或钩到现有的)C++编译器和在预处理步骤截取的宏的值。
- 使用regexes动态构建一个源文件,该文件将消耗当前定义的所有宏,然后编译并执行源文件以获取所有宏的评估形式。以某种方式(?)跳过不计算为编译时整数常量的宏。 (另外,不知道正则表达式是足够的表现力捕捉到所有可能的多行宏定义)
这两种方法都将增加相当大的复杂性和脆弱性的生成过程为这个项目,我想避免的。有没有更好的方法来评估C++ .h文件中的所有#define
宏?
下面是我所期待解析一个例子:
#ifndef Constants_h
#define Constants_h
namespace Foo
{
#define MAKE_CONSTANT(A, B) (A | (B << 4))
#define MAGIC_NUMBER_BASE 40
#define MAGIC_NUMBER MAGIC_NUMBER_BASE + 0x2
#define MORE_MAGIC_1 345
#define MORE_MAGIC_2 65
// Other stuff...
#define CONSTANT_1 MAKE_CONSTANT (MAGIC_NUMBER + 564, MORE_MAGIC_1 | MORE_MAGIC_2)
#define CONSTANT_2 MAKE_CONSTANT (MAGIC_NUMBER - 84, MORE_MAGIC_1 & MORE_MAGIC_2^0xA)
// etc...
#define SKIP_CONSTANT "What?"
// More CONSTANT_N mixed with more other stuff and constants which do
// not resolve to compile-time integers and must be skipped
}
#endif Constants_h
我需要摆脱的,这是所有编译时其决心的定义整型常量的名字和评估。在这种情况下,显示的定义它是
MAGIC_NUMBER_BASE 40
MAGIC_NUMBER 42
MORE_MAGIC_1 345
MORE_MAGIC_2 65
CONSTANT_1 1887
CONSTANT_2 -42
这其实并不重要,这个输出是什么格式,只要我可以用它作为键值对的列表,进一步扎实工作,管道。
只需使用现有的C预处理程序来帮助你。带'-dU'选项的常规GNU'cpp'应该会让你非常接近你之后的结果。 –
为什么输出中的“CONSTANT_1”和“CONSTANT_2”,但是“MAGIC_NUMBER_BASE”,“MAGIC_NUMBER”,“MORE_MAGIC_1”,“MORE_MAGIC_2”不是?它看起来符合你的标准(定义了编译时整数常量的解决方案),至少和其他两个一样。 –
@BenVoigt他们应该在输出中,我现在要修复它。 – Techrocket9