Java 当第二个谓词失败时,Antlr4不遵循备用路径

Java 当第二个谓词失败时,Antlr4不遵循备用路径,java,antlr,antlr4,Java,Antlr,Antlr4,这是我的密码: @parser::members { public boolean twoDigitDay(String text) { try { int day = Integer.parseInt(text); if (day >= 1 && day <= 31) { return true; } } catch (Exception e)

这是我的密码:

@parser::members {

public boolean twoDigitDay(String text) {
    try {
        int day = Integer.parseInt(text);
        if (day >= 1 && day <= 31)
        {
            return true;
        }
    }
    catch (Exception e)
    {

    }
    return false;
}
public boolean twoDigitMonth(String text) {
    try {
        int day = Integer.parseInt(text);
        if (day >= 1 && day <= 12)
        {
            return true;
        }
    }
    catch (Exception e)
    {
    }
    return false;
}
这里的问题是:
输入-12/29(由于第一次失败,应转到月分隔日路径)。解析器在29处没有抛出任何可行的输入。。。因为29不满足@member中定义的月份标准。在这种情况下,在29将进行月检查(1-12)之后,根据日期方法(1-31)通过12,但失败。它应该回溯到根并遵循第二条路径,而不是在29异常时不提供任何可行的输入

让我们将语义谓词直接移动到
date
语法规则

两位数字:[0-9][0-9];
日期
:{twoDigitDay(getCurrentToken().getText())和&twoDigitMonth(_input.LT(3.getText())}?
两位数“/”两位数#日和月
|{twoDigitMonth(getCurrentToken().getText())和&twoDigitDay(_input.LT(3.getText())}?
两位数“/”两位数#月日
;

当我们开始匹配规则
日期
时,我们首先检查
日期和月份
命名的备选方案。只有当第一个数字是正确的日期,第二个数字是正确的月份(用
\u input.LT(3)
标记表示),我们才匹配
日和月。否则,我们将匹配
monthAndDay
命名的替换项。

让我们将语义谓词直接移动到
date
语法规则

两位数字:[0-9][0-9];
日期
:{twoDigitDay(getCurrentToken().getText())和&twoDigitMonth(_input.LT(3.getText())}?
两位数“/”两位数#日和月
|{twoDigitMonth(getCurrentToken().getText())和&twoDigitDay(_input.LT(3.getText())}?
两位数“/”两位数#月日
;

当我们开始匹配规则
日期
时,我们首先检查
日期和月份
命名的备选方案。只有当第一个数字是正确的日期,第二个数字是正确的月份(用
\u input.LT(3)
标记表示),我们才匹配
日和月。否则我们将匹配
monthAndDay
namedalternative.

hiquepas,这只是我的日期语法的一个代码片段。还有很多其他的案例处理大约100种类型的日期。您提出的解决方案可能过于复杂,无法实施。我主要关心的是,如果没有可行的Alt异常,为什么ANTLR不转到下一个规则并检查?有什么办法可以强制要求Antlr4检查下一条规则吗?@Shiva嗨,因为我知道我没有什么好的解决办法。也许我以后会想点什么:)嗨,奎帕斯,这只是我约会语法的一个代码片段。还有很多其他的案例处理大约100种类型的日期。您提出的解决方案可能过于复杂,无法实施。我主要关心的是,如果没有可行的Alt异常,为什么ANTLR不转到下一个规则并检查?有什么办法可以强制要求Antlr4检查下一条规则吗?@Shiva嗨,因为我知道我没有什么好的解决办法。也许我以后会想出办法:)
date        :   day seperator month
        |   month seperator day
        ;

day             :   dayTwoDigits ;
month           :   monthTwoDigit;
monthTwoDigit   :   {twoDigitMonth(getCurrentToken().getText())}? TWO_DIGITS;
dayTwoDigits    :   {twoDigitDay(getCurrentToken().getText())}? TWO_DIGITS;
seperator   :   ('/');
ONE_DIGIT   :   [0-9];
TWO_DIGIT   :   ONE_DIGIT ONE_DIGIT