[antlr-interest] Template for optional element

Mark Volkmann r.mark.volkmann at gmail.com
Wed Jan 30 05:44:16 PST 2008


On Jan 29, 2008 9:57 PM, Oscar Pérez <oscar at perex.org> wrote:
> 2008/1/29, Mark Volkmann <r.mark.volkmann at gmail.com>:
>
> > On Jan 29, 2008 1:57 AM, Oscar Pérez <oscar at perex.org> wrote:
> > > Hi.
> > >
> > > I'm new in ANTLR.
> > >
> > > I want to use a template for a rule like this:
> > >
> > > func: ^( Func ID params* body ) -> func(name={$ID.text},
> > > par={$params.st}, block={$body.st});
> > >
> > > but if there aren't params in source text, then broken!!!
> > >
> > > ¿How can I write a template for optional elements?
> >
> > Does it solve the problem to use something like this in your template?
> >
> > <if(params)><params><endif>

> Is not work!
> I believe that <if(params)>  works only when you do not use the
> "params" param in the template. For example the template:
>
> func(name,body) ::= " <if(!body)> empty <endif> "
>
> you can use the template:
>
> func: ^( Func ID params* body ) -> func(name={$ID.text}) // no "body"
> in template...
>
>
> But my problem is another one:
>
> In the rule 'func' there is an optional element: params* , it can have no.
>
> func: ^(Func ID params* body) -> func(param={$params} )
>
> the error report is:
>
>
> Exception in thread "main" java.lang.NullPointerException
>         at MophouaWalker.method(MophouaWalker.java:1141)
>         at MophouaWalker.classDef(MophouaWalker.java:547)
>         at MophouaWalker.file(MophouaWalker.java:135)
>         at MophouaMain.main(MophouaMain.java:51)
>
> I think so the prvious rule is equvalent to:
>
> func: ^(Func ID body) -> func(param={$params} )
>
> when there are not parameters, then the templete function recive a null Pointer.
>
> the question is:
>
> How it can write template for rules with optional elements?
> I must rewrite the rule?

I'm pretty sure that  <if(params)><params><endif> will output params
only if params is not null and is not a boolean whose value is false.
When params isn't supplied, I think its value to StringTemplate is
null.

I have a case like this in one of my grammars. Here's a rule from my
tree grammar. Note how the "coef" and "exp" parameters are optional in
some alternatives and they are passed to the "term" StringTemplate.

term[String sign]
  : ^(TERM coef=NUMBER)
    {
      Double c = Double.parseDouble($coef.text);
      if ("-".equals(sign)) c = -c;
    }
    -> term(coef={c})
  | ^(TERM coef=NUMBER? var=NAME exp=NUMBER?)
    {
      Double c = Double.parseDouble($coef.text);
      if ("-".equals(sign)) c = -c;
    }
    -> term(coef={c}, var={$var}, exp={$exp})
  ;

Here's the "term" StringTemplate.

term(coef, var, exp) ::= <<
p.addTerm(<coef><if(var)>, "<var>"<endif><if(exp)>, <exp><endif>);
>>

Note how I use "if" to determine what to output.

-- 
R. Mark Volkmann
Object Computing, Inc.


More information about the antlr-interest mailing list