Робин писал:
Я думал, что написание правил для встроенного текста разметки будет легко
Я долженпризнайте, что я не знаком с этим языком разметки, но, похоже, он напоминает разметку BB-кода или Wiki, которые нелегко переводить в грамматику (ANTLR)!Эти языки не позволяют легко быть токенизированными, поскольку это зависит от того, где эти токены встречаются.Пробелы иногда имеют особое значение (со списками определений).Так что нет, это совсем не легко, ИМО.Поэтому, если вы хотите познакомиться с ANTLR (или генератором синтаксического анализатора в целом), я весьма рекомендую выбрать что-то еще для анализа.
Робин написал:
Может ли кто-нибудь указать на мои ошибки и, возможно, дать мне подсказку о том, как сопоставить обычный текст?
Вы должны сначала понять, чтоANTLR создает лексер (токенизатор) и парсер.Правила Lexer начинаются с заглавной буквы, а правила синтаксического анализатора начинаются со строчной буквы.Парсер может работать только с токенами (объектами, созданными по правилам лексера).Чтобы упорядочить ситуацию, вы не должны не использовать токены-литералы в правилах синтаксического анализатора (см. Правило q
в грамматике ниже).Кроме того, метасимвол ~
(отрицание) имеет различное значение в зависимости от того, где он используется (в правиле синтаксического анализатора или лексера).
Примите следующую грамматику:
p : T;
q : ~'z';
T : ~'x';
U : 'y';
ANTLR сначала «переместит» литерал 'z'
в правило лексера следующим образом:
p : T;
q : ~RANDOM_NAME;
T : ~'x';
U : 'y';
RANDOM_NAME : 'z';
(имя RANDOM_NAME
не используется, но это не имеет значения).Теперь правило синтаксического анализатора q
не не соответствует любому символу, кроме 'z'
!Отрицание внутри правила синтаксического анализатора отменяет токен (или правило лексера).Таким образом, ~RANDOM_NAME
будет соответствовать правилу лексера T
или правилу лексера U
.
Внутри правил лексера ~
отменяет (один!) Символы.Таким образом, правило лексера T
будет соответствовать любому символу в диапазоне \u0000
.. \uFFFF
, кроме 'x'
.Обратите внимание, что следующее: ~'ab'
недопустимо в правиле лексера: вы можете отвергать только одиночные наборы символов.
Итак, все эти ~'???'
внутри правил вашего синтаксического анализатора неверны (неправильно, как в: они неведет себя так, как вы ожидаете).
Робин писал:
Есть ли способ установить приоритет в правилах грамматики?Возможно, это может быть лидерство.
Да, порядок сверху вниз в правилах как лексеров, так и парсеров (где верх имеет наивысший приоритет).Допустим, parse
является точкой входа в вашу грамматику:
parse
: p
| q
;
, затем сначала будет пробоваться p
, а в случае неудачи q
будет пытаться найти соответствие.
Что касается правил лексера, то правила, которые, например, являются ключевыми словами, сопоставляются перед правилом, которое могло бы соответствовать указанным ключевым словам:
// first keywords:
WHILE : 'while';
IF : 'if'
ELSE : 'else';
// and only then, the identifier rule:
ID : ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*;