2013-05-16 19 views
10

Czy jest możliwe jakoś uzyskać błąd parsowania jakiegoś niestandardowego typu? Byłoby fajnie, gdyby na przykład uzyskać więcej informacji o kontekście analizy z powodu błędu. I wydaje się, że nie jest zbyt wygodne, aby mieć informacje o błędzie tylko w formie wiadomości tekstowej.Parsera i niestandardowy błąd parsowania typ

+1

To nie wydaje się możliwe. ['Text.Parsec.Error'] (http://hackage.haskell.org/packages/archive/parsec/3.1.1/doc/html/Text-Parsec-Error.html) wydaje się podpowiadać, że każdy rodzaj błędu odpowiedzią jest ostatecznie 'String', a nawet [' () '] (http://hackage.haskell.org/packages/archive/parsec/3.1.1/doc/html/Text-Parsec-Prim.html #v: -60--63--62-) operator przyjmuje tylko łańcuchy. –

+0

Po prostu: wynik błędu nie jest "tylko wiadomości tekstowej". Zawiera pozycję źródłową oraz informacje o tym, co parser spodziewał się zobaczyć i tak dalej. Ale tak, czasami byłoby miło uzyskać więcej ... – MathematicalOrchid

Odpowiedz

8

Jak zauważa Rhymoid, niestety nie jest to możliwe.

Łącząc Parsec z własnym Either -jak monady nie pomoże, za - to wyjdzie zbyt wcześnie (nad Either) lub zbyt późno (EitherT nad).

Jeśli chcesz, możesz to zrobić w następujący sposób: użyj przez State (SourcePos, YourErrorType). (Nie można użyć stanu użytkownika Parsec, ponieważ wtedy błąd zostanie wycofany.)

Za każdym razem, gdy chcesz emitować strukturalną wartość błędu, zapisz ją w stanie z bieżącą lokalizacją, ale pod numerem tylko, jeśli obecna lokalizacja jest dalej niż zapisana. (Jeśli lokalizacje są równe, możesz jakoś scalić błędy. Może zachować ich listę.)

Wreszcie, po uruchomieniu monadowego stosu, otrzymasz ostateczny stan i ParseError, który zawiera SourcePos. Sprawdź, czy te dwie lokalizacje są zbieżne. Jeśli tego nie robią (tj. Numer SourcePos Parsera jest dalej), to nie ma wartości błędu dla tego błędu.