antlr4切换声明语法给访问者

时间:2018-05-23 15:58:28

标签: java intellij-idea antlr4 intellij-plugin

作为编程社区的很多人,我也在尝试为Java中的学校项目构建自己的编程语言。我正在使用antlr4和intellij,因为它在编写测试代码的同时帮助了很多生成树。我创建了一个访问者类来为我的代码添加功能,到目前为止,我能够创建一个if / else语句和一个while语句。所以我还想创建一个switch语句并将其实现到访问者类。我对switch语句的语法如下:

switch_rule: SWITCH LPAREN any_var RPAREN LBRACKET case_rule* RBRACKET;

case_rule:  CASE any_var PRES statement;

statement:
    expression
    | rule_ifset
    | rule_for
    | method_call
    | rule_whiledo
    | rule_dowhile
    | switch_rule
    | assign
    |var_declaration;

any_var :INT              # NumericConst
        | DOUBLE           # NumericConst
        | IDENTIFIER       # NumericVariable
        |boolean_var      # BooleanConst;

所以我假设我开始这样的方法:

@Override
public InputValue visitSwitch_rule(AdamantParser.Switch_ruleContext ctx) {
    InputValue value = this.visit(ctx.any_var().getChild(0));
    if(!value.isInteger()){throw new RuntimeException("switch value is not an integer");}
    else{
           //code to write here
    }

    return InputValue.VOIDval;
}

我想在switch方法中编写case语句,但我不知道如何从这里开始,我没有找到任何简单的例子......任何人都可以指向正确的方向,或提供一些简单的代码?提前谢谢。

编辑:我想要的语法的一个简单示例如下:

switch(aNumber){
   case 1: print("return 1");
   case 2: print("return 2");
}

1 个答案:

答案 0 :(得分:0)

从您的评论中,您似乎正在编写一名直接在访问者中执行代码的翻译,而无需通过任何IR或类似的内容(如果我误解,请纠正我)。

所以你的问题是,如果你甚至不知道会有多少switch个陈述,你就不能在你的代码中写一个case语句 - 你毕竟不能将case置于循环中。即使这不是问题,另一个问题是case语句需要编译时常量,但是您需要将它们与从解析树中提取的值一起使用。

如果您正在生成代码,那么这些都不是问题,因为您可以使用给定的值生成适当数量的案例,一切都会好的。但你不是,所以一切都是动态的,你不能使用switch

但这并不是问题,因为没有人说你必须使用switch来实施switch。您可能知道,切换只是编写一系列if语句的一种更方便(通常更高性能)的方式。在您的示例中(假设您的语言具有隐式break s),那就是:

if (aNumber == 1) {
    print("return 1");
} else if (aNumber == 2) {
    print("return 2");
}

这对您的口译员来说意味着您可以评估您开启的表达式,然后循环遍历所有案例,并针对每个案例将评估的数字与case的值进行比较if。只要其中一个条件匹配,就会执行相关代码并退出循环。

如果你没有隐含的break,你应该只在遇到break时突破循环,否则请使用标记来记住你是否已经已遇到真实条件,然后执行每个后续代码块,直到遇到break或到达switch的末尾。