解释器的antlr4语法 - 在输入文件中定义入口点

时间:2013-12-24 19:29:33

标签: antlr4

我试图了解如何使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开始执行。例如如何发现/获取“主要”令牌/规则然后开始访问那里,而不是文件/树的顶部?

非常感谢提前。

凯文

1 个答案:

答案 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

一周只做这件事,所以寻求建议和更好的答案。