[antlr-interest] Syntactic anti-predicates
Steve Bennett
stevagewp at gmail.com
Mon Feb 11 05:45:53 PST 2008
On 2/10/08, Gavin Lambert <antlr at mirality.co.nz> wrote:
> Why not just use:
>
> ruleA
> : (X Y Z) => ruleXYZ
> | ruleNotXYZ
> ;
Ok, I've now got a good, non-contrived example to show the problem:
table:
LEFT_BRACE PIPE ws? table_format? NL
table_line*
ws? PIPE RIGHT_BRACE;
table_line:
ws?
(
(PIPE PLUS) => table_caption
| (PIPE HYPHEN) => table_row_separator
| (EXCLAMATION) => table_header_cells
| (PIPE) => table_data_cells
);
----
Here, the problem is that table_line is inside a looping construct.
Each time it loops, there can be whitespace, then a |} (end of table),
or one of the other forms: |-, |+, |text.
By the time the syntactic predicate inside fails the match, it's too
late. I could left factor table_line:
table_line:
(
(ws? PIPE PLUS) => ws? table_caption
| (ws? PIPE HYPHEN) => ws? table_row_separator
| (ws? EXCLAMATION) => ws? table_header_cells
| (ws? PIPE) => ws? table_data_cells
);
But that's inelegant. My ideal solution would have this line:
table_line*
replaced with something like:
(~(ws? PIPE RIGHT_BRACE) => table_line)*
The only way to get around it at the moment that I can see is to
either left factor as above, or use a semantic predicate - which I'm
not really sure how to use with an arbitrary length rule like ws.
Oh, or I can turn the loop inside out:
table:
LEFT_BRACE PIPE ws? table_format? NL
ws?
(table_line ws?)*
PIPE RIGHT_BRACE;
This does actually work. It's slightly disconcerting having the
whitespace grouped with the previous line, but it's less bad than the
other alternatives I think.
Steve
More information about the antlr-interest
mailing list