Я пытаюсь создать Lexer / Parser с ANTLR, который может анализировать простой текст с «тегами», разбросанными между ними. Эти теги обозначаются открывающими ({) и закрывающими (}) скобками, и они представляют Java объекты, которые могут преобразовываться в строку, которая затем заменяется в исходном вводе для создания динамического c шаблона сортов.
Вот пример: {player: name} говорит привет! {Player: name} должен быть заменен на имя игрока и привести к выводу, т.е. Марк говорит привет! для игрока по имени Марк.
Теперь я могу отлично распознавать и анализировать теги, с чем у меня проблемы, это текст, который идет после. Вот грамматика, которую я использую:
grammar : content+
content : tag
| literal
;
tag : player_tag
| <...>
| <other kinds of tags, not important for this example>
| <...>
;
player_tag : BRACKET_OPEN player_identifier SEMICOLON player_string_parameter BRACKET_CLOSE ;
player_string_parameter : NAME
| <...>
;
player_identifier : PLAYER ;
literal : NUMBER
| STRING
;
BRACKET_OPEN : '{';
BRACKET_CLOSE : '}';
PLAYER : 'player'
NAME : 'name'
NUMBER : <...>
STRING : (.+)? /* <- THIS IS THE PROBLEMATIC PART !*/
Теперь это определение STRING Lexer должно соответствовать всему, что не является пустой строкой, но проблема в том, что оно слишком жадное, а затем также использует токены скобки {}, необходимые правило тега. Я попытался установить для него значение ~ [{}] +, которое должно соответствовать чему-либо, что не включает скобки {}, но содержит винты с разбором тега, что я тоже не понимаю. Я мог бы установить что-то вроде [a-zA-Z0-9! "§ $% & / () = et c ...] +, но я действительно не хочу ограничивать его для анализа только символов, доступных на клавиатура briti sh (немецкие умляты или французские акценты и все другие специальные символы, которые должны присутствовать в других языках!) Единственное, что несколько работает, хотя мне это очень не нравится, это заставляет строки иметь префикс и суффикс, например, так:
STRING : '\'' ~[}{]+ '\'' ;
Это заставляет меня изменить форму с "{player: name} говорит привет!" На "{player: name} 'говорит привет!" ", И я действительно отчаянно хочу избежать таких ограничений, потому что Затем я должен был бы учитывать буквенные символы в самой строке, и работать с ним просто некрасиво.
Имеются два следующих решения: - Есть ли способ сопоставить любое количество символов который не был сопоставлен лексером как токен STRING и передал его парсеру? Таким образом, я мог бы сопоставить все теги и сказать, что остальная часть ввода представляет собой просто текст, вернуть его мне как STRING токен или еще что-нибудь ... - Поддерживает ли ANTLR выражения регулярных выражений lookahead и lookbehind, с которыми я могу сопоставить любое количество символов перед первым '{', после последнего '}' и что-нибудь между '}' и '{'? Я пробовал
STRING : (?<=})(.+)?(?={) ;
, но я не могу понять правильный синтаксис, потому что он вообще не компилируется, что приводит меня к мысли, что ANTLR не поддерживает синтаксис lookahead и lookbehind, но я мог не найти окончательного ответа на этот вопрос rnet.
Любой совет, что делать?