antlr - 使用任何序列

时间:2018-06-03 13:10:27

标签: parsing antlr4

我有一段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”规则可以按任何顺序发生。 我想到的一种方法是重写下面的规则,然后使用Listener进行验证:

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

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

示例输入:

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

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

那么在我的语法本身中有一种优雅的方法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

  

那么在我的语法本身中有一种优雅的方法可以解决这个问题吗?

没有

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

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

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

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

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