Je dois écrire un analyseur qui analyse paires clé-valeur dans un fichier qui ressemble à ceci:analyseur fparsec clé-valeur ne parvient pas à analyser
as235 242kj25klj Pairs:A=a1|B=b1|C=c1
kjlkjlkjlkj Pairs:A=a2|B=b2|C=c2
Notez que les lignes contiennent des ordures, l'étiquette, puis les paires clé-valeur.
Le code F # que j'ai écrit est la suivante:
#r"FParsec.dll"
open FParsec
let parse keys label =
let pkey = keys |> Seq.map pstring |> choice
let pvalue = manyCharsTill anyChar (anyOf "|\n")
let ppair = pkey .>> (skipChar '=') .>>. pvalue
let ppairSeq = many ppair
let pline = skipManyTill anyChar (pstring label)
>>. ppairSeq .>> newline
let pfile = many (opt pline) |>> Seq.choose id
run pfile
>> function
| Success (result, _, _) -> result
| Failure (errorMsg, _, _) -> failwith errorMsg
"""
as235 242kj25klj Pairs:A=a1|B=b1|C=c1
lkjlkjlkjlkj Pairs:A=a2|B=b2|C=c2
"""
|> parse ["A";"B";"C"] "Pairs:"
|> List.ofSeq
|> printfn "%A"
Le résultat attendu est:
[[("A","a1"); "B","b1"; "C","c1"]
[("A","a2"); "B","b2"; "C","c2"]]
... mais je reçois l'erreur suivante:
System.Exception: Error: Error in Ln: 8 Col: 1
Note: The error occurred at the end of the input stream.
Expecting: any char or 'Pairs:'
Des idées sur la façon dont je peux réparer cet analyseur?
Merci! MISE À JOUR: après le commentaire de Stephan j'ai essayé de le réparer mais sans succès. C'est une de mes dernières tentatives que je m'attendais à faire mais ce n'est pas le cas. Maintenant, le message d'erreur
let pkey = keys |> Seq.map pstring |> choice
let pvalue = manyCharsTill anyChar (anyOf "|\n")
let ppair = pkey .>> (skipChar '=') .>>. pvalue
let ppairSeq = manyTill ppair newline
let pnonEmptyLine =
skipManyTill anyChar (pstring label)
>>. ppairSeq
|>> Some
let pemptyLine = spaces >>. newline >>% None
let pline = pemptyLine <|> pnonEmptyLine
let pfile = manyTill pline eof |>> Seq.choose id
est:
Error in Ln: 2 Col: 5
as235 242kj25klj Pairs:A=a1|B=b1|C=c1
^
Expecting: newline
L'analyseur 'pline' semble échouer après avoir consommé entrée, comme' anyChar' consomme aussi des sauts de ligne, ce qui est probablement pas ce que vous voulait. Notez que 'many (opt pline)' conduira éventuellement à une exception, car 'opt x' peut réussir sans consommer d'entrée. Pour résoudre ce problème, vous pouvez ignorer les lignes vides en tant qu'espace (de fin) ou votre analyseur de ligne vide doit consommer un saut de ligne. –
Je pense que je comprends ce que tu veux dire mais je ne sais pas comment réparer l'analyseur. J'ai signalé ma tentative comme une mise à jour – vidi