You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ANTLR4的自定义语言Switch语句Visitor实现求助

实现ANTLR4 Visitor处理Switch语句的思路与代码示例

看起来你已经走在正确的路上了!处理switch语句的核心逻辑就是先计算switch表达式的值,再遍历所有case分支,匹配到对应值时执行分支内的语句。结合你的语法规则和现有代码,我给你整理一下具体的实现方向和代码示例:

核心步骤拆解

  • 提取并校验switch表达式的值:你已经完成了类型检查,接下来只需把InputValue转换为具体的整数类型(假设你的InputValue类提供了asInteger()这类取值方法)。
  • 遍历所有case分支:通过ctx.case_rule()获取所有case节点,逐个处理每个分支。
  • 匹配case值与switch值:对每个case,先计算它的any_var值,同样要确保是整数类型(避免类型不匹配的运行时错误),再和switch表达式的值做对比。
  • 执行匹配成功的case语句:如果值匹配,就调用visit()执行case对应的statement;如果你的语法需要支持fall-through(像示例里那样没有break的场景),匹配后会继续遍历后续case,否则可以额外添加break逻辑(不过你的语法里没定义break,暂时按fall-through处理)。

修改后的Visitor代码示例

@Override
public InputValue visitSwitch_rule(AdamantParser.Switch_ruleContext ctx) {
    // 1. 获取并校验switch表达式的整数值
    InputValue switchInput = this.visit(ctx.any_var().getChild(0));
    if (!switchInput.isInteger()) {
        throw new RuntimeException("switch value is not an integer");
    }
    int switchValue = switchInput.asInteger(); // 假设InputValue有asInteger()方法

    // 2. 遍历所有case分支
    for (AdamantParser.Case_ruleContext caseCtx : ctx.case_rule()) {
        // 3. 获取case的取值并校验类型
        InputValue caseInput = this.visit(caseCtx.any_var());
        if (!caseInput.isInteger()) {
            throw new RuntimeException("case value is not an integer");
        }
        int caseValue = caseInput.asInteger();

        // 4. 匹配成功则执行对应语句
        if (caseValue == switchValue) {
            this.visit(caseCtx.statement());
            // 如果后续要支持break,这里可以添加终止循环的逻辑,比如:
            // break; (当前语法无break,暂时注释)
        }
    }

    return InputValue.VOIDval;
}

额外补充说明

  • 关于fall-through逻辑:上面的代码是严格匹配值才执行的逻辑,如果需要实现传统的fall-through(匹配到某个case后,继续执行后续所有case的语句,不管值是否匹配),可以添加一个标志位来控制:
    boolean isMatched = false;
    for (AdamantParser.Case_ruleContext caseCtx : ctx.case_rule()) {
        InputValue caseInput = this.visit(caseCtx.any_var());
        if (!caseInput.isInteger()) {
            throw new RuntimeException("case value is not an integer");
        }
        int caseValue = caseInput.asInteger();
    
        // 首次匹配成功后,标记为已匹配
        if (!isMatched) {
            isMatched = (caseValue == switchValue);
        }
    
        // 已匹配状态下,执行所有后续case的语句
        if (isMatched) {
            this.visit(caseCtx.statement());
        }
    }
    
  • 关于default分支:如果之后要扩展default逻辑,只需在语法规则中添加default_rule: DEFAULT PRES statement;,然后在遍历case的最后,检查是否有匹配记录,若没有则执行default分支的语句。

这样应该就能满足你的需求啦!

内容的提问来源于stack exchange,提问作者SoftDev30_15

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:51:23