我有一段ALTLR语法是这样的:
mainfilter: mandatoryfilter (optionalfilter1)? (optionalfilter2)? (optionalfilter3)? ;
mandatoryfilter: 'NAME' '=' ID;
optionalfilter1: 'VALUE1' EQ ID;
optionalfilter2: 'VALUE2' EQ ID;
optionalfilter3: 'VALUE3' EQ ID;
EQ: '=' ;
ID: [A-Za-z0-9]+
//Also I will skip spaces and whitespace
我的要求是"可选过滤器"规则可以按任何顺序出现。 我想到的一种方法是重写如下所示的规则,然后使用侦听器进行验证:
mainfilter: mandatoryfilter (optionalfilter1|optionalfilter2|optionalfilter3)*;
实现此目的的另一种方法是将所有组合分别放在一个解析器规则中。 但如果可选过滤器的数量增加,这可能不是一个更明智的解决方案。
示例输入:
NAME = BOB VALUE1=X VALUE2=Y VALUE3 = Z
NAME = BILL VALUE3=X VALUE1=Y VALUE2 = Z
我的语法将成功解析第一个输入,但不会解析第二个输入。
那么在我的语法本身中是否有一种优雅的方法来处理这个问题?
那么在我的语法本身中是否有一种优雅的方法来处理这个问题呢?
不。
通常,匹配零个或多个,然后在解析后,验证筛选器仅出现一次。
以 Java 语言规范为例,该规范定义类定义可以具有零个或多个类修饰符({ClassModifier}
部分(
NormalClassDeclaration:
{ClassModifier} class Identifier [TypeParameters] [Superclass] [Superinterfaces] ClassBody
ClassModifier:
(one of)
Annotation public protected private abstract static final strictfp
这将匹配public public class Foo {}
.这在解析后的阶段被拒绝。