如何通过访问者访问ANTLR4中的重复子树?
我不敢相信我是第一个问这个问题的人!在使用ANTLR4时,我需要一个访问者遍历解析树并进行一些修改,因此我需要访问每个树节点中的子树。以下是我的Fortran语法片段:如何通过访问者访问ANTLR4中的重复子树?,antlr4,Antlr4,我不敢相信我是第一个问这个问题的人!在使用ANTLR4时,我需要一个访问者遍历解析树并进行一些修改,因此我需要访问每个树节点中的子树。以下是我的Fortran语法片段: ifStatement : IF_KEYWORD expression ( ( THEN_KEYWORD executableStatement* elseIfStatement* // <--- problem is here elseSt
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*
;
但是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*
的解析器规则模式。可能是一个bug,如果我删除|executableStatement
替代项,ctx.elseIfStatement()
会返回一个列表。您可能要报告它:
但是,当您现在这样做时,您将被迫执行一些null
检查,以查看哪个选项匹配。更好的方法是:
这将产生以下结果:
public static class IfMultipleStatementsContext extends IfStatementContext {
...
public List<ElseIfStatementContext> elseIfStatement() {
return getRuleContexts(ElseIfStatementContext.class);
}
...
}
公共静态类ifmultipleStatementContext扩展了IfStatementContext{
...
公共列表其他声明(){
返回getRuleContext(ElseIfStatementContext.class);
}
...
}
也就是说:它生成了适量的ElseIfStatementContext
s.可能是一个bug,如果我删除| executableStatement
替代项,ctx.elseIfStatement()
会返回一个列表。您可能要报告它:
但是,当您现在这样做时,您将被迫执行一些null
检查,以查看哪个选项匹配。更好的方法是:
这将产生以下结果:
public static class IfMultipleStatementsContext extends IfStatementContext {
...
public List<ElseIfStatementContext> elseIfStatement() {
return getRuleContexts(ElseIfStatementContext.class);
}
...
}
公共静态类ifmultipleStatementContext扩展了IfStatementContext{
...
公共列表其他声明(){
返回getRuleContext(ElseIfStatementContext.class);
}
...
}
即:它生成适量的ElseIfStatementContext
s.Bart,谢谢您的帮助!我听从了你的建议,并在类IfMultipleStatementsContext
中获得了公共列表elseIfStatement()
。我想ANTLR4不喜欢我以前的规则风格?无论如何,我会报告这个问题。我还有一个问题。既然我们已经标记了替代规则,那么如果我们有另一个规则包含ifStatement
,那么我们如何着手处理ifmultiplestatement
或ifSingleStatement
。我在IfStatementContext
类中没有看到它们。@LiDong,我没有测试它,但我想你应该将IfStatementContext
转换为ifmultiplestatementcontext
或IfSingleStatementContext
。我怎么知道应该转换哪一个呢?通过检查一些子树的存在?谢谢@李东,我想你在施展之前需要在IfStatementContext
上有一个(不太漂亮的)instanceof
。巴特,谢谢你的帮助!我听从了你的建议,并在类IfMultipleStatementsContext
中获得了公共列表elseIfStatement()
。我想ANTLR4不喜欢我以前的规则风格?无论如何,我会报告这个问题。我还有一个问题。既然我们已经标记了替代规则,那么如果我们有另一个规则包含ifStatement
,那么我们如何着手处理ifmultiplestatement
或ifSingleStatement
。我在IfStatementContext
类中没有看到它们。@LiDong,我没有测试它,但我想你应该将IfStatementContext
转换为ifmultiplestatementcontext
或IfSingleStatementContext
。我怎么知道应该转换哪一个呢?通过检查一些子树的存在?谢谢@李东,我想你在施放之前需要在IfStatementContext
上有一个(不太漂亮的)instanceof
。
public static class IfMultipleStatementsContext extends IfStatementContext {
...
public List<ElseIfStatementContext> elseIfStatement() {
return getRuleContexts(ElseIfStatementContext.class);
}
...
}