[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