On Tue, Jan 06, 2009 at 03:22:53PM +0000, Evan Lavelle <[email protected]> 
wrote:
> >I'll probably define myself some C macros so that I can at least
> >write something like
> >    E = E '+' E {pass2only append($1);append($3);append(OP_ADD);}
> >.
> >But it would of course be more nifty if the default behaviour 
> >"execute an action only if the pass is 2" could be placed
> >somewhere central.
> 
> You really want a bison equivalent of flex's YY_USER_ACTION, but I don't 
> think there is one. You could hack the bison output if you're desperate 
> - maybe something in/around YY_REDUCE_PRINT.

Turns out this was actally pretty easy to implement. I absolutely
love that "custom skeleton" feature of bison!

What follows is a short tutorial for setting up "two pass compiling".

Copy the file /usr/share/bison/yacc.c to twopass-yacc.c, and just 
after m4_include(b4_pkgdatadir/[c.m4]), redefine the b4_case macro:

m4_define([b4_case],
[
    case $1:
    if(pass==2) {
$2
    }
    break;
])

Now, in your grammar file, define the "pass" variable and
the following C macros:

int pass;
#define PASS1_CODE_START }} if(pass == 1) {{
#define PASS1_CODE_END }} if(pass == 2) {{
#define PASS12_CODE_START }} {{
#define PASS12_CODE_END }} if(pass == 2) {{

.
Now all actions will only execute if the global "pass" variable
is set to "2".
To define code which only executes in pass 1, do this:

'function' ID '(' PARAMS ')' {
        PASS1_CODE_START;registerfunction($2);PASS1_CODE_END

        // ... pass 2 code ...  
}

(and for code that should execute in both passes, use PASS12
 instead of PASS1)

Make sure to compile your grammar using the new skeleton:
    bison -S twopass-yacc.c grammar.y
.

Cheers,

Matthias




_______________________________________________
[email protected] http://lists.gnu.org/mailman/listinfo/help-bison

Reply via email to