[http://citeseer.ist.psu.edu/hutton96monadic.html Monadic Parser Combinators] - там наглядно описана общая идея, которую я тут развиваю. По-моему, это первая статья на эту тему. Ну, или одна из первых.
Ссылка на SVN: http://thesz.mskhug.ru/svn/parsers/
Всего там пять файлов:
* [http://thesz.mskhug.ru/browser/parsers/PTest.hs PTest.hs] - тестовое задание. Распознает примитивную грамматику выражений из +*, переменных, целых чисел и скобок. Из его содержимого интересны две функции: validParse и invalidParse, одна разбирает правильный текст, а другая разбирает текст с ошибкой. В зависимости от подключенного модуля с библиотекой разбора (import в начале файла), уровень информативности сообщений повышается.
* [http://thesz.mskhug.ru/browser/parsers/P0.hs P0.hs] - самый примитивный вариант библиотеки. Он может отрапортовать только лишь наличие ошибки или, если не все разобрали, где начинается неразобранный остаток. Обычно этого слишком мало.
* [http://thesz.mskhug.ru/browser/parsers/PMaxPos.hs PMaxPos.hs] - вариант библиотеки, который отслеживает наиболее далекое место, до которого добрались во время разбора. Этот вариант уже правильно рапортует о местоположении ошибки.
* [http://thesz.mskhug.ru/browser/parsers/PExpSet.hs PExpSet.hs] - это слегка модифицированный вариант PMaxPos.hs. Помимо правильного отчета о местоположении ошибки, он еще позволяет указать, что же система ждала в этом месте от пользователя - он перечисляет "ожидаемые" токены.
* [http://thesz.mskhug.ru/browser/parsers/Pos.hs Pos.hs] - операции над позициями. Ничего особо интересного.
Все это не очень эффективно с точки зрения производительности программы, но мне, обычно, хватало.
(по следам [http://community.livejournal.com/ru_lambda/87552.html небольшого обсуждения в ru_lambda]. Да и давно хотел все это описать.)