Ich versuche, eine einfache Sprache mit Parsec zu analysieren. Es kann entweder Zuweisungen "x = y" oder Präfixe wie "Präfix Test" geben. Die Parsing-Regel für Zuweisungen ist jedoch gierig und schlägt nicht fehl, wenn kein "=" vorhanden ist. Zum BeispielParsing-Operation ohne Präfix in Parsec
parse tp "" "prefix foo"
führt zu einem Parsing-Fehler. Der entsprechende Code:
module Test where
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Language
import Text.ParserCombinators.Parsec.Expr
import qualified Text.ParserCombinators.Parsec.Token as P
lexer = haskell
reserved = P.reserved lexer
reservedOp = P.reservedOp lexer
data Term = Term String
deriving (Show)
term :: Parser Term
term = do { x <- many alphaNum
; reservedOp "="
; y <- many alphaNum
; return (Term (x++y))
}
<|> do { reserved "prefix"
; x <- many alphaNum
; return (Term x)
}
tp = do { e<-term; return e }
Was fehlt mir? Ist meine Herangehensweise überhaupt möglich, oder habe ich Parsec falsch verstanden?
Wie wäre es mit 'Leerzeichen' nach' reserviertem "Präfix" '? – jeiea
Wir kommen nie so weit, der Parser sieht nur im ersten aus. Wenn wir die Reihenfolge der Regeln ändern, wird die Anweisung korrekt analysiert. Dies funktioniert jedoch nur in diesem einfachen Fall. Wenn wir mehr Regeln wie die erste haben, funktioniert der Trick nicht mehr. – hexhex
Es funktioniert nicht, weil 'viele alphaNum'" Präfix "verwendet, aber dann fehlschlägt - sobald ein Parser nach der Verwendung von Eingaben fehlgeschlagen ist, wird es keine andere Alternative versuchen (gegeben durch' <|> 'oder' choice' usw.). Sie benötigen einen "try" auf dem ersten Parser. (Ich glaube, Sie haben Parsec falsch verstanden - Sie erwarten automatisches Backtracking, aber Parsec tut das einfach nicht. Es gibt andere Parser-Bibliotheken, die das tun, glaube ich) – user2407038