Antlr4 - 表示检查任意数量的令牌的句法谓词

时间:2018-01-11 08:00:18

标签: java c++ parsing antlr4 antlr3

在Antlr3中,我有以下语法:

ruleA:
    (ruleBStart) => ruleB
    | ruleC
;

为简单起见,我们假设ruleB是SQL中SELECT语句的语法,但可以嵌套在任意数量的LPAREN中。通过简单地说:

,这很容易用旧语法表示
ruleBStart:
    (LPAREN)* SELECT
;

在Antlr4中,如果我想做同样的事情,我会编写一个语义谓词isRuleBStart(),它可能看起来像这样(伪代码):

@parser::members{
    public boolean isRuleBStart(int tokenNum)
    {
        int token = _input.LA(tokenNum);
        if (token == EOF) return false; // handling EOF probably needs more work
        if (token == SELECT) return true;
        if (token == LPAREN) return isRuleBStart(tokenNum++);
        return false;
    }
}

然后在我的语法中,我会这样做:

ruleA:
    {isRuleBStart(1)}? ruleB
    | ruleC
;

这对我来说似乎有问题:

  1. 它涉及已经传言的构造中的递归以降低性能
  2. 如果ruleBStart规则有一组任意不同的令牌要检查,而不是仅仅重复LPAREN,那么
  3. ruleBStart会变得复杂得多
  4. 它将我的代码绑定到目标语言。因此,如果我想在Java和C ++中发布解析器,我将不得不在两者中重新实现这个语义谓词。 (我知道可以仔细编写语义谓词,所以相同的代码在Java和C ++中工作,但这不是重点。)
  5. 所以我想问一下社区是否有正确的Antlr4方法来实现相同的结果。

1 个答案:

答案 0 :(得分:0)

不需要ANTLR4的语义谓词。如果需要,ALL(*)算法将做无限的预测,因此不需要语义谓词或任何可比较的黑客。

所以,只需删除该谓词,一切都应该正常工作。