当前位置: 首页 > 知识库问答 >
问题:

ANTLR4:在一般情况下,是否可以验证解析器规则的各个部分?

鲜于致远
2023-03-14

在使用ANTLR4时,我总是回到同样的问题--如何在解析器中实现算法规则验证。

例如,在匹配规则之前,我需要解析器验证写入“月、日、年”的日期的“年”部分。我已经学会了使用谓词可以做到这一点,如下所示:

date :
    {isYear(_input.LT(3).getText())}?
        month  day=INTEGER  year=INTEGER     { ... }

但是这个解决方案不是一般的,因为它依赖于规则月份总是一个令牌长。

date :  month  day=INTEGER  yearInt     { ... } ;

yearInt returns [int i]
     :   {isYear(_input.LT(1).getText())}?
             yr=INTEGER                 { $i = $yr.int; }
     ;
throw new FailedPredicateException(this, "isYear(_input.LT(1).getText())");

但是代码随后继续并接受yearint()

这是ANTLR的虫子,还是我的虫子?是否有一种“适当”的方法来编写一个需要验证规则部分的语法?

共有1个答案

易宣
2023-03-14

试试看

date :
    month  day=INTEGER  year=INTEGER {isYear($year)}?<fail="A sensible error msg"> { ... }
;

date :
    month  day=INTEGER  year=INTEGER {if ( ! isYear($year) ) 
                                       notifyErrorListeners("A sensible error msg");
                                     }     
    { ... }
;

其中一个将产生更明智的错误消息。notifyErrorListeners()建立错误,但就正在进行的解析而言,让解析“成功”。{isYear($year)}?会失败,并做更多的寻找匹配。

 类似资料:
  • 我对是否允许以下情况感到困惑: UPDATE:我知道当我在for循环中提供正确的声明类型时,它就会工作。问题是如果我不这样做会发生什么?

  • 如果我正确理解了这个答案,并参考了标准部分[dcl.type.auto.deduct-5],代码: 总是相当于 但是现在问题出现了,如果我把lambda表达式放在中,而不是: 令我惊讶的是,它在gcc和clang中都编译成功。我所经历的震惊的原因在于标准,其中特别指出lambda不应该出现在未赋值的操作数[expr.prim.lambda#2](emphasis mine)中: lambda表达式

  • 可能在内部使用的代码将在规则之后被取消,如下所示: ANTLR4就是这样做事的吗?

  • 我是JAXB的新手,继承了一个项目,该项目使用它来编组/取消编组xml-已经使用各种JAXB注释编写了自定义验证-目前没有使用模式。 我需要在解组时添加一些验证,以检查给定元素是否只发生一次-从搜索来看,它通常是在xsd中使用"maxOccurs=1"实现的-所以我的问题是这可以使用任何JAXB验证注释来实现吗? 例如(为简单起见,缩短了版本)-目前最后一个值'NameIII'被解组,但当存在多个

  • 我的语法在很大程度上必须忽略空格,除非在某些上下文中。这个问题的答案建议定义特定的lexer规则来处理我想要的异常。 问题是(我认为)我不能在lexer级别处理这种情况,因为它们似乎是在解析器级别被触发的。 更具体地说:我想认识一些东西,比如 记住我有一个WS- 在Xtext中,规则可以在规则范围的基础上指定在规则范围内应用哪些隐藏令牌: 但是我对antlr4一无所知。

  • 问题内容: 例如,如果我具有以下HTML: 和这个CSS: 就像在脚本语言中一样,您具有通常在脚本顶部编写的通用函数,而每次需要使用该函数时,只需调用该函数即可,而不必每次都重复所有代码。 问题答案: 不,您不能从另一个引用一个规则集。 但是,您可以在样式表中的多个规则集上重用选择器, _并_在单个规则集上使用多个选择器通过用逗号分隔它们。 您还可以将多个类应用于单个HTML元素(class属性采