使用FParsec解析float或int * float

时间:2016-02-02 11:02:52

标签: f# fparsec

我刚刚开始玩FParsec,我现在正尝试以下列格式解析字符串

10*0.5 0.25 0.75 3*0.1 0.9

例如,我希望将3 * 0.1扩展为0.1 0.1 0.1

到目前为止我所拥有的是以下内容

type UserState = unit
type Parser<'t> = Parser<'t, UserState>

let str s : Parser<_> = pstring s

let float_ws : Parser<_> = pfloat .>> spaces

let product = pipe2 pint32 (str "*" >>. float_ws) (fun x y -> List.init x (fun i -> y)) 

产品解析器正确解析格式为int*float的条目,并将其展开为浮点列表。但是,我无法提出一个解决方案,允许我解析int*float或只是一个浮点数。我想做点什么

many (product <|> float_ws)

这当然不起作用,因为解析器的返回类型不同。关于如何使这项工作的任何想法?是否可以包装修改float_ws,使其返回只有一个浮点数的列表?

1 个答案:

答案 0 :(得分:4)

您只需添加float_ws

即可float list返回|>> List.singleton
let float_ws : Parser<_> = pfloat .>> spaces |>> List.singleton

|>>只是map函数,您可以将一些函数应用于一个解析器的结果并接收一个新类型的新解析器:

val (|>>): Parser<'a,'u> -> ('a -> 'b) -> Parser<'b,'u>

请参阅:http://www.quanttec.com/fparsec/reference/primitives.html#members.:124::62::62

此外,由于product解析器包含一个int解析器,它将成功解析一个错误大小写的字符,这意味着解析器状态将被更改。这意味着您不能直接在第一个解析器上使用<|>运算符,还必须添加attempt,以便FParsec可以返回到原始解析器状态。

let combined = many (attempt product <|> float_ws)