antlr - 指定具有任何序列的解析器规则

antlr - specify a parser rule with any sequence

我有一段 ALTLR 语法是这样的:

mainfilter: mandatoryfilter (optionalfilter1)? (optionalfilter2)? (optionalfilter3)? ;
mandatoryfilter: 'NAME' '=' ID;
optionalfilter1: 'VALUE1' EQ ID; 
optionalfilter1: 'VALUE2' EQ ID; 
optionalfilter1: 'VALUE3' EQ ID; 
EQ: '=' ;

ID: [A-Za-z0-9]+
//Also I will skip spaces and whitespace

我的要求是 "optionalfilter" 规则可以按任何顺序出现。 我想到的一种方法是像下面这样重写规则,然后使用监听器进行验证:

mainfilter: mandatoryfilter (optionalfilter1|optionalfilter2|optionalfilter3)*;

实现此目的的另一种方法是将所有组合分别放入一个解析器规则中。但如果 optionalfilter 的数量增加,这可能不是一个更明智的解决方案。

示例输入:

NAME = BOB VALUE1=X VALUE2=Y VALUE3 = Z
NAME = BILL VALUE3=X VALUE1=Y VALUE2 = Z

我的语法将成功解析第一个输入但不能解析第二个输入。

那么在我的语法中是否有一种优雅的方式来处理这个问题?

So is there an elegant way to handle this in my grammar itself ?

没有

通常匹配零个或多个然后解析后验证过滤器只出现一次。

以 Java 语言规范为例,它定义了 class definition 可以有零个或多个 class 修饰符({ClassModifier} 部分)

NormalClassDeclaration:
  {ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody

ClassModifier:
  (one of) 
  Annotation public protected private abstract static final strictfp

这将匹配 public public class Foo {}。这在解析后的阶段被拒绝了。