【问题标题】:antlr4 switch statement grammar to visitorantlr4 switch 语句语法到访问者
【发布时间】:2018-05-23 15:58:28
【问题描述】:

作为编程社区的许多人,我也在尝试为 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");
}

【问题讨论】:

  • 我不确定问题是什么。你的语法有问题吗?还是您在问//code to write here 部分应该包含什么?后者在很大程度上取决于您的访问者应该做什么。
  • 我的语法和解析树工作正常!我不知道在 //code to write here 部分写什么,这样它会查看 switch 和 case 语句的内部,并根据我将给出的值执行代码。
  • 您的源语言是否有隐含的breaks?也就是说,如果aNumber == 1,您的示例代码应该打印“return 1”还是"return 1return 2"(在Java中,由于缺少breaks,它会打印后者)?

标签: java intellij-idea antlr4 intellij-plugin


【解决方案1】:

从您的评论看来,您正在编写一个解释器,它直接在访问者中执行代码,而不通过任何 IR 或类似的东西(如果我误解了,请纠正我)。

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

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

但这不是问题,因为没有人说你必须使用switch 来实现switch。您可能知道,开关只是编写一系列if 语句的一种更方便(而且通常更高效)的方式。在你的例子中(假设你的语言有隐含的breaks),那就是:

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

这对您的解释器意味着您可以评估您正在打开的表达式,然后循环遍历所有情况,并将评估的数字与case 的值与if 进行比较。只要其中一个条件匹配,您就会执行相关代码并跳出循环。

如果你没有隐式breaks,你应该只在遇到break时才跳出循环,否则使用标志来记住你是否已经遇到了一个真正的条件,然后执行每个后续代码块,直到遇到break 或到达switch 的末尾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 2010-12-20
    • 2018-10-07
    • 1970-01-01
    相关资源
    最近更新 更多