2016-06-20 17 views
0

Ich habe gerade mit Parsec begonnen und ich versuche, etwas Einfaches zu tun.Parsing maskiert Trennzeichen in Parsec

Ich möchte Schlüssel-Wert-Strings, wie in this parsec tutorial gezeigt, trennen.

Zum Beispiel sollte die Zeichenfolge FirstN=Tom&LastN=Brady[["FirstN","Tom"],["LastN","Brady"]] geben.

Das ist einfach, aber ich möchte auch zulassen, dass das '=' Zeichen in der Zeichenfolge escaped ist. Zum Beispiel sollte die Zeichenfolge Equation=1+1\\=2[["Equation", "1+1\\=2"]] (oder [["Equation","1+1=2"]] geben, aber ich habe noch nicht entschieden, was das beste ist).

Für das einfache Beispiel der Parsing-Code ist der folgende:

kvParser :: String -> Either ParseError [[String]] 
kvParser input = parse kvString "Error text?" input 

kvString = sepBy kvVal (char '&') 
kvVal = sepBy (many (noneOf "=&")) (char '=') 

einen entflohenen = Damit ich glaube, ich brauche den (char '=') Wert zu ändern, aber ich bin nicht sicher, wie. Hat jemand irgendwelche Vorschläge?

Dank

bearbeiten: Der letzte Arbeits Parser ist

kvParser :: String -> Either ParseError [[String]] 
kvParser input = parse kvString "Error text?" input 

kvString = sepBy kvVal (char '&') 
kvVal = sepBy (many kvChar) (char '=') 
kvChar = noneOf "\\&=" <|> (char '\\' >> anyChar) 

Ich habe auch die Verwendung eines try combinator arbeiten folgende.

kvParser :: String -> Either ParseError [[String]] 
kvParser input = parse kvString "Error text?" input 

kvString = sepBy kvVal (char '&') 
kvVal = sepBy (many kvChar) (char '=') 
kvChar = try (string "\\=" >> return '=') <|> noneOf "&=" 

Antwort

3

Der Separator ist in Ordnung; Was Sie wollen, ist \= als Teil eines Schlüssels oder Werts zu akzeptieren. Statt

noneOf "=&" 

können Sie versuchen

(noneOf "\\&" <|> (char '\\' >> anyChar)) 

Das heißt, noneOf akzeptieren, dass etwas nicht ein Backslash ist, da sonst der Parser auf der rechten Seite übernehmen (und überspringen) einen umgekehrten Schrägstrich und halten die Charakter folgt ihm. Das sollte verhindern, dass es als Trennzeichen erkannt wird.

+0

Ich ersetzte "noneOf" = & "' mit '(noneOf" \\ "<|> (char '\' anyChar))' aber jetzt ist es nicht auf '=' getrennt. Es isst jedoch die "\\" Werte. – user668074

+0

OK, vielleicht müssen Sie '=' zurück in die 'noneOf'-Zeichenfolge hinzufügen. Ich gebe zu, ich habe es nicht persönlich getestet. Ich denke 'noneOf" \\ = & "' wird funktionieren ... – MathematicalOrchid

+0

Danke, das funktioniert. Ich habe eine andere Art zu arbeiten. – user668074