Разбор одного или нескольких выражений с полезными ошибками
Я использую Grako (PEG-генератор парсера для Python) для анализа простого декларативного языка, где документ может содержать один или несколько протоколов.
Первоначально у меня было корневое правило для документа, написанное как:
document = {protocol}+ ;
Это соответствующим образом возвращает список протоколов, но дает полезные ошибки, только если синтаксическая ошибка есть в первом протоколе. В противном случае он молча отбрасывает неверный протокол и все, что после него.
Я также попробовал несколько вариантов:
document = protocol document | $ ;
Но это не приводит к списку, если есть только один протокол, и не дает полезных сообщений об ошибках, говоря только no available options: (...) document
если какой-либо из протоколов содержит ошибку.
Как мне написать правило, которое выполняет оба следующих действия:
- Всегда возвращает список, даже если есть только один протокол
- Отображает полезные сообщения об ошибках о неудачном сопоставлении, вместо того, чтобы просто сказать, что это недействительный документ или молча отбросить поврежденный протокол
1 ответ
Это решение:
document = {protocol ~ }+ $ ;
Если вы не добавите $
для синтаксического анализатора, чтобы увидеть конец файла, анализ будет успешным с одним или несколькими протоколами, даже если есть больше для анализа.
Добавление вырезанного выражения (~
) заставляет синтаксический анализатор выполнить то, что было проанализировано в ближайшем параметре / параметре синтаксического анализа (закрытие - это опция X = a X|();
). Дополнительные выражения вырезки в пределах того, что анализируется protocol
сделает сообщения об ошибках ближе к ожидаемым точкам отказа на входе.