2

私はFParsecを使用して空白に敏感なパーサーを実装しようとしています。そして、n空白の文字で始まるテキストの行を解析する関数を定義するという赤ちゃんのステップから始めています。

これが私がこれまでに持っているものです:

let test: Parser<string list,int>
  = let manyNSatisfy i p = manyMinMaxSatisfy i i p

    let p = fun (stream:CharStream<int>) ->
      let state = stream.UserState

      // Should fail softly if `state` chars wasn't parsed
      let result = attempt <| manyNSatisfy state (System.Char.IsWhiteSpace) <| stream

      if result.Status <> Ok 
        then result
        else restOfLine false <| stream

    sepBy p newline

私の問題は私が走るとき

runParserOnString test 1 "test" " hi\n there\nyou" |> printfn "%A"

「あなた」でエラーが発生します。attempt私は、状態の変化をさかのぼって追跡Errorし、自分のステータスがソフトな失敗を与えるので戻るという印象を受けました。

["hi"; "there"]パーサーから戻るにはどうすればよいですか?

4

2 に答える 2

3

ああ、なんて恥ずかしい。

sepEndByつまり、セパレーターで解析を終了する必要があります。

于 2012-07-24T08:43:57.450 に答える
0

これはもっと慣用的に見えます。ハードコーディング1しましたが、パラメータとして簡単に抽出できます。

let skipManyNSatisfy i = skipManyMinMaxSatisfy i i
let pMyText =
    (                                               // 1st rule
        skipManyNSatisfy 1 System.Char.IsWhiteSpace // skip an arbitrary # of WhiteSpaces
        >>. restOfLine false |>> Some               // return the rest as Option
    )
    <|>                                             // If the 1st rule failed...
    (                                               // 2nd rule
        skipRestOfLine false                        // skip till the end of the line
        >>. preturn None                            // no result
    )
    |> sepBy <| newline                             // Wrap both rules, separated by newLine
    |>> Seq.choose id                               // Out of received string option seq, select only Some()
于 2012-07-25T12:20:34.560 に答える