FParsec で同種の json のような配列を解析しようとすると問題が発生します。問題を再現する短い例に分解しました。
#r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsecCS.dll"
#r @"..\packages\FParsec.1.0.2\lib\net40-client\FParsec.dll"
open System
open FParsec
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errormsg, _, _) -> printfn "Failure: %s" errormsg
type CValue = CInt of int64
| CBool of bool
| CList of CValue list
let P_WHITESPACE = spaces
let P_COMMA = pstring ","
let P_L_SBRACE = pstring "[" .>> P_WHITESPACE
let P_R_SBRACE = P_WHITESPACE >>. pstring "]"
let P_INT_VALUE = pint64 |>> CInt
let P_TRUE = stringReturn "true" (CBool true)
let P_FALSE = stringReturn "false" (CBool false)
let P_BOOL_VALUE = P_TRUE <|> P_FALSE
let P_LIST_VALUE =
let commaDelimitedList ptype = sepBy (ptype .>> P_WHITESPACE) (P_COMMA .>> P_WHITESPACE)
let delimitedList = (commaDelimitedList P_INT_VALUE) <|> (commaDelimitedList P_BOOL_VALUE)
let enclosedList = between P_L_SBRACE P_R_SBRACE delimitedList
enclosedList |>> CList
関数を使用しtest
て試してみると、次の結果が得られます。
test P_LIST_VALUE "[1,2,3]"
Success: CList [CInt 1L; CInt 2L; CInt 3L]
test P_LIST_VALUE "[true,false]"
Failure: Error in Ln: 1 Col: 2
[true,false]
^
Expecting: integer number (64-bit, signed) or ']'
演算子を使用するときにP_INT_VALUE
との順序を入れ替えると、解析は成功しますが、同様のエラーで失敗します。基本的に、私が最初に使用するパーサーは、使用しようとするものです。P_BOOL_VALUE
<|>
[true,false]
[1,2,3]
LHS がユーザー状態を変更した場合、オペレーターが RHS パーサーを試行しないことは理解して<|>
いますが、それがどのように発生するのかわかりません。P_BOOL_VALUE と P_INT_VALUE には共通の開始文字がないため、間違ったデータ型を解析しようとすると、両方ともすぐに失敗するはずです。Int が「false」または「true」で始まることはなく、bool が数字で始まることもありません。
私は何を間違っていますか?