如何在ANTLR 4中跳过解析规则?

7
在词法分析器中,可以跳过标记,使它们不进入解析器,如下所示:
Whitespace : [ \t\r\n]+ -> skip ;

对于解析器,是否有类似于-> skip的等效选项?也就是说,一旦匹配了解析器规则,是否有办法将其排除在解析树之外?假设可能看起来像这样:

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

(例子摘自The Definitive ANTLR Book,第225页)

1个回答

4
不是跳过,而是可以使用谓词显着地限定规则的匹配方式。
@members {
    boolean once = true;
    public boolean once() {
        if (once) {
            once = false;
            return true;
        }
        return false;
    }
}

考虑仅匹配一次子规则的可能性:

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

只允许匹配子规则一次:

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

仅匹配子规则一次:

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

更新

Antlr3有一个后缀'!'运算符,可以将其元素从树中静默删除。Antlr4没有直接等价物。

惯用的解决方法是在遍历时完全忽略解析树中该元素的存在。访问者不会关心元素是否存在,除非您明确编写代码来处理它。

尽管如此,您可以通过将prolog规则降级为令牌规则,并将匹配的令牌放在隐藏通道上(以防以后需要查看它),来模拟省略运算符。根据prolog规则的复杂性,规则降级并不总是可行的选择。


那是语义谓词的有趣应用,@GRosenberg。谢谢你提供的想法。不幸的是,这并不是我在寻找的。 :-( - james.garriss

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接