antlr4 将语句语法切换到访问者



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

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");
}

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

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

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

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

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

这对您的解释器意味着您可以评估您正在打开的表达式,然后遍历所有情况,并针对每种情况将评估的数字与带有ifcase值进行比较。一旦其中一个条件匹配,您就会执行关联的代码并脱离循环。

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

相关内容

  • 没有找到相关文章

最新更新