Flex和Bison,检测宏语句(新手)

时间:2014-09-20 22:29:31

标签: c macros bison flex-lexer

我想教flex& bison用于检测纯C中的宏定义。实际上我正在将此函数添加到现有解析器表单here中。解析器本身很好,但它缺乏宏功能。所以我确实成功添加了#includepragma宏检测,但是对于选择宏我有问题,这是解析器中的代码:

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警告来说是一件非常糟糕的事情。

1 个答案:

答案 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

这只是一个开始:)