Вопрос или проблема
ANTLR4.13 – несоответствующий ввод ‘|’ в ожидании {‘)’, ‘|’}
В данный момент я начинающий пользователь ANTLR. Я лишь отчасти понимаю из предыдущих постов различия между лексическим анализом и синтаксическим анализом. Но иногда я все еще путаюсь, следует ли определять правило x перед или после правила y. В любом случае, я попал вsort of pickle. Я тестировал некоторую грамматику ANTLR и столкнулся с этой ошибкой:
несоответствующий ввод '|' ожидая {')', '|'}
После прочтения этого я был очень озадачен и провел много времени, пытаясь это исправить. Я ожидал, что парсер воспримет ‘|’ как Vline, поскольку я определил его как лексическое правило ранее, но, похоже, это не так.
Вот большая часть грамматики ANTLR, которая относится к этой проблеме:
Vline: '|';
tcf_annotated : 'tcf('name','formula_role','tcf_formula annotations').';
tcf_formula : tcf_logic_formula | tff_atom_typing;
tcf_logic_formula : tcf_quantified_formula | cnf_formula;
tcf_quantified_formula : '!' '['tff_variable_list']' ':' tcf_logic_formula;
cnf_formula : cnf_disjunction | '(' cnf_formula ')';
cnf_disjunction : cnf_literal | cnf_disjunction Vline cnf_literal;
cnf_literal : fof_atomic_formula | '~' fof_atomic_formula | '~' '('fof_atomic_formula')' | fof_infix_unary;
Вот строки из файла, где возникает ошибка:
43 tcf(equality,axiom,
44 ! [X: $i,Y: $i,Z: $i] :
45 (
46 ( f(Y) = g(X,f(Y),Z) )
47 | ( f(f(f(b))) != a )
48 | ( X = f(Y) )
49 )
50 ).
Грамматика правильно анализирует name, и formula role, а также первое tcf_quantified_formula.
Грамматика создает проблемы при анализе cnf_formula, который начинается на строке 45, что меня сбивает с толку.
Я также использую расширение ANTLR debugger от VSCode, и дерево разбора выдает мне эту ошибку:
Прошу прощения, если я что-то неправильно понимаю, потому что я довольно нов в грамматике ANTLR. Можете ли вы, пожалуйста, пролить свет или дать совет, чтобы помочь мне? Спасибо.
Ответ или решение
Ошибки, подобные "mismatched input ‘|’ expecting {‘)’, ‘|’}", часто возникают из-за неправильной структуры грамматики или из-за последовательности правил, которые не соответствуют ожидаемому вводу. В вашем случае проблема заключается в использовании символа ‘|’ в контексте, где ANTLR ожидает другой символ.
Рассмотрим ваш случай более внимательно. Исходя из вашего описания и приведенного кода:
-
Проблема с правилами грамматики: Вы определяете
cnf_disjunction
с использованием оператора ‘|’ для обозначения альтернатив, но ANTLR не может правильно интерпретировать ‘|’ в контексте вашего ввода. Согласно вашему правилу,cnf_disjunction
определяется какcnf_literal | cnf_disjunction Vline cnf_literal;
, что предполагает использованиеVline
как разделитель для вашихcnf_literal
. Это верно, но стоит убедиться, что вы правильно обрабатываете этот ввод и его структуру при разборе. -
Контекст: Ошибка указывает, что парсер ожидает
')'
или еще один|
, но находит символ ‘|’. Это может происходить из-за того, что вы используетеVline
в контексте, где он не ожидается. Постарайтесь уточнить, должен ли вашcnf_formula
содержатьcnf_disjunction
, и проверьте правильность категории, где происходит разбор. -
Тестирование правила: Попробуйте протестировать ваше правило отдельно, с более простыми примерами, чтобы убедиться в правильности его работы. Например, при тестировании можно убрать дополнительные сложности, чтобы оставить только
cnf_disjunction
и минимально необходимый ввод. - Корректировка структуры: Вам следует убедиться, что у вас есть корректные грамматические конструкции вокруг всех правил, особенно в тех местах, где используются операторы альтернативы (‘|’). Это может включать правильное использование круглых скобок вокруг выражений, чтобы явно указать порядок разбора.
Пример исправленного правила для cnf_formula
может выглядеть следующим образом:
cnf_formula: cnf_disjunction | '(' cnf_formula ')';
cnf_disjunction: cnf_literal (Vline cnf_literal)*;
В этом исправлении мы обеспечиваем, чтобы cnf_disjunction
принимал одно или несколько выражений (разделенных символом Vline
), что может помочь исправить текущую ошибку синтаксиса.
- Тестирование: После внесения изменений в правила, убедитесь, что вы тщательно тестируете ваш ввод, чтобы удостовериться, что новая структура грамматики обрабатывает все ожидаемые форматы.
Надеюсь, эти рекомендации помогут вам устранить ошибку и лучше понять структуру ANTLR. Если проблема не исчезнет, советую внимательно рассмотреть другие части вашего кода на предмет возможных конфликтов или синтаксических ошибок.