使用此虚拟antlr4-语法:
grammar testingGrammar;
@header{package gen;}
dsopt_rename: 'rename' (OLDN=ID '=' NEWN=ID)+;
ID: [a-zA-Z_];
我的目标是Java。我想得到两个列表:oldNames和newNames;可以这样:
@Override
public DsOption visitDsopt_rename(Dsopt_renameContext ctx) {
LinkedList<String> oldNames = new LinkedList<String>();
LinkedList<String> newNames = new LinkedList<String>();
for (int i=0; i < ctx.ID().size(); ++i) {
LinkedList<String> rename = (i%2 == 1) ? oldNames : newNames;
rename.add(ctx.ID(i).getText());
}
return new DsOptRename(oldNames, newNames);
}
我更喜欢以下的-也称为“第二种方法”((如果可行)):
@Override
public DsOption visitDsopt_rename(Dsopt_renameContext ctx) {
LinkedList<String> oldNames = new LinkedList<String>();
LinkedList<String> newNames = new LinkedList<String>();
ctx.OLDN().forEach(e -> oldNames.add(e.getText()));
ctx.NEWN().forEach(e -> oldNames.add(e.getText()));
return new DsOptRename(oldNames, newNames);
}
显然,标签ctx.OLDN(不带括号)和ctx.NEWN只保留列表的第一个迭代,而不是整个列表(例如,ID保留整个列表)。
第一个问题: 1.是否可以通过使用第二种方法(即不触及语法)来修复第二种代码以完成工作?请记住,此示例非常简单,因此第一个代码可以正常工作,但是我是否有类似“ example:(ID ID?ID)+;”的规则?将需要另一种方法;也许不可能修复它,因为这种方法最初不应该起作用(规则应该有不同的定义)。
grammar testingGrammar;
@header{package gen;}
dsopt_rename: 'rename' (oldn '=' newn)+;
oldn: ID;
newn: ID;
ID: [a-zA-Z_];
但是它可能容易出错,因为oldn和newn可能会意外匹配。
感谢您的时间!
答案 0 :(得分:3)
使用+=
表示法收集令牌:
grammar testingGrammar;
dsopt_rename
: 'rename' ( lhs+=ID '=' rhs+=ID )+
;
ID : [a-zA-Z_];
SPACES : [ \t\r\n]+ -> skip;
像这样测试它:
String source = "rename a = A b = B c = C";
testingGrammarLexer lexer = new testingGrammarLexer(CharStreams.fromString(source));
testingGrammarParser parser = new testingGrammarParser(new CommonTokenStream(lexer));
testingGrammarParser.Dsopt_renameContext ctx = parser.dsopt_rename();
List<Token> lhsTokens = ctx.lhs;
List<Token> rhsTokens = ctx.rhs;
System.out.printf("lhsTokens=%s\nrhsTokens=%s\n", lhsTokens, rhsTokens);
将打印:
lhsTokens=[[@1,7:7='a',<3>,1:7], [@4,13:13='b',<3>,1:13], [@7,19:19='c',<3>,1:19]]
rhsTokens=[[@3,11:11='A',<3>,1:11], [@6,17:17='B',<3>,1:17], [@9,23:23='C',<3>,1:23]]
更多信息:https://github.com/antlr/antlr4/blob/master/doc/parser-rules.md#rule-element-labels