Parsec - «много» и сообщения об ошибках - PullRequest
3 голосов
/ 17 ноября 2010

Когда я пытаюсь проанализировать many p, я не получаю сообщение «Ожидается р»:

> parse (many (char '.') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting end of input

Сравнить с

> parse (sepBy (char '.') (char ',') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting "." or end of input

который сообщает "." как я и ожидал. many1 p <|> return [] тоже работает.

Все эти функции принимают пустой ввод , так почему же many не сообщает, что ожидает? Это ошибка или особенность?

Ответы [ 4 ]

7 голосов
/ 17 ноября 2010

Вы получите лучшие сообщения об ошибках с manyTill:

> parse (manyTill (char '.') eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting end of input or "."

Это просто из-за того, как вы цепляетесь с >>. Если первый анализатор завершится успешно, будет запущен второй. many успешно, поэтому попытка eof. eof терпит неудачу, поэтому вы получаете только сообщение об ошибке eof.

С manyTill он пробует оба синтаксических анализатора (второй первый), и, если оба не удаются, сообщения об ошибках объединяются (это потому, что он использует <|> внутри).

В целом проще определить собственные ошибки с помощью <?>:

> parse (many (char '.') >> eof <?> "lots of dots") "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting lots of dots
3 голосов
/ 17 ноября 2010

В некотором поверхностном смысле причина различий в поведении заключается в том, что many является примитивным парсером , тогда как sepBy создается аналогично вашему переопределенномуmany.В последнем случае сообщение «ожидание ...» строится на основе альтернатив, доступных по пути, приведшему к ошибке разбора;с many такого выбора не было, он просто безоговорочно удался.

Я не знаю, назвал бы это ошибкой или , это просто своего родапричуды того, как работает Parsec.Обработка ошибок на самом деле не является сильной стороной Parsec, и это не кажется первым, о чем я бы беспокоился в этом отношении.Если это вас достаточно беспокоит, возможно, вы лучше справитесь с другими библиотеками разбора.Например, я слышал хорошие вещи о uu-parsinglib .

1 голос
/ 17 ноября 2010

С пикша

many p применяет анализатор p ноль или более раз.Возвращает список возвращаемых значений p.

Таким образом, пустая строка является допустимым входным значением для many комбинатора.

[Добавлено]

Ах, теперь я понимаю вашу точку зрения.expecting a or b сообщается, когда используется <|> (выбор комбинатора).many реализован без использования <|>, но sepBy использует его внутри.

0 голосов
/ 17 ноября 2010

Это ошибка, введенная в parsec-3.1. Если вы тестируете предыдущие версии, вы должны получить сообщение об ошибке, подобное этому:

> parse (many (char '.') >> eof) "" "a"
Left (line 1, column 1):
unexpected 'a'
expecting "." or end of input

По крайней мере, вот что я получаю после исправления ошибки: -)

...