在ANTLR中,是否存在用于表示某些规则集的所有排列的交替的捷径符号? [英] In ANTLR, is there a shortcut notation for expressing alternation of all the permutations of some set of rules?
问题描述
在ANTLR中,我想定义如下规则:
In ANTLR I want to define a rule like this:
规则:(a b c | a c b | b a c | b c a | c a b | c b a);
rule : ( a b c | a c b | b a c | b c a | c a b | c b a );
但是,在我的情况下,我想置换10条规则而不是3条规则,因此它变得非常不切实际. 有什么方法可以在ANTLR中表达这一点而不必编写所有排列吗?
But in my case I have 10 rules instead of three, that I want to permute so it gets very impractical. Is there any way of expressing this in ANTLR without having to write all the permutations?
推荐答案
我将一次或多次匹配任何a
,b
或c
:
I would just match any a
, b
or c
once or more:
rule
: ( a | b | c )+
;
,然后在解析之后遍历解析树并检查a
,b
和c
是否都完全匹配一次.
and then, after parsing, traversing the parse tree and checking if a
, b
and c
all matched exactly once.
但是,是的,在语法本身中可以通过在需要时使用谓词来实现.
But Yes, it is possible in the grammar itself by using predicates where needed.
演示:
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();};
上面的演示语法使用2种不同的谓词: 1)一个门控语义谓词 i 以确保permutation
规则只匹配参数final int n
标记和 2),一个验证语义谓词 i 以确保set
准确地保存final int n
元素以确保它是5个标记的正确排列.
The demo grammar above uses 2 different types of predicates: 1) a gated semantic predicate i to make sure that the permutation
rule matches no more than the parameter final int n
tokens, and 2) a validating semantic predicate i to ensure that the set
holds exactly the final int n
elements to ensure that it's a proper permutation of the 5 tokens.
有关语义谓词的更多信息,请参见:什么是语义"谓词"在ANTLR中?
More info about semantic predicates can be found here: What is a 'semantic predicate' in ANTLR?
您可以使用以下课程测试语法:
You can test the grammar with the following class:
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();
}
}
java -cp antlr-3.3.jar org.antlr.Tool Permutation.g
javac -cp antlr-3.3.jar *.java
java -cp .:antlr-3.3.jar Main "A B C D E"
parsed: ABCDE
java -cp .:antlr-3.3.jar Main "B D C E A"
parsed: BDCEA
java -cp .:antlr-3.3.jar Main "A B C D B"
line 1:9 rule permutation failed predicate: {set.size() == n}?
parsed: null
这篇关于在ANTLR中,是否存在用于表示某些规则集的所有排列的交替的捷径符号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!