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

ANTLR4实现基于参数类型的Excel函数重载解析问题

Excel函数解析器重载匹配问题

问题描述

我开发了一款Excel函数解析器,需基于参数类型处理函数重载。核心问题在于数字与字符串列的类型依赖外部上下文,解析器需要根据列上下文选择匹配的函数:

  • 输入表达式IFNA(123, 234) → 正确解析为number_function
  • 输入表达式IFNA("foo", "bar") → 正确解析为string_function

但使用列时出现异常:

columnsContext = {
   column1: Type.String
   column2: Type.String
}

输入表达式:IFNA(column1, column2)
该表达式应根据列类型解析为string_function,但因语法中number_function声明在前,被错误识别为number_function。

我尝试通过语义谓词结合自定义解析器处理,但执行isNumber()时抛出noViableAlt异常——解析器已将IFNA识别为number_function,但列类型为字符串,谓词返回false。

相关代码

初始语法

grammar ExcelLikeFunctionsGrammar;
expression : number | string;
number_function:
    IFNA LEFT_PAREN number COMMA number RIGHT_PAREN |
    ... other functions;
string_function:
    IFNA LEFT_PAREN string COMMA string RIGHT_PAREN |
    ... other functions;
number : NUMBER_CONSTANT | number_function | number_column ;
string : STRING_CONSTANT | string_function | string_column ;
number_column: ALPHANUMERIC;
string_column: ALPHANUMERIC;

修改后带语义谓词的语法

grammar ExcelLikeFunctionsGrammar;
// 该方法会在自定义解析器中被覆盖
    @members {
        protected boolean isNumber() {
            return true;
        }
        protected boolean isString() {
            return true;
        }
    }
expression : number | string;
number_function:
    IFNA LEFT_PAREN number COMMA number RIGHT_PAREN |
    ... other functions;
string_function:
    IFNA LEFT_PAREN string COMMA string RIGHT_PAREN |
    ... other functions;
number : NUMBER_CONSTANT | number_function | {isNumber()}? number_column ;
string : STRING_CONSTANT | string_function | {isString()}? string_column ;
number_column: ALPHANUMERIC;
string_column: ALPHANUMERIC;

自定义解析器代码

public class ExcelLikeFunctionsGrammarCustomParser extends ExcelLikeFunctionsGrammarParser {
    private final ReferenceContext referenceContext;
    public ExcelLikeFunctionsGrammarCustomParser(TokenStream input, ReferenceContext referenceContext) {
        super(input);
        this.referenceContext = referenceContext;
    }
    @Override
    protected final boolean isNumber() {
        return checkColumnTokenType(TableColumnType.DECIMAL);
    }
    @Override
    protected final boolean isString() {
        return checkColumnTokenType(TableColumnType.STRING);
    }
    private boolean checkColumnTokenType(TableColumnType columnType) {
        return checkTypeLogic(...);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 11:48:18