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 {}
。这在解析后的阶段被拒绝了。
我有一段 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 {}
。这在解析后的阶段被拒绝了。