[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Multi-file Compilation



Hi,

I need to compile multiple files simultaneously and build a single AST
representing the complete program spanning multiple source files.
The program is represented by a set of classes, each source file containing
one or more classes.
The solution I am thinking about is to have a production "program" that
serves no purpose at parse time, with a hidden alternative (classfile+), and
then perform a post-parse transformation, using that alternative to collect
all the tree roots into a list of 'classfile' nodes, with the "program"
production being the new AST root.
I have doubts however that this is really a good solution. Has anybody had
to do this before in SableCC, or does anybody see a better solution? Are
there any issues I should be aware of (e.g. EOF?) ?

P.S.: I have seen mentioned writing your own PushBackReader as a solution
for #includes. It didn't seem really relevant to my situation... or is it?

Thanks.
Othman

----- Original Message -----
From: "Etienne M. Gagnon" <egagnon@j-meg.com>
To: "sablecc-list" <sablecc-list@sable.mcgill.ca>
Sent: Saturday, March 04, 2000 10:11 PM
Subject: NEWS: Much improved conflict messages in SableCC 2.13


> Hi everyone.
>
> Another release.  It was quick, but it is, I think, an interesting
release.
>
> I received a patch from Ben Menking <bmenking@bigfoot.com>.  This patch
> contained some code to:
> - Indicate the current position in a production using a * symbol instead
of
> using a position number
> - Filtering out the state's irrelevant productions and displaying only
those
> that are directly involved in the conflict.
>
> This code needed improvement (see the ChangeLog).  [I know, I'm picky].
> Anyway, while improving this code, I said to myself, why not also
implement a
> related feature that was initially meant for SableCC 3.0.
>
> The result is that, now SableCC 2.13 reports conflict in a much clearer
way.
> (1) It gets rid of irrelevant state items.
> (2) It clearly indicates the action beside each item (reduce/shift)
> (3) It indicates the parsing position using a "*" instead of an integer
>
> Finally, and not least:
>
> (4) It prints the shortest stack configuration that would expose the
conflict!
>
> The addition of (4) helps figuring out what is normally pretty difficult
to
> see:  The question we normally ask, when SableCC reports a conflict, is
"what
> kind of program would cause this conflict"?  (4) answers this question.
Thus,
> it gives us an intuitive context to see the conflict. :-)
>
> Here is a small example of ambiguous grammar, and the SableCC output (old
and
> new):
> ====================================
> // an obviously ambiguous grammar
> Tokens
>   plus = '+';
>   minus = '-';
>   num = ['0'..'9']+;
>
> Productions
>   exp = {plus}  [lexp]:exp plus  [rexp]:exp |
>         {minus} [lexp]:exp minus [rexp]:exp |
>         {num}   num;
> ====================================
> ---OLD STYLE---
> $ java SableCC ambiguous.sablecc
> SableCC version 2.12
> [...]
> shift/reduce conflict on TPlus in {
>         [PExp = PExp TPlus PExp]:1:TPlus,
>         [PExp = PExp TPlus PExp]:1:TMinus,
>         [PExp = PExp TPlus PExp]:1:EOF,
>         [PExp = PExp TPlus PExp]:3:TPlus,
>         [PExp = PExp TPlus PExp]:3:TMinus,
>         [PExp = PExp TPlus PExp]:3:EOF,
>         [PExp = PExp TMinus PExp]:1:TPlus,
>         [PExp = PExp TMinus PExp]:1:TMinus,
>         [PExp = PExp TMinus PExp]:1:EOF
> }
> ====================================
> ---NEW STYLE---
> $ java SableCC ambiguous.sablecc
> SableCC version 2.13
> [...]
> shift/reduce conflict in state [stack: PExp TPlus PExp *] on TPlus in {
>         [ PExp = PExp * TPlus PExp ] (shift),
>         [ PExp = PExp TPlus PExp * ] followed by TPlus (reduce)
> }
>
> NOTE:
> - NEW: the stack state is "in state [...]"
> - The lookahead is "on ..."
> - NEW: The parsing position is indicated by "*"
> - NEW: The action is shown (reduce/shift)
> - NEW: There are no spurious items
> ====================================
> EXPLANATION
>
> What the error message means is that if we have a program that starts with
the
> following:
>
>   stack: PExp-1 TPlus PExp-2
>   lookahead: TPlus
>
> e.g.: (pick here anything that looks like "PExp TPlus PExp")
>
>   3+4 (and an upcoming "+")
>
> then there is a shift/reduce conflict as you could have:
>
> [parentheses indicate a PExp]
>   3+(4+...)...
> i.e.: shift the "+" in [ PExp = PExp-2 * TPlus  PExp-3 ]
>                                  \4/      \+/   \.../
> In other words [PExp-2 TPlus PExp-3] will eventually be reduced to a PExp
(let
> say PExp-4), then the stack will look like
>   [ PExp-1 TPlus PExp-4 ]
>
> or you could have
>   (3+4)+...
> i.e.: reduce [ PExp = PExp-1 TPlus PExp-2 * ]
>                        \3/    \+/   \4/
>
> Neat, isn't it?
>
> Have fun resolving conflicts!  (I'll use this version to resolve
Scriptonite
> conflicts http://scriptonite.sourceforge.net/).
>
> Etienne
> --
> ----------------------------------------------------------------------
> Etienne M. Gagnon, M.Sc.                     e-mail: egagnon@j-meg.com
> Author of SableCC:                 http://www.sable.mcgill.ca/sablecc/
> ----------------------------------------------------------------------
>