在Perl中解析多嵌套条件C预处理器语句

时间:2014-09-08 23:09:08

标签: c perl parsing conditional c-preprocessor

我正试图想出一种方法来轻松解析一些C头文件。我有三个头文件,File_A1,File_A2和File_B。 File_A *仅包含#defines#defines本身可以映射到布尔值,数值数据或类似(E && F)的条件语句,其中EF在文件的前面定义。例如:

FILE_A1

#define TRUE 1
#define FALSE 0
#define USERWARE                                TRUE
#define SECTION_SIZE                            2
#define ENGR2_LOAD_ADDRESS                      0x6FF020
#define INTEGER_ONLY_SUPPORT                    FALSE
#define PRESSURE_SENSOR_MIN_KPA_DELTA           -50
#define DUMMY_ENGR2_LOAD_ADDRESS                0x92059020
#define FAST_FLUSH_SUPPORT                      USERWARE

FILE_A2非常相似。

File_B在定义方面有点复杂。它包含嵌套的#define语句,其中许多语句被#if...#elif...#endif包围,所以类似于:

FILE_B

#include "File_A1.h"
#include "File_A2.h"

#if (FAST_FLUSH_SUPPORT )
#define MEMORY_BUDGET_FLASH_DIR                   (12 * 256)
#define MEMORY_BUDGET_FLASH_CFG                   (15 * 256)
#else //(FAST_FLUSH_SUPPORT )
#define MEMORY_BUDGET_FLASH_DIR                   (0)
#define MEMORY_BUDGET_FLASH_CFG                   (0)
#endif //(FAST_FLUSH_SUPPORT )

#define DRAM_OFFSET_FLASH_DIR                   (DUMMY_ENGR2_LOAD_ADDRESS)
#define DRAM_OFFSET_FLASH_CFG                    (DRAM_OFFSET_FLASH_DIR            + MEMORY_BUDGET_FLASH_DIR)
#define DRAM_OFFSET_FLASH_LOG                   (DRAM_OFFSET_FLASH_CFG             + MEMORY_BUDGET_FLASH_CFG)

#define DRAM_FLASH_CFG_BASE              (DRAM_OFFSET_FLASH_CFG + ENGR2_LOAD_ADDRESS)
#define DRAM_FLASH_CFG_SIZE              (MEMORY_BUDGET_FLASH_CFG)

正如你所看到的,它可能会变得有点毛茸茸。我想要做的是将所有FILE_B的#defines解析为一个评估级别。此外,所有条件都将被处理和删除。 (假设用户软件为TRUE),

#define MEMORY_BUDGET_FLASH_DIR                   (12 * 256)
#define MEMORY_BUDGET_FLASH_CFG                   (15 * 256)

#define DRAM_OFFSET_FLASH_DIR                   (0x92059020)
#define DRAM_OFFSET_FLASH_CFG                   (0x92059020            + (12 * 256))
#define DRAM_OFFSET_FLASH_LOG                   ((0x92059020            + (12 * 256))             + (15 * 256))

#define DRAM_FLASH_CFG_BASE              ((0x92059020            + (12 * 256)) + 0x6FF020)
#define DRAM_FLASH_CFG_SIZE              ((15 * 256))

如果我能达到这样的目的,那么我可以研究下一步,即评估宏的所有右侧。例如,MEMORY_BUDGET_FLASH_DIR将评估为3,072。

这些构建过程漫长而繁琐且涉及数千个文件,因此使用-E运行gcc并不是最佳解决方案。事实上,它可能是更糟糕的解决方案之一,因为我认为'-E'解决了所有宏声明,因此我失去了初始定义。此外,我实际需要的唯一文件是File_A1,File_A2和File_B,这意味着其他数千个文件在此范围内毫无意义。

我希望找到一种解析这些语句的简单方法。 我不太清楚如何评估扩展的表达式,也不知道用什么样的结构存储所有这些信息。我希望用Perl编写这个,因为我对它有一些小的经验,比Python更多。

任何帮助将不胜感激。

编辑:更新了问题描述以反映实际值。澄清了一点。

1 个答案:

答案 0 :(得分:1)

在Perl中,您可以使用Marpa::R2 - 一般的BNF解析器。

This gist从您的qiestion解析FILE_B的开头到树(请参阅注释中的输出)。

希望这有帮助。