我不敢相信我是第一个问这个问题的人!当使用ANTLR4时,我需要访问者遍历分析树并进行一些修改,所以我需要访问每个树节点中的子树。这里是我的Fortran语法的一个片段:如何通过访问者访问ANTLR4中的重复子树?
ifStatement
: IF_KEYWORD expression
((THEN_KEYWORD
executableStatement*
elseIfStatement* // <--- problem is here
elseStatement?
END_KEYWORD IF_KEYWORD
) | executableStatement)
;
elseIfStatement
: ELSE_KEYWORD IF_KEYWORD expression THEN_KEYWORD executableStatement*
;
正如你所看到的,有在ifStatement
重复子树elseIfStatement
。当我创建解析树访问者,我想访问被解析的所有elseIfStatement
上下文:
public Void visitIfStatement(FortranParser.IfStatementContext ctx) {
...
for (FortranParser.ElseIfStatementContext elsIf : ctx.elseIfStatement()) // ERROR!!!
visitElseIfStatement(elseIf);
...
return null;
}
但ctx.elseIfStatement()
只返回的elseIfStatement
第一次出现为:
if (a == 1) then
a = 2
else if (b == 1) then |
b = 3 | -> returned by ctx.elseIfStatement()
else if (c == 1) then \
c = 4 \ -> ignored??
else
d = 4
end if
所以如何访问所有elseIfStatement
子树?这个问题适用于上面的所有解析器规则模式,其中'*'为executableStatement*
。
巴特,感谢您的帮助!我遵循你的建议,并在'class IfMultipleStatementsContext'中得到了'public List elseIfStatement()'。我认为ANTLR4不喜欢我以前的规则风格?无论如何我会报告这个问题。 –
@LiDong,不客气。 –
我还有一个问题。由于我们已经标记了其他规则,如果我们有另一个规则包含'ifStatement',那么我们该如何回到'ifMultipleStatements'或'ifSingleStatement'。我在IfStatementContext类中看不到它们。 –