[antlr-interest] Syntactic anti-predicates

Gerald B. Rosenberg gbr at newtechlaw.com
Mon Feb 11 23:20:51 PST 2008


Your source spec is completely ambiguous.  So force the loop termination:

table
   @init{ boolean done = false; } :
      LEFT_BRACE PIPE ws? table_format? NL
           ( ( ws? PIPE RIGHT_BRACE )=> ws? PIPE RIGHT_BRACE { 
done=true; } | { !done }? table_line )+
;

Perhaps the cleaner solution would be to disambiguate the PIPE 
combinations in the lexer:

  table:
      LB_PIPE ws? table_format? NL
      ( ( ~PIPE_RB )=>  table_line )* ws? PIPE_RB
   ;

LB_PIPE: '{|' { intable = true; } ;

PIPE : '|}'      { $type=PIPE_RB;  intable = false; }
          | '|+'     { $type=PIPE_PLUS; }
          | '|-'      { $type=PIPE_HYPH; }
          | '|' TEXT   { if (intable) $type=PIPE_FOO else 
$type=PIPE_BLAH; } // if intable modes are needed
          | '|'
;


At 09:19 PM 2/11/2008, Steve Bennett wrote:
>On 2/12/08, Gerald B. Rosenberg <gbr at newtechlaw.com> wrote:
> >
> >  Won't this do the trick?
> >
> >  table:
> >     LEFT_BRACE PIPE ws? table_format? NL
> >     ( ( ws? PIPE RIGHT_BRACE )=> ws? PIPE RIGHT_BRACE | table_line )+
> >  ;
>
>It's close, but matches too much input on data like:
>
>{|
>|foo
>|}
>|blah
>
>That last row (|blah) should not be matched by the table rule. Sort of
>comes back to the need for the anti-predicate: the only way to
>terminate a loop is for everything in it to fail, and it can be a bit
>awkward arranging for that to take place.
>
>Steve



More information about the antlr-interest mailing list