我试图了解如何使antlr4在输入文件中的给定点执行而不是在顶部执行。我从SO用户那里获得了建议,并使用Antlr4访问者开始了解决方案。
我的输入文件声明'BASIC'就像子程序一样,底部有一个Main。输入文件示例:
#Program hello;
Sub mysub1()
print "please dont call me but I know you will";
End Sub
Sub mysub2()
#code
End Sub
Main() #execute code from here
call mysub2;
EndMain
不出所料,它在Sub中执行任何代码,因为它与从顶部开始不知道任何不同。
我的语法文件包含
prog
: stat* 'Main' stat* 'EndMain' EOF
;
stat
: call_sub
| assignment
| if_stat
| while_stat
...
所以第一个stat *执行 - 这就是我的观点,我如何从Main开始执行。例如如何发现/获取“主要”令牌/规则然后开始访问那里,而不是文件/树的顶部?
非常感谢提前。
凯文
答案 0 :(得分:1)
我的解决方案是在扩展的BaseVisitor类中声明一个布尔maindone = false,然后在我的
中public Value visitBeginSublabel(@NotNull t5Parser.BeginSublabelContext ctx) {
if (maindone == false){
subs.put(ctx.ID().toString(),ctx); // stash the function/sub name to HashMap
//main not done. skipping activity
return null;
}
...
}
访问visitMain时
@Override public Value visitMain(@NotNull t5Parser.MainContext ctx) {
maindone=true;
...
这似乎已经成功了。我还整理了语法,因此只能在全局级别和其他一些必要项目中声明变量。
我并不是说这是完成这项练习的最佳方式,但肯定是有效的。我也声明了
public Map< String,t5Parser.BeginactivitylabelContext>subs = new HashMap<String,t5Parser.BeginactivitylabelContext>();
因为当我从另一个函数调用它时我想快速查找子例程名称,所以在我的visitCall函数中
public Value visitCall(@NotNull t5Parser.CallContext ctx) {
this.visit(subs.get(ctx.ID().toString()));
...
我的源文件有
Main
call myfunction()
EndMain
一周只做这件事,所以寻求建议和更好的答案。