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それを float のリストに展開します。ただし、フロートまたはフロートのみを解析できるソリューションを思い付くのに苦労していますint*float。私は次のようなことをしたいと思います

many (product <|> float_ws)

もちろん、パーサーの戻り値の型が異なるため、これは機能しません。これを機能させる方法についてのアイデアはありますか?float_ws を変更して、float が 1 つだけのリストを返すようにラップすることは可能ですか?

4

1 に答える 1

4

aを追加するだけで、 float_wsreturn aを作成できます。float list|>> List.singleton

let float_ws : Parser<_> = pfloat .>> spaces |>> List.singleton

|>>map1 つのパーサーの結果に何らかの関数を適用し、新しいタイプの新しいパーサーを受け取る関数です。

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

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


また、productパーサーには int パーサーが含まれているため、間違った大文字と小文字の文字を正常に解析します。これは、パーサーの状態が変更されることを意味します。つまり<|>、最初のパーサーで演算子を直接使用することはできません。また、attemptFParsec が元のパーサー状態に戻れるように追加する必要があります。

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