Как вы делаете что-то подобное с ANTLR?
Пример ввода:
title: hello world
Грамматика:
header : IDENT ':' REST_OF_LINE ;
IDENT : 'a'..'z'+ ;
REST_OF_LINE : ~'\n'* '\n' ;
Не получается, с line 1:0 mismatched input 'title: hello world\n' expecting IDENT
(Я знаю, что ANTLR является излишним для разбора MIME-подобных заголовков, но это только начало более сложного файла.)
Ответ 1 · рейтинг 3 · Bart Kiers
Это не удается, строка 1:0 не соответствует вводу 'title: hello world\n', ожидая IDENT
Вы должны понимать, что лексер работает независимо от парсера. Независимо от того, что синтаксический анализатор "хочет" сопоставить в определенное время, лексер просто создает токены, следуя некоторым строгим правилам:
- попытаться сопоставить токены сверху вниз в правилах лексера (правила, определенные первыми, пробуются первыми);
- сопоставьте как можно больше текста. Если 2 правила соответствуют одному и тому же объему текста, то правило, определенное первым, будет сопоставлено.
Из-за правила 2 ваш REST_OF_LINE всегда будет "выигрывать" из правила IDENT. Единственный раз, когда токен IDENT будет создан, это когда в конце больше не будет \n. Вот что не так с вашими грамматиками: в сообщениях об ошибках говорится, что он ожидает токен IDENT, который не найден (но создается токен REST_OF_LINE).
Вы не можете просто определить токены (правила лексера), которые хотите применить к заголовку файла. Эти токены также будут применяться к остальной части более сложного файла. Возможно, вам следует предварительно обработать заголовок отдельно от остальной части файла?
Ответ 2 · рейтинг -1 · Raghu
Разбор antlr обычно выполняется в 2 этапа. 1. построить свой аст 2. определить свой грамматик
псевдокод (прошло несколько лет с тех пор, как я играл с antlr) - AST:
WORD : 'a'..'z'+ ;
SEPARATOR : ':';
SPACE : ' ';
псевдокод - парсер дерева:
header: WORD SEPARATOR WORD (SPACE WORD)+
Надеюсь, это поможет....