Vanya
Vanya

Reputation: 439

Flex And Bison, detecting macro statements (newbie)

I want to teach flex & bison to detect the macro definitions in pure C. Actually i'am adding this function to the existing parser form here. The parser itself is good, but it lacks macro functionality. So i did add successfully the #include and pragma macros detection, but with the selection macroses i have the problems, this is the code in the parser:

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 is declared like so:

 statement
    : labeled_statement     
    | compound_statement
    | expression_statement
    | selection_statement
    | iteration_statement
    | jump_statement    
    ;

And the lexer part for those macroses is:

"#ifdef"        { count(); return(MACRO_IFDEF); }
"#ifndef"       { count(); return(MACRO_IFNDEF); }
"#else"         { count(); return(MACRO_ELSE); }
"#endif"        { count(); return(MACRO_ENDIF); }

So the problem is i get the 2 reduce/reduce errors because i'm trying to use statement in my macro_selection_statement. I need to use statement in the macro selection block, because those blocks can have variables definitions likes so:

#ifdef USER
#include "user.h"
 int some_var;
 char some_text[]="hello";
    #ifdef ONE
        int two=0;
    #endif
#endif

What would be the right move here? because i read that %expect -rr N is a really bad thing to do with the reduce warnings.

Upvotes: 0

Views: 1300

Answers (1)

rici
rici

Reputation: 241731

You cannot really expect to implement a preprocessor (properly) inside of a C grammar. It needs to be a *pre*processor; that is, it reads the program text, and its output is sent to the C grammar.

It is possible to (mostly) avoid doing a second lex pass, since (in theory) the preprocessor can output tokens rather than a stream of characters. That would probably work well with a bison 2.7-or-better "push parser", so you might want to give it a try. But the traditional approach is just a stream of characters, which may well be easier.

It's important to remember that the replacement text of a macro, as well as the arguments to the macro, have no syntactic constraints. (Or almost no constraints.) The following is entirely legal:

#define OPEN {
#define CLOSE }
#define SAY(whatever) puts(#whatever);

#include <stdio.h>

int main(int argc, char** argv) OPEN SAY(===>) return 0; CLOSE

And that's just a start :)

Upvotes: 1

Related Questions