У меня возникла проблема в том, как разобрать дату в моей грамматике.ANTLR: проанализируйте дату в строке цитаты
Дело в том, что оно разделяет его определение на String, но в соответствии с документацией Antlr 4 оно должно следовать за приоритетом, глядя на порядок объявления.
Вот моя грамматика:
grammar formula;
/* entry point */
parse: expr EOF;
expr
: value # argumentArithmeticExpr
| l=expr operator=('*'|'/'|'%') r=expr # multdivArithmeticExpr // TODO: test the % operator
| l=expr operator=('+'|'-') r=expr # addsubtArithmeticExpr
| '-' expr # minusArithmeticExpr
| FUNCTION_NAME '(' (expr (',' expr)*) ? ')'# functionExpr
| '(' expr ')' # parensArithmeticExpr
;
value
: number
| variable
| date
| string
| bool;
/* Atomes */
bool
: BOOL
;
variable
: '[' (~(']') | ' ')* ']'
;
date
: DQUOTE date_format DQUOTE
| QUOTE date_format QUOTE
;
date_format
: year=INT '-' month=INT '-' day=INT (hour=INT ':' minutes=INT ':' seconds=INT)?
;
string
: STRING_LITERAL
;
number
: ('+'|'-')? NUMERIC_LITERAL
;
/* lexemes de base */
QUOTE : '\'';
DQUOTE : '"';
MINUS : '-';
COLON : ':';
DOT : '.';
PIPE : '|';
BOOL : T R U E | F A L S E;
FUNCTION_NAME: IDENTIFIER ;
IDENTIFIER
: [a-zA-Z_] [a-zA-Z_0-9]* // TODO: do we more chars in this set?
;
NUMERIC_LITERAL
: DIGIT+ ('.' DIGIT*)? (E [-+]? DIGIT+)? // ex: 0.05e3
| '.' DIGIT+ (E [-+]? DIGIT+)? // ex: .05e3
;
INT: DIGIT+;
STRING_LITERAL
: '\'' (~'\'' | '\'\'')* '\''
| '"' (~'"' | '""')* '"'
;
WS: [ \t\n]+ -> skip;
UNEXPECTED_CHAR: . ;
fragment DIGIT: [0-9];
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');
Важной частью здесь является следующее:
value
: number
| variable
| date
| string
| bool;
date
: DQUOTE date_format DQUOTE
| QUOTE date_format QUOTE
;
date_format
: year=INT '-' month=INT '-' day=INT (hour=INT ':' minutes=INT ':' seconds=INT)?
;
Моя грамматика ожидает, что эти вещи:
"a quoted string"
-> даетstring
"2015-03 TOTOTo"
-> даетstring
, потому что формат даты не совпадает."2015-03-15"
-> даетdate
, потому что он соответствуетDQUOTE INT '-' INT '-' INT DQUOTE
И я, чтобы убедиться, что анализатор пытается сопоставить дату перед тем пытается соответствовать строке: value: ...| date | string| ...
(пробовал?).
Но когда я использую утилиту grun
(и мои юнит-тесты ...), я вижу, что она классифицирует дату как строку, например, если она никогда не беспокоилась о проверке формата даты.
Можете ли вы сказать мне, почему это так? Я подозреваю, что есть улов с порядком, в котором я объявляю свои правила грамматики, но я попробовал некоторые перестановки и ничего не получил.
Я реализовал другое решение, которое должно анализировать дату в правиле * string *. Но я приму решение в качестве альтернативы. – Gui13