Parsing int oder float with FParsec
Ich versuche, eine Datei mit FParsec zu analysieren, die entweder aus float- oder int-Werten besteht. Ich habe zwei Probleme, für die ich keine gute Lösung finden kann.
1
Beidepint32
undpfloat
analysiert dieselbe Zeichenfolge erfolgreich, gibt jedoch unterschiedliche Antworten, z. B.pint32
wird zurückkehren3
beim Parsen der Zeichenfolge"3.0"
undpfloat
wird zurückkehren3.0
beim Parsen der gleichen Zeichenfolge. Ist es möglich, einen Gleitkommawert mit @ zu analysierepint32
und habe es scheitern, wenn die Zeichenfolge ist"3.0"
?
it anderen Worten, gibt es eine Möglichkeit, den folgenden Code zum Laufen zu bringen:
let parseFloatOrInt lines =
let rec loop intvalues floatvalues lines =
match lines with
| [] -> floatvalues, intvalues
| line::rest ->
match run floatWs line with
| Success (r, _, _) -> loop intvalues (r::floatvalues) rest
| Failure _ ->
match run intWs line with
| Success (r, _, _) -> loop (r::intvalues) floatvalues rest
| Failure _ -> loop intvalues floatvalues rest
loop [] [] lines
Dieser Code platziert alle Gleitkommawerte korrekt imfloatvalues
Liste, aber weilpfloat
kehrt zurück"3.0"
beim Parsen der Zeichenfolge"3"
, alle ganzzahligen Werte werden auch in das @ geschriebfloatvalues
aufführen
2
Das obige Codebeispiel scheint mir etwas ungeschickt zu sein, daher schätze ich, dass es einen besseren Weg dafür geben muss. Ich überlegte, sie mit @ zu kombinierchoice
, beide Parser müssen jedoch denselben Typ zurückgeben, damit dies funktioniert. Ich denke, ich könnte eine diskriminierte Vereinigung mit einer Option für float und einer für int machen und die Ausgabe von @ konvertierepint32
undpfloat
Verwendung der|>>
Operator. Allerdings frage ich mich, ob es eine bessere Lösung gibt?