ANTLR принимает специальные символы, такие как . (точка) и (запятая) в идентификаторе или выражении

Я пытаюсь выполнить динамические выражения для входных данных (Map) с помощью ANTLR и ответа @Bart Kiers из поста stackoverflow Мне удалось это сделать.

Я пытался добавить IN, STARTSWITH, ENDSWITH условие в грамматоре и пытался добавить для него логику со стороны Java. В случае функции IN я пытаюсь разделить набор строк, желательно используя специальный символ , (comma). Но когда я добавляю их в свое выражение, я получаю следующую ошибку:

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

Подскажите, как разрешить использование специальных символов в выражении.

Файл Grammer, который я использовал

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;
        }

Выражение, которое я передал,

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

Попробуйте поставить '\' (обратную косую черту) перед специальным символом.

Berc07 14.09.2023 18:16

К сожалению, я не могу передать обратную косую черту во входных данных, поскольку это может повлиять на требование :(

User1512 14.09.2023 18:37

В каком месте вашей грамматики вы пытаетесь поставить запятые?

sepp2k 14.09.2023 21:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
3
72
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Добавьте 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 ) анализируются следующим образом (без ошибок!):

спасибо за Ваш ответ. Я все еще получаю исключение «ошибка (122): Filter.g4:7:0: выражение правила: необходимо пометить все альтернативы или ничего». Кстати, я хотел бы передать и другие специальные символы, поскольку пользовательский ввод и любые значения могут содержать специальные символы. Смогу ли я предоставить грамматику для принятия специальных символов в любом месте данного выражения?

User1512 15.09.2023 21:30

Тогда вы не сделали так, как я предложил :)

Bart Kiers 16.09.2023 16:11

Я добавил тот же оператор, о котором вы упомянули, но каким-то образом он выдал исключение. Теперь все работает нормально :)

User1512 20.09.2023 14:42

Вы забыли добавить #multipleExpression в конце альтернативы (что я и предложил вам сделать). Если теперь это работает, возможно, вы только что добавили его. Ошибка не могла исчезнуть чудесным образом :)

Bart Kiers 20.09.2023 19:06

Другие вопросы по теме