在ANTLR中,是否有一个快捷符号表示某些规则集的所有排列的交替?

Par*_*ife 4 grammar parsing antlr rules

在ANTLR中,我想定义一个这样的规则:

规则:(abc | acb | bac | bca | cab | cba);

但在我的情况下,我有10个规则而不是3个,我想要置换,因此它变得非常不切实际.有没有办法在ANTLR中表达这一点而不必写出所有的排列?

Bar*_*ers 7

是的,通过在需要的地方使用谓词.

演示:

rule
 : ( a | b | c )+
 ;
Run Code Online (Sandbox Code Playgroud)

上述演示语法使用2种不同类型的谓词:1)一个门控语义谓词以确保该a规则不大于参数更匹配b的令牌,和2)一个验证语义谓词以确保c保持完全a元件,以确保这是5个令牌的正确排列.

有关语义谓词的更多信息可以在这里找到:ANTLR中的"语义谓词"是什么?

您可以使用以下类测试语法:

grammar Permutation;

parse
  :  permutation[5] {System.out.println("parsed: " + $permutation.text);} EOF
  ;

permutation[final int n]
@init{
  java.util.Set set = new java.util.HashSet();
  int counter = n;
}
  :  (
       {counter > 0}?=> token   // keep matching a `token` as long as `counter > 0`
       {                        //
         set.add($token.text);  // add the contents of `token` to `set`
         counter--;             // decrease `counter`
       }                        //
     )+ 
     {set.size() == n}?         // if `set.size() != n`, an exception is thrown
  ;

token
  :  A
  |  B
  |  C
  |  D
  |  E
  ;

A : 'A';
B : 'B';
C : 'C';
D : 'D';
E : 'E';

Space : ' ' {skip();};
Run Code Online (Sandbox Code Playgroud)
import org.antlr.runtime.*;

public class Main {
  public static void main(String[] args) throws Exception {
    PermutationLexer lexer = new PermutationLexer(new ANTLRStringStream(args[0]));
    PermutationParser parser = new PermutationParser(new CommonTokenStream(lexer));
    parser.parse();
  }
}
Run Code Online (Sandbox Code Playgroud)