我试图弄清楚如何使 antlr4 在输入文件中的给定点而不是顶部执行。我听取了SO用户的建议,并使用Antlr4 Visits开始了一个解决方案。
我的输入文件像子例程一样声明"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
...
因此,第一个统计数据*被执行 - 这就是我的观点,我如何让执行从 Main 开始,例如,我如何发现/获取"主"令牌/规则然后开始访问那里,而不是文件/树的顶部?
提前非常感谢。
凯文
我的解决方案是在扩展的 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;
}
...
}
和访问时访问主要
@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
一周只做这些事情,所以寻找建议和更好的答案。