[antlr-interest] The right way to invoke templates with null arguments?

Tim Clark timgclark at gmail.com
Thu Jun 21 03:57:48 PDT 2007


Hi

My application is outputting 'assembler code' for a stack machine.
Corresponding to this tree parser rule:

-------------A------------------
ifStatement
    :
    ^(IF_STAT e=expr s1=statement s2=statement?)
     -> ifStat(
             expr={$e.st},
             stat1={$s1.st},
             stat2={$s2.st},
             L1={myHelper.nextLabel()},
             L2={myHelper.nextLabel()}
         )
-------------------------------

I have this template:

-------------------------------
ifStat(expr,stat1,stat2,L1,L2) ::= <<
    <expr>
<if(stat2)>
    ifFalse <L1>
    <stat1>
    goto <L2>
    <L1>:
    <stat2>
    <L2>:
<else>
    ifFalse <L1>
    <stat1>
    <L1>:
<endif>

>>
-------------------------------

so that the code generated for

if(expr) stat

should be something like this:
-------------------------------
<expr>        // leaves result on stack
ifFalse L_1  // consumes top of stack
<stat1>
L_1:
-------------------------------

and the code generated for

if(expr) stat1 else stat2

should be something like this:
-------------------------------
<expr>
ifFalse L_1
<stat1>
goto L_2
L_1:
<stat2>
L_2:
-------------------------------

However, in the first case (no else clause) the template rewrite part of the
code generated for the rule throws a NullPointerException, because $s2 is
null.


If I change the rule to:

--------------B-----------------
ifStat
    :
    ^(IF_STAT e=expr s1=statement s2=statement?)
     -> {$e2 != null}?
         ifStat(
             expr={$e.st},
             stat1={$s1.st},
             stat2={$s2.st},
             L1={myHelper.nextLabel()},
             L2={myHelper.nextLabel()}
         )
    -> ifStat(
            expr={$e.st},
            stat1={$s1.st},
            L1={myHelper.nextLabel()}
        )
    ;
-------------------------------

then Antlr complains with this message: "missing attribute access on rule
scope: s2". This is unfortunate, because it seems to me that this is the
right way to express this. [Manually changing the parser code generated for
form (A) to test $s2 for nullness does actually makes it work.]

It doesn't help to change the semantic predicate to {$s2.st}?  (which
persuades Anlr to accept it), because it's $s2 that is null, not $s2.st, so
the exception still happens.

It would seem that the only solution is to change the rule to this:

----------------C---------------
ifStat
options{ backtrack=true;}
    :
    ^(IF_STAT e=expr s1=statement s2=statement)
     -> ifStat(
             expr={$e.st},
             stat1={$s1.st},
             stat2={$s2.st},
             L1={myHelper.nextLabel()},
             L2={myHelper.nextLabel()}
         )
    |
    ^(IF_STAT e=expr s1=statement)
    -> ifStat(
            expr={$e.st},
            stat1={$s1.st},
            L1={myHelper.nextLabel()}
        )
    ;
-------------------------------

The backtracking option is necessary, otherwise Anlr sees it as ambiguous.
This version does work. I don't think it's the right way, and for more
complicated constructions like for statements, or case statements, there are
many more possible alternatives to cover.

My question is this: is this how it's intended to be, or is there a bug,
preventing what I think is the right way from working?


The obvious solution that springs to mind, to change STAttrMap (in the Antlr
code generator) like this:

    public static class STAttrMap extends HashMap {
      public STAttrMap put(String attrName, Object value) {
        if(value != null) super.put(attrName, value);
        return this;
      }
      public STAttrMap put(String attrName, int value) {
        super.put(attrName, new Integer(value));
        return this;
      }
    }

unfortunately does not work, because one is invoking templates with things
like $e.st, where it's $e that may be null, not $e.st.

Regards
Tim
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.antlr.org/pipermail/antlr-interest/attachments/20070621/535fc439/attachment.html 


More information about the antlr-interest mailing list