ANTLR4: Как разобрать строку многоугольника WKT?
Я использую ANLTR4 в Java, и я мог бы разобрать строку многоугольника WKT, как это
polygon((20 30, 30 40, 50 60, 20 30))
с этим лексером:
POLYGON: ('polygon'|'POLYGON')'(('[0-9:,-.eTZ" ]+'))';
поскольку числа внутри многоугольника (()) могут быть datetime или float, то он содержит несколько символов.
Тем не менее, я не мог разобрать многоугольник с внутренним многоугольником, как это
polygon((20 30, 30 40, 50 60, 20 30), (20 30, 30 40, 50 60, 20 30), (20 30, 30 40, 50 60, 20 30))
когда я пытался добавить () в Lexer, например:
POLYGON: ('polygon'|'POLYGON')'(('[0-9:,-.eTZ" \(\)]+'))';
Java выдает исключение, не может найти ")" с.
Что я могу сделать, чтобы ANTLR4 мог анализировать полигон ((), (), (), ...)?
2 ответа
Лексер должен определять только основные строительные блоки языка. Полигон, список и т. Д. Должны быть определены как правила синтаксического анализа.
Примерно так должно начаться:
grammar WKT;
parse
: polygon EOF
;
polygon
: POLYGON '(' ( points ( ',' points )* )? ')'
;
points
: '(' ( value value ( ',' value value )* )? ')'
;
value
: INT
| FLOAT
| DATE_TIME
;
POLYGON
: [pP] [oO] [lL] [yY] [gG] [oO] [nN]
;
INT
: DIGITS
;
FLOAT
: DIGITS '.' DIGITS
;
DATE_TIME
: D D D D '-' D D '-' D D 'T' D D ':' D D ':' D D [+-] D D ':' D D
| D D D D '-' D D '-' D D 'T' D D ':' D D ':' D D 'Z'
| D D D D D D D D 'T' D D D D D D 'Z'
;
SPACES
: [ \t\r\n]+ -> skip
;
fragment DIGITS
: D+
;
fragment D
: [0-9]
;
Следующий вход: POLYGON ((35 10, 45 45, 15 40, 10 20, 35 10), (20 30, 35 35, 30 20, 20 30))
будет проанализирован следующим образом:
Я думаю, что вы не должны делать это только с лексером. Вы должны использовать свой лексер, чтобы разделить на символы; например 'polygon'
, '('
, ')'
, ','
, <number>
, <date>
и так далее. Затем реализуйте грамматику, чтобы иметь дело с синтаксисом большого масштаба; например
<polygon> ::= 'polygon' '(' <list> ')'
<list> ::= '(' ')' |
'(' <element> ( ',' <element> ) * ')'
<element> ::= <number> | <date>
(Я использую метасинтаксис вроде EBNF ....)
Проблемы с использованием только основанного на регулярных выражениях лексера без грамматики:
- регулярное выражение трудно читать / трудно проверить
- вы не получите дерево разбора
- вы не получаете никаких значимых ошибок парсера
- чем сложнее регулярное выражение, тем больше вероятность возникновения проблем с производительностью; например, https://www.regular-expressions.info/catastrophic.html