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

如何通过Listener方法获取规则中的所有逻辑运算符Token?

解决ANTLR Listener提取逻辑运算符Token的问题

嘿,我来帮你搞定这个提取and/or运算符Token的问题!其实核心就是利用ANTLR的Listener机制,结合Parser上下文来获取这些关键字对应的Token,下面分步骤给你讲清楚:

第一步:确保Lexer正确定义关键字规则

首先得保证你的TransitionLexer里明确把and和or定义为独立的Token,而且要放在标识符(IDENTIFIER)规则的前面,避免被当成普通标识符匹配。比如:

lexer grammar TransitionLexer;

// 先定义关键字,优先级更高
AND: 'and';
OR: 'or';

// 其他语法规则
EQUAL: '=';
LPAREN: '(';
RPAREN: ')';
BOOLEAN: 'true' | 'false';
IDENTIFIER: [a-zA-Z_][a-zA-Z0-9_]*;
WS: [ \t\n\r]+ -> skip;

第二步:优化Parser规则(可选但推荐)

为了更方便在Listener里定位运算符,建议给Parser的表达式规则分支命名,这样Listener会自动生成对应的进入/退出方法。比如:

parser grammar TransitionParser;

options { tokenVocab = TransitionLexer; }

expr : expr AND expr #AndExpr
     | expr OR expr #OrExpr
     | LPAREN expr RPAREN #ParenExpr
     | IDENTIFIER EQUAL BOOLEAN #EqExpr;

第三步:通过Listener提取Token

接下来就可以编写自定义Listener,重写对应的方法来获取运算符Token了:

方法一:利用命名分支的Listener方法

如果上面给Parser规则分支命了名,ANTLR生成的Listener会包含enterAndExpr和enterOrExpr方法,直接在这些方法里获取Token即可:

public class OperatorExtractorListener extends TransitionParserBaseListener {

    @Override
    public void enterAndExpr(TransitionParser.AndExprContext ctx) {
        // 获取and对应的Token
        Token andToken = ctx.AND();
        System.out.println("提取到运算符: " + andToken.getText());
    }

    @Override
    public void enterOrExpr(TransitionParser.OrExprContext ctx) {
        // 获取or对应的Token
        Token orToken = ctx.OR();
        System.out.println("提取到运算符: " + orToken.getText());
    }
}

方法二:遍历上下文获取Token(适用于未命名分支)

如果没给Parser规则分支命名,也可以在enterExpr方法里遍历上下文的Token,筛选出AND和OR类型的Token:

public class OperatorExtractorListener extends TransitionParserBaseListener {

    @Override
    public void enterExpr(TransitionParser.ExprContext ctx) {
        // 提取所有AND类型的Token
        for (Token token : ctx.getTokens(TransitionLexer.AND)) {
            System.out.println("提取到运算符: " + token.getText());
        }
        // 提取所有OR类型的Token
        for (Token token : ctx.getTokens(TransitionLexer.OR)) {
            System.out.println("提取到运算符: " + token.getText());
        }
    }
}

最后:运行Listener的示例代码

你可以像下面这样使用这个Listener来解析输入并提取运算符:

public class Main {
    public static void main(String[] args) throws IOException {
        String input = "(states = failed) and (states1 = nominal) or (states2 = nominal)";
        TransitionLexer lexer = new TransitionLexer(CharStreams.fromString(input));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        TransitionParser parser = new TransitionParser(tokens);
        ParseTree tree = parser.expr();

        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(new OperatorExtractorListener(), tree);
    }
}

这样运行后,就能输出你想要的and和or啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:35:07