作为编程社区的很多人,我也在尝试为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");
}
答案 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
的末尾。