[antlr-interest] tricky (to this newby) translation problem

Kenny Tilton ktilton at nyc.rr.com
Fri Dec 30 13:05:49 PST 2005


Bryan Ewbank wrote:

>On 12/30/05, Kenny Tilton <ktilton at nyc.rr.com> wrote:
>  
>
>>   enumerator
>>        :       i:ID            { print( i ); }
>>                ( b:ASSIGN      { print( b ); }
>>                  expr
>>                )?
>>        ;
>>
>>But my problem is that, if the match with an ASSIGN happens, I need to
>>get a left-parens /in front/ of the emitted ID. Otherwise I have to
>>always wrap enumerators in parens:
>>    
>>
>
>There's two ways you can do this; one is to use an intermediate form - a tree
>parser - so that you move the ASSIGN above the id and the expr.  This is,
>argueably, the ANTLR way.  There's a section on tree parsers in the
>PDF manual that should help...
>
>    // parser
>    enumerator:
>        : ID ( ASSIGN^ expr )?
>        ;
>
>    // tree parser - next pass
>    enumerator:
>        : i:ID { print i ; }
>        | #( ASSIGN j:ID e:expr ) { print "(", j, e, ")"; }
>        ;
>
>  
>
Yes, that really tackles the problem head on. Nice.

>The other way is very much like what you tried, but with a twist to
>avoid the ambiguity:
>
>    enumerator
>        :   i:ID
>            (
>                ASSIGN      { print("("); print( i ); print(" "); }
>                expr        {print(")");}
>            |
>                // no "= expr" - just need the name
>                { print( i ); }
>            )
>        ;
>  
>
Also good. And now I do not have to learn where to put the tree parser. 
:) But something tells me that before long I will have to break down and 
learn more about parsing. That's OK, it seems like fun and the on-line 
doc and support here is great.

>On reflection, there's a third way that might be better only because
>it normalizes the output lisp, and that is to always produce the
>parens and the assigned value.  This helps to reduce the ambiguity and
>variation in the lisp output...
>
>    enumerators
>    { int c = 0; }
>    : ( c=enumerator[c] { c = c+1; } )+
>    ;
>
>    enumerator
>    [int cur]
>    returns [int nxt=cur+1]
>        :   i:ID
>            (
>                ASSIGN      { print ( "(", i, " " ); }
>                cur=expr    { nxt = nxt+1; }
>            |
>                // no "= expr" - assign the defined value
>                { print ( "(", i, " ", cur, ")" ); }
>            )
>            ;
>
>This will result in always having the equivalent number in the list. 
>  
>
Cool. But I have done Lisp "enum" macros in the past and always go with 
the approach in which one has an option to vary the syntax:

   (defenum zero one (five 5) six (seven))

That makes the resulting code as maintainable as a C enum just by 
inserting or removing items with default enumeration, and Lisp macros 
often give the programmer a little flexibility like this to minimize 
visual clutter.

Thx for the great suggestions to work from.

kenny



More information about the antlr-interest mailing list