使用ANTLR,是否有一种方法可以编写解析器规则,以便它可以表达:x和/或y和/或z以任何顺序而无需编写Java。例如,它应该匹配:"x y"、"y z"和"x y z",但不应匹配"x x y"。我能想到的最好方法是下面的规则,但我需要在树遍历器中检查"x x y"。
rule: ( x | y | z )* ;
虽然你可以做一些类似于:
rule: x
| y
| z
| x y
| y x
| x z
| z x
| y z
| z y
| x y z
| x z y
| y x z
| y z x
| z x y
| z y x;
rule: x? y? z?
| x? z? y?
| y? x? z?
| y? z? x?
| z? x? y?
| z? y? x?
;
我能想到的最好的是...
grammar Sandbox;
@members {
boolean a, b, c;
}
start: ( 'test' test )+ EOF ;
test:
{a=b=c=true;} // Reset
( {a}? a {a=false;}
| {b}? b {b=false;}
| {c}? c {c=false;}
)* ;
a: 'a';
b: 'b';
c: 'c';
WS : [ \t\r\n]+ -> skip ;
而测试驱动程序...
package sandbox;
import org.antlr.v4.runtime.*;
public class Main {
public static void main(String[] args) {
new Main();
}
private Main() {
System.out.println("Should be OK...");
test("test a b c test c test c b a test c");
System.out.println("Should fail...");
test("test c a a");
}
private void test(String toTest) {
final CharStream cs = CharStreams.fromString(toTest);
final SandboxLexer lexer = new SandboxLexer(cs);
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final SandboxParser parser = new SandboxParser(tokens);
parser.start();
}
}