如何使用ANTLR 4跳过解析规则?

jam*_*iss 7 parsing parser-generator antlr4

在词法分析器中,可以跳过令牌,使它们脱离解析器,如下所示:

Whitespace : [ \t\r\n]+ -> skip ;
Run Code Online (Sandbox Code Playgroud)

-> skip解析器是否有相同的功能?也就是说,一旦匹配解析器规则,是否有办法将其保留在解析树之外?假设,它可能看起来像这样:

document : prolog? -> skip 
           misc* element misc* 
         ;
Run Code Online (Sandbox Code Playgroud)

(例子取自最终的ANTLR书,第225页.)

GRo*_*erg 4

不是跳过,但您可以使用谓词显着限定规则的匹配方式。

@members {
    boolean once = true;
    public boolean once() {
        if (once) {
            once = false;
            return true;
        }
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

example1 : { once() }? prolog misc* element misc* 
         | misc* element misc* 
         ;
Run Code Online (Sandbox Code Playgroud)

只允许一次匹配子规则的机会:

example2 : prolog { once() }? misc* element misc* 
         | misc* element misc* 
         ;
Run Code Online (Sandbox Code Playgroud)

仅匹配子规则一次:

example3 : prolog misc* element misc* { once() }?
         | misc* element misc* 
         ;
Run Code Online (Sandbox Code Playgroud)

更新

Antlr3 有一个后缀“!” 默默地从树中删除其元素的运算符。Antlr4 没有直接等效项。

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

尽管如此,您可以通过将序言规则降级为令牌规则来模拟 elide 运算符,该规则将匹配的令牌放在隐藏通道上(以防万一您想稍后查看它)。根据序言规则的复杂性,规则降级并不总是一种选择。