我有一段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
我的语法将成功解析第一个输入而不是第二个输入。
那么在我的语法本身中有一种优雅的方法可以解决这个问题吗?
答案 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 {}
。这在解析后的阶段被拒绝。