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



下面是我的代码:

@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;
}

}

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

问题是:输入- 12/29(它应该转到月分隔符日路径,因为第一个失败)。解析器抛出没有可行的输入在29…因为29不满足在@member中定义的月份标准。在这种情况下,12根据日期方法(1-31)通过,之后29将进行月检查(1-12)并且失败。它应该回溯到根并遵循第二条路径,而不是在29异常时给出No Viable Input。

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

TWO_DIGIT : [0-9][0-9];
date
    : {twoDigitDay(getCurrentToken().getText()) && twoDigitMonth(_input.LT(3).getText())}? 
        TWO_DIGIT '/' TWO_DIGIT # dayAndMonth
    | {twoDigitMonth(getCurrentToken().getText()) && twoDigitDay(_input.LT(3).getText())}?
        TWO_DIGIT '/' TWO_DIGIT # monthAndDay
    ;

当我们开始匹配规则date时,我们首先检查dayAndMonth命名的替代。只有当第一个数字是正确的日,第二个数字是正确的月(用_input.LT(3)令牌表示),我们才匹配dayAndMonth。否则,我们将匹配monthAndDay命名替代

相关内容

  • 没有找到相关文章

最新更新