6

我刚开始玩 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 使其返回一个只有一个浮点数的列表?

4

1 回答 1

4

您可以通过简单float_wsfloat list添加 a|>> 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 :


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

let combined = many (attempt product <|> float_ws)
于 2016-02-02T11:18:55.547 回答