3 Stimmen

FParsec: wie parse ich das Datum in fparsec (Neuling)

Ich verwende die Bill Casarin Beitrag über das Parsen von Dateien mit Trennzeichen mit fparsec habe ich die Logik vereinfacht, um ein Verständnis dafür zu bekommen, wie der Code funktioniert. Ich analysiere ein mehrzeiliges Dokument mit Trennzeichen in eine Cell-List-Struktur (vorerst), wobei eine Cell ein String oder ein Float ist. Ich bin ein kompletter Neuling auf diesem Gebiet.

Ich habe Probleme beim Parsen der Floats - in einem typischen Fall (eine Zelle, die durch Tabulatoren begrenzt ist und einen numerischen Wert enthält) funktioniert es. Wenn jedoch eine Zelle zufällig eine Zeichenfolge ist, die mit einer Zahl beginnt, fällt es auseinander.

Wie ändere ich pFloatCell, um entweder zu parsen (obwohl der Weg durch die Registerkarte) als Float oder nichts?

Gracias

type Cell = 
    | String of string 
    | Float of float
.
.
.
let pStringCell delim = 
    manyChars (nonQuotedCellChar delim)
    |>> String

// this is my issue. pfloat parses the string one 
// char at a time, and once it starts off with a number 
// it is down that path, and errors out
let pFloatCell delim = 
    FParsec.CharParsers.pfloat
    |>> Float

let pCell delim = 
    (pFloatCell delim) <|> (pStringCell delim)
.
.
.
let ParseTab s  =
  let delim = "\t"
  let res = run (csv delim) s in
    match res with
     | Success (rows, _, _) -> { IsSuccess = true; ErrorMsg = "Ok"; Result = stripEmpty rows }
     | Failure (s, _, _) -> { IsSuccess = false; ErrorMsg = s; Result = [[]] }
.
.
.
let test() =

    let parsed = ParseTab data

Ups, zu spät für mich gestern Abend. Ich wollte die Daten posten. Diese erste funktioniert

let data = 
    "s10 Mar 2011 18:28:11 GMT\n"

während dies einen Fehler zurückgibt:

let data = 
    "10 Mar 2011 18:28:11 GMT\n"

sowohl mit als auch ohne die Empfehlung von ChaosP:

ErrorMsg = "Fehler in Ln: 1 Col: 3 \r\n10 Mar 2011 18:28:11 GMT \r\n ^ \r\nExpecting : Ende der Datei, Zeilenumbruch oder ' \t ' \r\n "

Es sieht so aus, als ob der Versuch gut funktioniert. Im zweiten Fall wird nur bis zur 10 gegriffen - und der Code für pfloat sucht nur bis zum ersten Whitespace . Ich muss pfloat davon überzeugen, dass es bis zum nächsten Tabulator oder Zeilenumbruch schauen muss, unabhängig davon, ob ein Leerzeichen davor ist; schreibe meine eigene Version von pfloat, indem ich ein Double.Parse ausführe - aber ich würde mich lieber auf die Bibliothek verlassen.

2voto

ChaosPandion Punkte 75527

Da der zu analysierende Text anscheinend etwas zweideutig ist, müssen Sie Ihre pCell Parser.

let sep delim =
     skipString delim <|> skipAnyOf "\r\n" <|> eof

let pCell delim = 
    attempt (pFloatCell delim .>> sep delim) <|> (pStringCell delim .>> sep delim)

Das bedeutet auch, dass Sie den Parser ändern müssen, der die pCell .

let pCells delim =
    many pCell delim 

Hinweis

En .>> Operator ist eigentlich ganz einfach. Stellen Sie sich das so vor wie den Leap-Frog-Operator. Der Wert der linken Seite wird zurückgegeben, nachdem die rechte Seite angewendet und das Ergebnis ignoriert wurde.

Parser<'a, 'b> -> Parser<'c, 'b> -> Parser<'a, 'b>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X