我正在try 使用ANTLR执行输入数据(Map)的动态表达式,并使用@Bart Kier的答案,我可以做到这一点.

我try 在语法中添加INSTARTSWITHENDSWITH 条件,并try 从Java端为其添加逻辑.对于IN 函数,我try 使用一个特殊字符来拆分一组字符串,最好是 , (comma).但是,当我将它们添加到我的表达式中时,会得到如下错误

line 1:64 token recognition error at: ','

让我知道如何在表达式中允许特殊字符.

The grammer file I used

grammar SimpleBoolean;

parse
 : expression EOF
 ;

expression
 : LPAREN expression RPAREN                       #parenExpression
 | NOT expression                                 #notExpression
 | left=expression op=comparator right=expression #comparatorExpression
 | left=expression op=binary right=expression     #binaryExpression
 | bool                                           #boolExpression
 | IDENTIFIER                                     #identifierExpression
 | DECIMAL                                        #decimalExpression
 ;

comparator
 : GT | GE | LT | LE | EQ | NE | IN | NOTIN | STARTSWITH | ENDSWITH | NULL | NOTNULL
 ;

binary
 : AND | OR
 ;

bool
 : TRUE | FALSE
 ;

AND        : 'AND' ;
OR         : 'OR' ;
NOT        : 'NOT';
TRUE       : 'TRUE' ;
FALSE      : 'FALSE' ;
GT         : '>' ;
GE         : '>=' ;
LT         : '<' ;
LE         : '<=' ;
EQ         : '=' ;
NE         : '!=' ;
IN         : 'IN' ;
NOTIN      : 'NOTIN' ;
STARTSWITH : 'STARTSWITH' ;
ENDSWITH   : 'ENDSWITH' ;
NULL       : 'NULL' ;
NOTNULL    : 'NOTNULL' ;
LPAREN     : '(' ;
RPAREN     : ')' ;
DECIMAL    : '-'? [0-9]+ ( '.' [0-9]+ )? ;
IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]* ;
WS         : [ \r\t\u000C\n]+ -> skip;

修改后的EvalVisitor.class

添加了以下行

if (ctx.op.EQ() != null) {
          return this.visit(ctx.left).equals(this.visit(ctx.right));
        }
        else if (ctx.op.IN() != null) {
            String checkVal[] = this.visit(ctx.right).toString().split(",");
            boolean valuePresent = false;
            
            for(String value : checkVal) {
                if(value.equals(this.visit(ctx.left).toString()))
                    valuePresent = true;
            }
            return valuePresent;
        }

我通过了Expression分,

ID = ID AND NOT ( comments = comments AND system IN system,admin,developer )

推荐答案

expression规则的开头添加expression ( ',' expression )+:

expression
 : expression ( ',' expression )+ #multipleExpression
 | ...
 ;

编辑

添加上述规则后:

grammar SimpleBoolean;

parse
 : expression EOF
 ;

expression
 : expression ( ',' expression )+                 #multipleExpression
 | LPAREN expression RPAREN                       #parenExpression
 | NOT expression                                 #notExpression
 | left=expression op=comparator right=expression #comparatorExpression
 | left=expression op=binary right=expression     #binaryExpression
 | bool                                           #boolExpression
 | IDENTIFIER                                     #identifierExpression
 | DECIMAL                                        #decimalExpression
 ;

comparator
 : GT | GE | LT | LE | EQ | NE | IN | NOTIN | STARTSWITH | ENDSWITH | NULL | NOTNULL
 ;

binary
 : AND | OR
 ;

bool
 : TRUE | FALSE
 ;

AND        : 'AND' ;
OR         : 'OR' ;
NOT        : 'NOT';
TRUE       : 'TRUE' ;
FALSE      : 'FALSE' ;
GT         : '>' ;
GE         : '>=' ;
LT         : '<' ;
LE         : '<=' ;
EQ         : '=' ;
NE         : '!=' ;
IN         : 'IN' ;
NOTIN      : 'NOTIN' ;
STARTSWITH : 'STARTSWITH' ;
ENDSWITH   : 'ENDSWITH' ;
NULL       : 'NULL' ;
NOTNULL    : 'NOTNULL' ;
LPAREN     : '(' ;
RPAREN     : ')' ;
DECIMAL    : '-'? [0-9]+ ( '.' [0-9]+ )? ;
IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]* ;
WS         : [ \r\t\u000C\n]+ -> skip;

您的示例输入9355560 = 9355560 AND NOT ( comments = comments AND system IN system,admin,developer )将按如下方式进行解析(没有错误!):

enter image description here

Java相关问答推荐

Selenium Java:无法访问IFRAME内部的元素

Listview—在Android Java中正确链接项目时出错

Javascript在边界中心调整ImageView大小

需要一个找不到的jakarta.sistence.EntityManager类型的Bean

只需最少的代码更改即可将版本号标记添加到日志(log)

RichFaces 3.x-Spring Boot-迁移web.xml

当涉及到泛型时,类型推理在Java中是如何工作的?

使用Mockito进行的Junit测试失败

更新GWT 2.5.1到2.11.0和sencha GXT 3.1.1到4.1时出现错误

无法初始化JPA实体管理器工厂:无法确定为Java类型<;类>;推荐的JdbcType

Java编译器抛出可能未正确初始化的错误?

Spring和可编辑";where";@Query

如何为JavaFX Spring Boot应用程序制作Windows/MacOS/Linux安装程序

解析方法";javax/imageio/metadata/IIOMetadata.getAsTree(Ljava/lang/String;)Lorg/w3c/dom/Node时加载约束冲突

二进制数据的未知编码/序列化

如何使用MapStrCut转换双向链接

在Java中将对象&转换为&q;HashMap(&Q)

using case default on switch语句返回;预览特征切换中的模式匹配仅在源级别20及以上的情况下可用;

在不带instanceof或switch的java中记录模式

单例模式中热切初始化和惰性初始化的区别