Тип ошибки Parsec и пользовательский синтаксический анализ

Возможно ли каким-то образом получить ошибку синтаксического анализа какого-либо пользовательского типа? Было бы здорово получить дополнительную информацию о синтаксическом анализе контекста из-за ошибки, например. И, кажется, не очень удобно иметь информацию об ошибке только в виде текстового сообщения.

Ответ 1

Как отмечает Раймоид, это невозможно напрямую, к сожалению.

Сочетание Parsec с вашей собственной монадией Either -подобие тоже не поможет - он скоро выйдет (ParsecT over Either) или слишком поздно (EitherT over ParsecT).

Если вы хотите это плохо, вы можете сделать это следующим образом: используйте ParsecT over State (SourcePos, YourErrorType). (Вы не можете использовать пользовательское состояние Parsec, потому что ошибка будет возвращена.)

Каждый раз, когда вы хотите исправить структурированное значение ошибки, запишите его в состояние с текущим местоположением, но только если текущее местоположение находится дальше, чем уже записанное. (Если местоположения равны, вы можете каким-то образом слить ошибки. Возможно, сохраните их список.)

Наконец, когда вы запустите свой стек монады, вы получите окончательное состояние и ParseError, который содержит SourcePos. Просто проверьте, совпадают ли эти два местоположения. Если они этого не делают (то есть Parsec SourcePos дальше), то у вас нет значения ошибки для этой ошибки.