Что не так с этой грамматикой ANTLR? Условное утверждение вложенная скобка
Мне было поручено написать прототип DSL моей команды на Java, поэтому я решил попробовать его с помощью ANTLR. Однако у меня проблемы с правилами "выражения" и "условия".
DSL уже четко определен, поэтому я хотел бы сохранить как можно ближе к текущей спецификации.
grammar MyDSL;
// Obviously this is just a snippet of the whole language, but it should give a
// decent view of the issue.
entry
: condition EOF
;
condition
: LPAREN condition RPAREN
| atomic_condition
| NOT condition
| condition AND condition
| condition OR condition
;
atomic_condition
: expression compare_operator expression
| expression (IS NULL | IS NOT NULL)
| identifier
| BOOLEAN
;
compare_operator
: EQUALS
| NEQUALS
| GT | LT
| GTEQUALS | LTEQUALS
;
expression
: LPAREN expression RPAREN
| atomic_expression
| PREFIX expression
| expression (MULTIPLY | DIVIDE) expression
| expression (ADD | SUBTRACT) expression
| expression CONCATENATE expression
;
atomic_expression
: SUBSTR LPAREN expression COMMA expression (COMMA expression)? RPAREN
| identifier
| INTEGER
;
identifier
: WORD
;
// Function Names
SUBSTR: 'SUBSTR';
// Control Chars
LPAREN : '(';
RPAREN : ')';
COMMA : ',';
// Literals and Identifiers
fragment DIGIT : [0-9] ;
INTEGER: DIGIT+;
fragment LETTER : [A-Za-z@$#];
fragment CHARACTER : DIGIT | LETTER | '_';
WORD: LETTER CHARACTER*;
BOOLEAN: 'TRUE' | 'FALSE';
// Arithmetic Operators
MULTIPLY : '*';
DIVIDE : '/';
ADD : '+';
SUBTRACT : '-';
PREFIX: ADD| SUBTRACT ;
// String Operators
CONCATENATE : '||';
// Comparison Operators
EQUALS : '==';
NEQUALS : '<>';
GTEQUALS : '>=';
LTEQUALS : '<=';
GT : '>';
LT : '<';
// Logical Operators
NOT : 'NOT';
AND : 'AND';
OR : 'OR';
// Keywords
IS : 'IS';
NULL: 'NULL';
// Whitespace
BLANK: [ \t\n\r]+ -> channel(HIDDEN) ;
Фраза, с которой я тестирую
(FOO == 115 AND (SUBSTR(BAR,2,1) == 1 OR SUBSTR(BAR,4,1) == 1))
Однако он разбивается на вложенные скобки, сопоставляя первое (с первым) вместо внешнего (см. Ниже). В ANTLR3 я решил эту проблему с помощью семантических предикатов, но кажется, что ANTLR4 должен был устранить необходимость в них.
Я бы очень хотел сохранить condition
и expression
правила раздельные, если это вообще возможно. Я смог заставить его работать, когда объединены в одном expression
правила (на основе примеров здесь и в других местах), но в текущей спецификации DSL они различны, и я пытаюсь уменьшить возможные различия в поведении.
Может кто-нибудь указать, как я могу заставить все это работать, сохраняя отдельное правило для conditions' and
expressions`? Большое спасибо!
1 ответ
Грамматика мне кажется хорошей.
В лексере есть одна проблема: WORD
токен определяется перед различными ключевыми словами / операторами, в результате чего он получает приоритет над ними. Поместите свой WORD
править в самом конце ваших правил лексера (или, по крайней мере, после последних ключевых слов, которые WORD
также может соответствовать).