[antlr-interest] validating semantic predicates

Harald M. Müller harald_m_mueller at gmx.de
Fri Nov 30 13:08:30 PST 2007


Ok, Mark. You forced me to. Your exception machinery is no good, I say. 
Here is a different way - and I'm sure I'll get beaten for it ... (and maybe
it doesn't work in general - it's tricky; and it worked in my toy example
:-) ).
Don't say I didn't warn you.
;-)

You want to run through a rule if some condition is true; but you want to
ignore all of the rule if the condition is false. To this end, you trick
ANTLR by doing the followng:

a) You define a rule

    ignore : . (DOWN (ignore)* UP)? ;
    
This describes ANY TREE NODE with subtrees or not; and it has no actions
whatsoever in it. It's the most ignorant thing of all.
(DOWN and UP are "reserved tokens" of ANTLR to tell a tree parser that we go
down or up one level in the tree; using them publicly like above is probably
not intended, but it works ...).

b) In your grammar, you either follow the right way (i.e., your semantically
rich rule, rife with actions and activities) when you want to do something;
or you run the ignore rule on the tree you want to ... well ... ignore:

  statement
      : simpleStatement
      | ^('if' x=condition ( { x }? => statement
                           |           ignore
                           )
         )
     ;

Voila - statement is done when condition is true; but not when it's false.
(I extended the language - nested ifs are possibly ... just to check whether
it works in this case. It does.)
   
If you want, I can send you a small working example around this grammar ...

Still, an honest interpreter should, IMVHO pass parameters with
computations' values into the rules and guard each real (side-effect) action
with the result of checking a parameter ...

Regards
Harald M.

P.S. On some level, I wish ANTLR would handle tree grammars are real
two-dimensional grammars - i.e. NOT flatten them into a TreeNodeSTREAM, but
accept that rules decide themselves whether to "go down" or just handle the
rule as a single node. Maybe it might not be that difficult to have another
special symbol like . (e.g. ...) which means "a complete tree" - essentially
the ignore rule above. Then the conditional would become

        ^('if' x=condition ( { x }? => statement
                           |           ...
                           )
         )

Wouldn't that be nice? 

> -----Original Message-----
> From: Mark Volkmann [mailto:r.mark.volkmann at gmail.com] 
> Sent: Friday, November 30, 2007 6:20 PM
> To: Harald Mueller
> Cc: antlr-interest at antlr.org
> Subject: Re: [antlr-interest] validating semantic predicates
> 
> On 11/30/07, Harald Mueller <harald_m_mueller at gmx.de> wrote:
> > Hi -
> >
> > You are already in a tree-parser, aren't you?
> 
> Yes.
> 
> > So some syntax parser has produced your trees (I don't 
> assume you create the trees manually in some other way).
> 
> Right.
> 
> > That syntax parser can then - in its tree-building rules 
> (-> ...) - create trees which actually DO have terminating 
> tokens - there is some documentation on such artificial 
> tokens in the Wiki and also - I think - in the ANTLR book.
> 
> Genius! Thanks!
> 
> I think I'm almost there, but it still stops processing after 
> it completes the catch block.
> 
> Here's the AST I'm processing.
> 
>  (SCRIPT (ADD 10 END) (ADD 20 END) (PRINT END) (SUBTRACT 90 
> END) (IF POSITIVE (PRINT END)) (ADD 10 END) (IF NEGATIVE 
> (PRINT END)) (IF (< 0) (ADD 100 END)) (IF (< 40) (SUBTRACT 10 
> END)) (IF (> 30) (SUBTRACT 20
> END)) (PRINT END))
> 
> Everything works up to the first IF. At that point the value 
> is 10 + 20 - 90 which is -60 so the first if fails since the 
> value isn't positive. Here's the rule with the catch.
> 
> statement
>   : simpleStatement
>   | ^('IF' c=condition { $c.result }? simpleStatement)
>   ;
>   catch[FailedPredicateException fpe] {
>     System.err.println("recoving and continuing");
>     consumeUntil(input, END);
>     input.consume();
>   }
> 
> I get the println output, but the ADD that follows isn't 
> executed. I know because the action for ADD prints out 
> something every time it runs. Any idea what processing stops 
> after the catch executes?
> 
> > Hope this helps ...
> > Regards
> > Harald
> >
> > -------- Original-Nachricht --------
> > > Datum: Fri, 30 Nov 2007 09:37:19 -0600
> > > Von: "Mark Volkmann" <r.mark.volkmann at gmail.com>
> > > An: antlr-interest at antlr.org
> > > Betreff: [antlr-interest] validating semantic predicates
> >
> > > I'm trying to determine how to use validating semantic 
> predicates in 
> > > a rule that has no terminating token. Here's an example of the 
> > > approach I've tried.
> > >
> > > statement
> > >   : simpleStatement
> > >   | ^('if' c=condition { $c.result }? simpleStatement)
> > >   ;
> > >   catch[FailedPredicateException fpe] {
> > >     consumeUntil(input, STMT_TERMINATOR);
> > >     input.consume();
> > >   }
> > >
> > > The problem is that simpleStatements have no terminating 
> token. They 
> > > are a keyword optionally foIlowed by a number. I know whether to 
> > > expect the number based on the keyword. There's no such thing as 
> > > STMT_TERMINATOR in my grammar.
> > >
> > > I think in order to continue parsing when the condition 
> evaluates to 
> > > false, I have to consume all the tokens that make up the 
> > > simpleStatement being skipped. How can I consume those tokens?
> > >
> > > --
> > > R. Mark Volkmann
> > > Object Computing, Inc.
> >
> > --
> > Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
> > Ideal für Modem und ISDN: http://www.gmx.net/de/go/smartsurfer
> >
> 
> 
> --
> R. Mark Volkmann
> Object Computing, Inc.
> 



More information about the antlr-interest mailing list