8 people like it.
Like the snippet!
JSON Parser
JSON Parser using Regular Expressions & Active Patterns (just for fun).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
|
type token =
| WhiteSpace
| Symbol of char
| StrToken of string
| NumToken of float
| BoolToken of bool
let (|Match|_|) pattern input =
let m = System.Text.RegularExpressions.Regex.Match(input, pattern)
if m.Success then Some m.Value else None
let bool = System.Boolean.Parse
let unquote (s:string) = s.Substring(1,s.Length-2)
let toToken = function
| Match @"^\s+" s -> s, WhiteSpace
| Match @"^""[^""\\]*(?:\\.[^""\\]*)*""" s -> s, s |> unquote |> StrToken
| Match @"^\{|^\}|^\[|^\]|^:|^," s -> s, s.[0] |> Symbol
| Match @"^\d+(\.\d+)?|\.\d+" s -> s, s |> float |> NumToken
| Match @"^true|false" s -> s, s |> bool |> BoolToken
| _ -> invalidOp "Unknown token"
let tokenize s =
let rec tokenize' index (s:string) =
if index = s.Length then []
else
let next = s.Substring index
let text, token = toToken next
token :: tokenize' (index + text.Length) s
tokenize' 0 s
|> List.choose (function WhiteSpace -> None | t -> Some t)
type json =
| Number of float
| String of string
| Boolean of bool
| Array of json list
| Object of (string * json) list
| Null
let rec (|ValueRec|_|) = function
| NumToken n::t -> Some(Number n, t)
| BoolToken b::t -> Some(Boolean b, t)
| StrToken s::t -> Some(String s, t)
| Symbol '['::ValuesRec(vs, Symbol ']'::t) -> Some(Array vs,t)
| Symbol '{'::PairsRec(ps, Symbol '}'::t) -> Some(Object ps,t)
| [] -> Some(Null,[])
| _ -> None
and (|ValuesRec|_|) = function
| ValueRec(p,t) ->
let rec aux p' = function
| Symbol ','::ValueRec(p,t) -> aux (p::p') t
| t -> p' |> List.rev,t
Some(aux [p] t)
| _ -> None
and (|PairRec|_|) = function
| StrToken k::Symbol ':'::ValueRec(v,t) -> Some((k,v), t)
| _ -> None
and (|PairsRec|_|) = function
| PairRec(p,t) ->
let rec aux p' = function
| Symbol ','::PairRec(p,t) -> aux (p::p') t
| t -> p' |> List.rev,t
Some(aux [p] t)
| _ -> None
let parse s =
tokenize s |> function
| ValueRec(v,[]) -> v
| _ -> failwith "Failed to parse JSON"
module Test =
let jsonString = "{
\"Name\": \"Phil\",
\"Phone\": 123456789
}"
let person = parse jsonString
let name, phone = person |> function
| Object(["Name", String name; "Phone",Number phone]) ->
name, phone
| _ -> invalidOp "Invalid person"
|
union case token.WhiteSpace: token
union case token.Symbol: char -> token
Multiple items
val char : value:'T -> char (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.char
--------------------
type char = System.Char
Full name: Microsoft.FSharp.Core.char
union case token.StrToken: string -> token
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
union case token.NumToken: float -> token
Multiple items
val float : value:'T -> float (requires member op_Explicit)
Full name: Microsoft.FSharp.Core.Operators.float
--------------------
type float = System.Double
Full name: Microsoft.FSharp.Core.float
--------------------
type float<'Measure> = float
Full name: Microsoft.FSharp.Core.float<_>
union case token.BoolToken: bool -> token
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
val pattern : string
val input : string
val m : System.Text.RegularExpressions.Match
namespace System
namespace System.Text
namespace System.Text.RegularExpressions
Multiple items
type Regex =
new : pattern:string -> Regex + 1 overload
member GetGroupNames : unit -> string[]
member GetGroupNumbers : unit -> int[]
member GroupNameFromNumber : i:int -> string
member GroupNumberFromName : name:string -> int
member IsMatch : input:string -> bool + 1 overload
member Match : input:string -> Match + 2 overloads
member Matches : input:string -> MatchCollection + 1 overload
member Options : RegexOptions
member Replace : input:string * replacement:string -> string + 5 overloads
...
Full name: System.Text.RegularExpressions.Regex
--------------------
System.Text.RegularExpressions.Regex(pattern: string) : unit
System.Text.RegularExpressions.Regex(pattern: string, options: System.Text.RegularExpressions.RegexOptions) : unit
System.Text.RegularExpressions.Regex.Match(input: string, pattern: string) : System.Text.RegularExpressions.Match
System.Text.RegularExpressions.Regex.Match(input: string, pattern: string, options: System.Text.RegularExpressions.RegexOptions) : System.Text.RegularExpressions.Match
property System.Text.RegularExpressions.Group.Success: bool
union case Option.Some: Value: 'T -> Option<'T>
property System.Text.RegularExpressions.Capture.Value: string
union case Option.None: Option<'T>
Multiple items
val bool : arg00:string -> bool
Full name: Script.bool
--------------------
type bool = System.Boolean
Full name: Microsoft.FSharp.Core.bool
type Boolean =
struct
member CompareTo : obj:obj -> int + 1 overload
member Equals : obj:obj -> bool + 1 overload
member GetHashCode : unit -> int
member GetTypeCode : unit -> TypeCode
member ToString : unit -> string + 1 overload
static val TrueString : string
static val FalseString : string
static member Parse : value:string -> bool
static member TryParse : value:string * result:bool -> bool
end
Full name: System.Boolean
System.Boolean.Parse(value: string) : bool
val unquote : s:string -> string
Full name: Script.unquote
val s : string
System.String.Substring(startIndex: int) : string
System.String.Substring(startIndex: int, length: int) : string
property System.String.Length: int
val toToken : _arg1:string -> string * token
Full name: Script.toToken
active recognizer Match: string -> string -> string option
Full name: Script.( |Match|_| )
val invalidOp : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.invalidOp
val tokenize : s:string -> token list
Full name: Script.tokenize
val tokenize' : (int -> string -> token list)
val index : int
val next : string
val text : string
Multiple items
val token : token
--------------------
type token =
| WhiteSpace
| Symbol of char
| StrToken of string
| NumToken of float
| BoolToken of bool
Full name: Script.token
Multiple items
module List
from Microsoft.FSharp.Collections
--------------------
type List<'T> =
| ( [] )
| ( :: ) of Head: 'T * Tail: 'T list
interface IEnumerable
interface IEnumerable<'T>
member Head : 'T
member IsEmpty : bool
member Item : index:int -> 'T with get
member Length : int
member Tail : 'T list
static member Cons : head:'T * tail:'T list -> 'T list
static member Empty : 'T list
Full name: Microsoft.FSharp.Collections.List<_>
val choose : chooser:('T -> 'U option) -> list:'T list -> 'U list
Full name: Microsoft.FSharp.Collections.List.choose
val t : token
type json =
| Number of float
| String of string
| Boolean of bool
| Array of json list
| Object of (string * json) list
| Null
Full name: Script.json
union case json.Number: float -> json
Multiple items
union case json.String: string -> json
--------------------
module String
from Microsoft.FSharp.Core
union case json.Boolean: bool -> json
Multiple items
union case json.Array: json list -> json
--------------------
module Array
from Microsoft.FSharp.Collections
type 'T list = List<'T>
Full name: Microsoft.FSharp.Collections.list<_>
union case json.Object: (string * json) list -> json
union case json.Null: json
val n : float
val t : token list
val b : bool
active recognizer ValuesRec: token list -> (json list * token list) option
Full name: Script.( |ValuesRec|_| )
val vs : json list
active recognizer PairsRec: token list -> ((string * json) list * token list) option
Full name: Script.( |PairsRec|_| )
val ps : (string * json) list
active recognizer ValueRec: token list -> (json * token list) option
Full name: Script.( |ValueRec|_| )
val p : json
val aux : (json list -> token list -> json list * token list)
val p' : json list
val rev : list:'T list -> 'T list
Full name: Microsoft.FSharp.Collections.List.rev
val k : string
val v : json
active recognizer PairRec: token list -> ((string * json) * token list) option
Full name: Script.( |PairRec|_| )
val p : string * json
val aux : ((string * json) list -> token list -> (string * json) list * token list)
val p' : (string * json) list
val parse : s:string -> json
Full name: Script.parse
val failwith : message:string -> 'T
Full name: Microsoft.FSharp.Core.Operators.failwith
module Test
from Script
val jsonString : string
Full name: Script.Test.jsonString
val person : json
Full name: Script.Test.person
val name : string
Full name: Script.Test.name
val phone : float
Full name: Script.Test.phone
val name : string
val phone : float
More information