How can I skip a parsing rule using ANTLR 4?
Asked Answered
B

1

7

In the lexer, tokens can be skipped, keeping them out of the parser, like so:

Whitespace : [ \t\r\n]+ -> skip ;

Is there an equivalent to -> skip for the parser? That is, once a parser rule is matched, is there a way to keep it out of the parse tree? Hypothetically, it might look something like this:

document : prolog? -> skip 
           misc* element misc* 
         ;

(Example taken from The Definitive ANTLR Book, p 225.)

Blinkers answered 28/1, 2015 at 18:3 Comment(0)
I
4

Not skip, but you can significantly qualify how a rule is matched using a predicate.

@members {
    boolean once = true;
    public boolean once() {
        if (once) {
            once = false;
            return true;
        }
        return false;
    }
}

Consider the possibility of a subrule match only once:

example1 : { once() }? prolog misc* element misc* 
         | misc* element misc* 
         ;

Allow only a single chance to match a subrule:

example2 : prolog { once() }? misc* element misc* 
         | misc* element misc* 
         ;

Match a subrule only one time:

example3 : prolog misc* element misc* { once() }?
         | misc* element misc* 
         ;

Update

Antlr3 has a postfix '!' operator that silently elides its element from the tree. Antlr4 has no direct equivalent.

The idiomatic workaround is to just totally ignore the existence of the element in the parse tree when walking. The visitor won't care if the element is present or not unless you explicitly write the code to do so.

Nonetheless, you can emulate the elide operator by demoting the prolog rule to a token rule that puts the matched token on the hidden channel (just in case you want to look at it later). Depending on the complexity of the prolog rule, rule demotion won't always be an option.

Imminence answered 29/1, 2015 at 20:30 Comment(1)
That is an interesting use of a semantic predicate, @GRosenberg. Thanks for the idea. Unfortunately, it really isn't what I am looking for. :-(Blinkers

© 2022 - 2024 — McMap. All rights reserved.