我想教flex& bison用于检测纯C中的宏定义。实际上我正在将此函数添加到现有解析器表单here中。解析器本身很好,但它缺乏宏功能。所以我确实成功添加了#include
和pragma
宏检测,但是对于选择宏我有问题,这是解析器中的代码:
macro_selection_variants
: macro_compound_statement
| include_statement
| pragma_statement
| macro_selection_statement
| statement
;
macro_selection_statement
: MACRO_IFDEF IDENTIFIER macro_selection_variants MACRO_ENDIF
| MACRO_IFDEF IDENTIFIER macro_selection_variants MACRO_ELSE macro_selection_variants MACRO_ENDIF
| MACRO_IFNDEF IDENTIFIER macro_selection_variants MACRO_ENDIF
| MACRO_IFNDEF IDENTIFIER macro_selection_variants MACRO_ELSE macro_selection_variants MACRO_ENDIF
;
statement
的声明如下:
statement
: labeled_statement
| compound_statement
| expression_statement
| selection_statement
| iteration_statement
| jump_statement
;
这些宏的词法分析器部分是:
"#ifdef" { count(); return(MACRO_IFDEF); }
"#ifndef" { count(); return(MACRO_IFNDEF); }
"#else" { count(); return(MACRO_ELSE); }
"#endif" { count(); return(MACRO_ENDIF); }
所以问题是我收到2 reduce/reduce
错误,因为我试图在statement
中使用macro_selection_statement
。我需要在宏选择块中使用statement
,因为这些块可以有变量定义,如下所示:
#ifdef USER
#include "user.h"
int some_var;
char some_text[]="hello";
#ifdef ONE
int two=0;
#endif
#endif
这里有什么选择?因为我读到%expect -rr N
对于reduce
警告来说是一件非常糟糕的事情。
答案 0 :(得分:1)
你真的不希望在C语法中实现预处理器(正确)。它需要是一个* pre *处理器;也就是说,它读取程序文本,并将其输出发送到C语法。
(大多数情况下)可以避免执行第二个lex传递,因为(理论上)预处理器可以输出令牌而不是字符流。这可能适用于野牛2.7或更好的“推送解析器”,所以你可能想尝试一下。但传统方法只是一个字符流,可能更容易。
重要的是要记住宏的替换文本以及宏的参数没有语法约束。 (或几乎没有约束。)以下是完全合法的:
#define OPEN {
#define CLOSE }
#define SAY(whatever) puts(#whatever);
#include <stdio.h>
int main(int argc, char** argv) OPEN SAY(===>) return 0; CLOSE
这只是一个开始:)