java - 比较antlr生成的 token

标签 java parsing antlr dsl antlr4

我的语法中有以下内容(为了简单起见,这里 'name''value' 只是静态的,但实际上并非如此):

test4 : 'name' CMPOP 'value';

CMPOP       :   EQUALS | NOTEQUALS;
EQUALS      :   '=';
NOTEQUALS   :   '!=';

现在,我想要做的是以不同的方式处理不同的 CMPPOP(可能通过交换机)。当我在 FilterListener 实现中评估表达式时,有没有办法获取 CMPPOP 底层 token 的 int/enum 版本(= 或 !=)?我知道我可以使用 getText() 获取字符串,但比较各处的字符串可能会很慢。例如如果我有 name=value 我可以看到 = TerminalNodeImpl 并且它有一个符号。唯一看起来相似的是 type 属性,但这似乎给了我 CMPPOP。

public void exitTest4(@NotNull testParser.Test4Context ctx) {
    System.out.println(ctx.CMPOP().getSymbol().toString());
    int type = ctx.CMPOP().getSymbol().getType();
    System.out.println(type + "," + testParser.tokenNames[type]);
}

给我:

[@1,4:4='=',<6>,1:4]
6,CMPOP

我想做的是:

switch ( ctx.CMPOP().something() ) {
  EQUALS : //evaluate with = ; break
  NOTEQUALS : //evaluate with != ; break
}

或者我的处理方式是错误的?我是否应该将其移至解析器规则而不是词法分析器规则,例如: 'name' (EQUALS | NOTEQUALS) 'value'

我正在使用antlr4。

最佳答案

您有两个主要选择。您可以选择最适合您的方法。

选项 1:将 CMPOP 更改为解析器规则而不是词法分析器规则

cmpOp
  : EQUALS
  | NOTEQUALS
  ;

优点:

  • 易于执行更改
  • 如果需要更改,可以轻松维护 cmpOp 规则
  • EQUALSNOTEQUALS 作为比较运算符进行更好的概念分组

选项 2:删除 CMPOP 规则,并将该集内联到解析器规则中

将当前引用 CMPOP 的所有代码替换为 (EQUALS | NOTEQUALS)

优点:

  • 每个比较运算符减少 1 个解析树节点(内存开销略有减少,如果这对您的情况很重要)

关于java - 比较antlr生成的 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24390502/

相关文章:

java - Message Driven bean 可以实现除 MessageListener 之外的其他接口(interface)吗?

安卓 : How to Parse HTML tags and retrieve information from an HTML page

c# - 在 C# 构造函数中处理损坏的输入数据的最合适方法是什么?

Antlr4 从错误中恢复并继续解析直到 EOF

antlr - 使用 ANTLR4 生成的访问者生成 AST

java - 向 JButton 添加关闭操作

java - 使用mvn assembly :single to build a jar-with-dependencies?时如何包含本地jar

java - 递归的性能

c - 从 C 中的文本文件中读取 8 位二进制数

ANTLR 4 树注入(inject)/重写运算符