[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Two-pass parser or AST with Bison?
From: |
Matthias Kramm |
Subject: |
Re: Two-pass parser or AST with Bison? |
Date: |
Fri, 30 Jan 2009 16:35:49 +0100 |
User-agent: |
Mutt/1.5.6i |
On Tue, Jan 06, 2009 at 03:22:53PM +0000, Evan Lavelle <address@hidden> 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
Re: Two-pass parser or AST with Bison?, Luca, 2009/01/06