java - ANTLR 中的递归处理规则

标签 java antlr

好的,这是我两天内的第三个 ANTLR 问题:

我的语法旨在解析 boolean 语句,如下所示:

AGE > 21 AND AGE < 35

由于这是一个相对简单的语法,因此我嵌入了代码而不是使用 AST。该规则如下所示:

: a=singleEvaluation { $evalResult = $a.evalResult;} 
(('AND') b=singleEvaluation {$evalResult = $evalResult && $b.evalResult;})+
{
// code
}
;

现在我需要使用括号实现运算顺序,以解析如下内容:

AGE >= 21 AND (DEPARTMENT=1000 OR DEPARTMENT=1001)

或者更糟:

AGE >= 21 AND (DEPARTMENT=1000 OR (EMPID=1000 OR EMPID=1001))

任何人都可以建议一种方法来实现所需的递归吗?我不想在这么晚的阶段切换到 AST,而且我在这方面仍然是一个相对菜鸟。

杰森

最佳答案

由于您的某些规则计算结果为 boolean 值,而其他规则计算结果为整数(或仅比较整数),因此您最好让您的规则返回通用对象,并进行相应的转换。

这是一个快速演示(包括在括号表达式的情况下进行递归调用):

grammar T;

@parser::members {
  private java.util.Map<String, Integer> memory = new java.util.HashMap<String, Integer>();
}

parse
@init{
  // initialize some test values
  memory.put("AGE", 42);
  memory.put("DEPARTMENT", 999);
  memory.put("EMPID", 1001);
}
 : expression EOF {System.out.println($text + " -> " + $expression.value);}
 ;

expression returns [Object value]
 : logical {$value = $logical.value;}
 ;

logical returns [Object value]
 : e1=equality {$value = $e1.value;} ( 'AND' e2=equality {$value = (Boolean)$value && (Boolean)$e2.value;}
                                     | 'OR' e2=equality  {$value = (Boolean)$value || (Boolean)$e2.value;}
                                     )*
 ;

equality  returns [Object value]
 : r1=relational {$value = $r1.value;} ( '=' r2=relational  {$value = $value.equals($r2.value);}
                                       | '!=' r2=relational {$value = !$value.equals($r2.value);}
                                       )*
 ;

relational returns [Object value]
 : a1=atom {$value = $a1.value;} ( '>=' a2=atom {$value = (Integer)$a1.value >= (Integer)$a2.value;}
                                 | '>'  a2=atom {$value = (Integer)$a1.value >  (Integer)$a2.value;}
                                 | '<=' a2=atom {$value = (Integer)$a1.value <= (Integer)$a2.value;}
                                 | '<'  a2=atom {$value = (Integer)$a1.value <  (Integer)$a2.value;}
                                 )?
 ;

atom returns [Object value]
 : INTEGER            {$value = Integer.valueOf($INTEGER.text);}
 | ID                 {$value = memory.get($ID.text);}
 | '(' expression ')' {$value = $expression.value;}
 ;

INTEGER : '0'..'9'+;
ID      : ('a'..'z' | 'A'..'Z')+;
SPACE   : ' ' {$channel=HIDDEN;};

解析输入“AGE >= 21 AND (DEPARTMENT=1000 OR (EMPID=1000 OR EMPID=1001))” 将产生以下输出:

AGE >= 21 AND (DEPARTMENT=1000 OR (EMPID=1000 OR EMPID=1001)) -> true

关于java - ANTLR 中的递归处理规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13399344/

相关文章:

java - 在 Jenkins 插件中设置 envvars

java - 如何用LocalDate查询LocalDateTime?

java - HQL:动态添加JOINS和WHERE部分(ANTLR,正则表达式或String)

regex - Antlr 解析器是贪婪的吗?

java - 未使用的解析器规则导致错误,具体取决于定义 - 为什么?

c - antlr C语法创建AST

java - Spring 锁定域对象的最佳实践?

java - react 器: Flux<object> .subscribe() 与 .toStream()

java - java中的Python套接字

java - ANTLR 努力解析整数与引用字符串