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

Re: SableCC 3-beta.2 Released



On Fri, Sep 05, 2003 at 09:55:22PM -0400, Etienne Gagnon wrote:
> After much work, a new beta release of SableCC 3 is now available for
> download.
> 
> We are pretty excited about a newly implemented feature: automatic
> conflict resolution.  More precisely, SableCC will now resolve some
> LALR(1) conflicts by inlining conflictual productions, while preserving
> the shape of the built AST.  While this feature will not resolve all
> possible LALR(1) conflicts, it can solve many minor conflicts.

This has left me somwhat mystified. I have yet to produce a conflict that
can be resolved by the inlining process. I notice that the doc directory has
a file called "rules-to-follow.txt", but it doesn't help much.

> This version is also meant as a release candidate.  We encourage you to
> test it with your grammars.  Please report back about any bug you find.

It worked just fine with the grammars I have, but since they don't have any
conflicts, that doesn't help dubug the inlining process.

Are there any example grammars with conflicts that can be resolved by the
inlining process? It would especially help if the results of the process is
plain from the output from the --prettyprint option.

> Please note that the generated AST builder has not yet been optimized
> for performance.  So, parsers might be sometimes slower than those
> generated by SableCC2. This issue will be addressed in a post-3.0 release
> (probably 3.1).

I notice that the filter() method has been removed from the generated
parser. I spent a little while with the source putting it back so that it
behaved like the sablecc-3-beta.1 release candidate, which then allowed me
to test the parser generated by the sablecc-3-beta.2 release candidate with
my existing code. This took no account of the inlining process, but it
worked for grammars without any conflicts. The --no-inline option made no
difference for these grammars, for obvious reasons.

I would be disappointed if the parser filter() method disappeared from
version 3 of SableCC, since I have found a few cases that can't be performed
using the automatic CST->AST tranformations. A diff file for my putting it
back are attached, although I might have got it the wrong way round to work
as patch files. Note the boolean "hidden" parameter to the "push()" method
in the parser.txt file, instead of the sablecc-3-beta.1 boolean "filter"
parameter.

I have also found myself making quite a lot of mistakes when writing
CST->AST transformations. Elements inside curly and square brackets are
separated by whitespace, but elements inside round brackets are separated by
commas. I keep using whitespace and comma separation in the wrong places. Is
there any chance of making them all one thing or the other? Consistent comma
separation would probably allow for more growth in the CST->AST syntax than
consistent whitespace separation. The semicolon separator character should
probably be kept aside for side effecting transormations, which would solve
the few cases that the current CST->AST process can't handle.

Thanks for using square brackets for helping to pick out list transormations
more readily. That has prevented an awful lot of mistakes.

-- 
Jon Shapcott <eden@xibalba.demon.co.uk>
"This is the Space Age, and we are Here To Go" - Wlliam S. Burroughs
Binary files ./classes/org/sablecc/sablecc/GenParser.class and /home/eden/sablecc/sablecc-3-beta.2/classes/org/sablecc/sablecc/GenParser.class differ
diff -r ./classes/org/sablecc/sablecc/parser.txt /home/eden/sablecc/sablecc-3-beta.2/classes/org/sablecc/sablecc/parser.txt
42,45d41
<     protected void filter() throws ParserException, LexerException, IOException
<     {
<     }
<
151c147
<     private void push(int numstate, ArrayList listNode, boolean filter) throws ParserException, LexerException, IOException
---
>     private void push(int numstate, ArrayList listNode) throws ParserException, LexerException, IOException
155,159d150
< 	if(filter)
< 	{
< 	    filter();
< 	}
<
192c183
<         push(0, null, false);
---
>         push(0, null);
250c241
<                         push(action[1], list, true);
---
>                         push(action[1], list);
262c253
<                     case $0$: /* $3$ */
---
>                     case $0$:
265c256
< 			push(goTo($1$), list, $2$);
---
> 			push(goTo($1$), list);
365a357
> 
Binary files ./lib/sablecc.jar and /home/eden/sablecc/sablecc-3-beta.2/lib/sablecc.jar differ
diff -r ./src/org/sablecc/sablecc/GenParser.java /home/eden/sablecc/sablecc-3-beta.2/src/org/sablecc/sablecc/GenParser.java
368,372c368,370
< 	macros.apply(file, "ParserReduce", new String[] {
< 	             "" + productions[i].index,
< 		     "" + productions[i].leftside,
< 		     "" + productions[i].isHidden(),
< 		     productions[i].name});
---
>         macros.apply(file, "ParserReduce", new String[] {
>                        "" + productions[i].index,
>                        "" + productions[i].leftside});
380,381c378,379
< 	macros.apply(file, "ParserNewHeader", new String[] {
< 	             "" + productions[i].index, productions[i].name});
---
>         macros.apply(file, "ParserNewHeader",
>                      new String[] {"" + productions[i].index});
diff -r ./src/org/sablecc/sablecc/Production.java /home/eden/sablecc/sablecc-3-beta.2/src/org/sablecc/sablecc/Production.java
62,67d61
<   boolean isHidden()
<   {
<     /* FIXME: Works for EBNF operators '*' and '+', but ignores inlining. */
<     return name.startsWith("ANonTerminal$") || name.startsWith("ATerminal$");
<   }
<
diff -r ./src/org/sablecc/sablecc/parser.txt /home/eden/sablecc/sablecc-3-beta.2/src/org/sablecc/sablecc/parser.txt
42,45d41
<     protected void filter() throws ParserException, LexerException, IOException
<     {
<     }
<
151c147
<     private void push(int numstate, ArrayList listNode, boolean hidden) throws ParserException, LexerException, IOException
---
>     private void push(int numstate, ArrayList listNode) throws ParserException, LexerException, IOException
155,159d150
<         if(!hidden)
<         {
<             filter();
<         }
<
192c183
<         push(0, null, true);
---
>         push(0, null);
250c241
<                         push(action[1], list, false);
---
>                         push(action[1], list);
262c253
<                     case $0$: /* reduce $3$ */
---
>                     case $0$:
265c256
< 			push(goTo($1$), list, $2$);
---
> 			push(goTo($1$), list);
296c287
<     ArrayList new$0$() /* reduce $1$ */
---
>     ArrayList new$0$()