Re: implementing #include etc without pre-preprocessing

ftit07bv85@pop.anti.wanadoo.spam.fr (C. Pernod)
21 Mar 1997 10:22:05 -0500

          From comp.compilers

Related articles
implementing #include etc without pre-preprocessing sfrederi@asc.corp.mot.com (Sudhakar Frederick) (1997-03-16)
Re: implementing #include etc without pre-preprocessing thetick@scruz.net (Scott Stanchfield) (1997-03-18)
Re: implementing #include etc without pre-preprocessing bothner@cygnus.com (1997-03-21)
Re: implementing #include etc without pre-preprocessing ftit07bv85@pop.anti.wanadoo.spam.fr (1997-03-21)
Re: implementing #include etc without pre-preprocessing ok@cs.rmit.edu.au (1997-03-21)
Re: implementing #include etc without pre-preprocessing sethml@ugcs.caltech.edu (1997-03-22)
| List of all articles for this month |
From: ftit07bv85@pop.anti.wanadoo.spam.fr (C. Pernod)
Newsgroups: comp.compilers
Date: 21 Mar 1997 10:22:05 -0500
Organization: Compilers Central
References: 97-03-090
Keywords: C, parse

On 16 Mar 1997 23:38:48 -0500, in comp.compilers you wrote:


>Is it practical to implement "conditional compilation" C-style
>constructs similar to #include, #define #ifdef etc. as part of the
>parsing rather than through a pre-processor. I'm using Bison and Flex.


Yes, this can be done easily with bison : just add the directive :


%pure_parser


somewhere in the 1st section (before the '%%')
It will make a reentrant parser what can be called from lex as:


/* ... */
my_token_xx { return MY_TOKEN_XX; }
include { return MY_TOKEN_INCLUDE; }
ifdef { return MY_TOKEN_IFDEF; }


^[ \t]*"#"[ \t* { handle_cpp_dir(); }
/* ... */
%%


/*
  * Handle preprocessor directives ::
  *
  */
void handle_cpp_dir()
{
int cur_line = yylineno;


push_token( CPP_MARK_TOKEN ); /* See (1) */
if( yyparse() )
fprintf( stderr, "preprocessor error, line %d\n", cur_line );
}




In yacc, write:


%token ... CPP_MARK_TOKEN ....
%pure_parser
%%
start: my_language_rules
              | CPP_MARK_TOKEN cpp_dir '\n'
              ;


cpp_dir: MY_TOKEN_INCLUDE STRING { do_include( $2 ); return 0;}
| MY_TOKEN_IF expr { push_if( $2);return 0;}
| MY_TOKEN_IFDEF IDENTIFIER { push_if(
srch_id( $2 ) != NULL
); return 0; }
| error { return -1; }




[...]
>[Look at the flex manpage, wherein is found great wisdom on creating,
>deleting, and switching among input buffers. Yes, you can do this although
>the expressions in #if require a complete expression parser. -John]


... that can be done in the same grammar, with the above tip.
(1) While in buffer switching,make room for a fake token I called
CPP_MARK_TOKEN, which will force the parser to track preprocessor
directives. I noted this as push_token().
This may not be mandatory, depending on your language, but in C
for instance there would be unresovable conflicts (on IF, ...)


I hope sample code is clear enough -- ask for more if not !...
--
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.