[antlr-interest] validating semantic predicates

Mark Volkmann r.mark.volkmann at gmail.com
Fri Nov 30 13:57:09 PST 2007


On 11/30/07, Harald M.  Müller <harald_m_mueller at gmx.de> wrote:
> Ok, Mark. You forced me to.

Thanks for all the time you've spent trying to help me! I have more
replies below.

> 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 ...

Hmm ... that's a little scary looking. Go ahead and send me your
working example though. Thanks!

> 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 ...

Do you mean like the following? I had this working, but I didn't
particularly like having to check the condition result inside the rule
for simpleStatement with "if ($b)". Do you think this is the best
approach? It's certainly pretty simple.

statement
  : simpleStatement[true]
  | ^('IF' b=condition simpleStatement[$b.result])
  ;

simpleStatement[boolean b]
	: ^('ADD' n=NUMBER) { if ($b) value += toInt(n); }
	| ^('SUBTRACT' n=NUMBER) { if ($b) value -= toInt(n); }
	| 'PRINT' { if ($b) System.out.println(value); }
	;

condition returns [boolean result]
  :	'POSITIVE' { $result = value > 0; }
  | 'NEGATIVE' { $result = value < 0; }
  | ^('<' n=NUMBER) { $result = value < toInt(n); }
  | ^('>' n=NUMBER) { $result = value > toInt(n); }
  | ^('=' n=NUMBER) { $result = value == toInt(n); }
  ;

> 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?

Yes, it would!

> > -----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.
> >
>
>


-- 
R. Mark Volkmann
Object Computing, Inc.


More information about the antlr-interest mailing list