[antlr-interest] BUG: Constant (literal) token is incorrectly assumed to be present in AST rewrite

Jesse McGrew jmcgrew at gmail.com
Wed Aug 13 18:23:21 PDT 2008


On Wed, Aug 13, 2008 at 6:06 PM, Austin Hastings
<Austin_Hastings at yahoo.com> wrote:
> Howdy,
>
> I have a C-like grammar with this entry:
>
> conditional_expr
>   : logical_or ( '?' expression ':' conditional_expr )?
>      -> ^( '?' logical_or expression? conditional_expr?)
>   ;
>
> I am using antlr v3.1. In this case, the generated code assumes that the
> rewrite-rule's '?' token is the same as the possibly-nonexistent '?' in the
> matching rule, and tries to dereference the "stream" that would contain that
> token, if it were present.
>
> In the case where no conditional expression is present, the rewrite should
> collapse into ^( '?' logical_or )
>
> I suspect that there's a better way to handle this particular rewrite
> scenario. I'd like to hear it.

Well, what I'd do is this:

conditional_expr
  : logical_or
    ( '?' expression ':' conditional_expr
      -> ^('?' logical_or expression conditional_expr)
    )?
  ;

But that's not quite the same - this way, a logical_or with no ternary
operator after it won't be rewritten at all, it'll just stay as
whatever tree was produced by the logical_or. So the question is, are
you really sure you want it to be rewritten as a '?' node, even when
the 'token' operator isn't present in the input?

If so, then try this:

conditional_expr
  : logical_or
    ( '?' expression ':' conditional_expr
      -> ^('?' logical_or expression conditional_expr)
    | /* empty */
      -> ^('?' logical_or)
    )
  ;

This time, Antlr shouldn't be confused by the '?' token in the second
rewrite, since there's no '?' token to the left of the second arrow.

Jesse


More information about the antlr-interest mailing list