大佬教程收集整理的这篇文章主要介绍了f# – 使用FParsec解析int或float,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
1
pint32和pfloat都会成功解析相同的字符串,但会给出不同的答案,例如pint32在解析字符串“3.0”时将返回3,而pfloat在解析相同的字符串时将返回3.0.是否可以尝试使用pint32解析浮点值,如果字符串为“3.0”则会失败?
换句话说,有没有办法使以下代码工作:
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
这段代码将正确地将所有浮点值放在floatvalues列表中,但由于pfloat在解析字符串“3”时返回“3.0”,因此所有整数值也将放在floatvalues列表中.
2
上面的代码示例对我来说似乎有点笨拙,所以我猜测必须有更好的方法来做到这一点.我考虑过使用choice来组合它们,但是两个解析器必须返回相同的类型才能工作.我想我可以使用一个浮动选项和一个用于int的选项进行区分联合,并使用|>>转换pint32和pfloat的输出.操作符.但是,我想知道是否有更好的解决方案?
这是我写它的方式:
/// The resulTing type,or DSL type MyData = | IntValue of int | FloatValue of float | Error // special case for all parse @R_750_4895@ // Then,let's define individual parsers: let pMyInt = pint32 |>> IntValue // this is an alternative version of float parser. // it ensures that the value has non-zero fractional part. // caveat: the naive approach would treat values like 42.0 as Integer let pMyFloat = pfloat >>= (fun x -> if x % 1 = 0 then fail "Not a float" else preturn (FloatValue X)) let pError = // this parser must consume some input,// otherwise combined with `many` it would hang in a dead loop skipAnyChar >>. preturn Error // Now,the combined parser: let pCombined = [ pMyFloat; pMyInt; pError ] // note,future parsers will be added here; // mind the order as float supersedes thE int,// and Error must be the last |> List.map (fun p -> p .>> ws) // I'm too lazy to add whitespase skipping // into each individual parser |> List.map attempt // each parser is optional |> choice // on each iteration,one of the parsers must succeed |> many // a loop
注意,上面的代码能够处理任何来源:字符串,流或其他任何来源.您的真实应用可能需要使用文件,但只使用字符串列表可以简化单元测试.
// Now,applying the parser somewhere in the code: let maybeParseResult = match run pCombined myStringData with | success(result,_) -> Some result | Failure(_,_) -> None // or anything that inDicates general parse failure
UPD.我根据评论编辑了代码.更新了pMyFloat以确保解析的值具有非零小数部分.
以上是大佬教程为你收集整理的f# – 使用FParsec解析int或float全部内容,希望文章能够帮你解决f# – 使用FParsec解析int或float所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。