Parsec: потреблять весь вход
Одна общая проблема с Parsec заключается в том, что она имеет тенденцию игнорировать недопустимый ввод, если он встречается в "правильном" месте.
В качестве конкретного примера предположим, что мы имеем integer :: Parser Int
, и я пишу
expression = sepBy integer (char '+')
(Игнорировать проблемы с пробелами на мгновение.)
Это правильно разбирает что-то вроде "123 + 456 + 789". Однако, если я подаю его "123 + 456-789", он весело игнорирует незаконный символ "-" и конечную часть выражения; Я действительно хотел, чтобы сообщение об ошибке сообщало мне о недопустимом входе, а не просто молчаливо игнорировало эту часть.
Я понимаю, почему это происходит; я не уверен, как это исправить. Каков общий метод проектирования парсеров, которые потребляют все предоставленные входные данные и преуспевают, только если все это допустимое выражение?
Ответы
Ответ 1
Это на самом деле довольно просто - просто убедитесь, что он eof
:
parse (expression <* eof) "<interactive>" "123+456-789"
eof
соответствует концу ввода, даже если вход представляет собой только строку, а не файл.
Очевидно, что это имеет смысл только на верхнем уровне вашего синтаксического анализатора.