1 ! Copyright (C) 2006 Chris Double.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: kernel parser-combinators namespaces sequences promises strings
4 assocs math math.parser math.vectors math.functions
5 lazy-lists hashtables ascii ;
8 ! Grammar for JSON from RFC 4627
10 : [<&>] ( quot -- quot )
11 { } make unclip [ <&> ] reduce ;
13 : [<|>] ( quot -- quot )
14 { } make unclip [ <|> ] reduce ;
16 LAZY: 'ws' ( -- parser )
23 LAZY: spaced ( parser -- parser )
24 'ws' swap &> 'ws' <& ;
26 LAZY: 'begin-array' ( -- parser )
29 LAZY: 'begin-object' ( -- parser )
32 LAZY: 'end-array' ( -- parser )
35 LAZY: 'end-object' ( -- parser )
38 LAZY: 'name-separator' ( -- parser )
41 LAZY: 'value-separator' ( -- parser )
44 LAZY: 'false' ( -- parser )
47 LAZY: 'null' ( -- parser )
50 LAZY: 'true' ( -- parser )
53 LAZY: 'quot' ( -- parser )
56 LAZY: 'string' ( -- parser )
60 [ CHAR: \\ = or ] keep
63 'quot' <& [ >string ] <@ ;
67 LAZY: 'member' ( -- parser )
73 LAZY: 'object' ( -- parser )
75 'member' 'value-separator' list-of &>
76 'end-object' <& [ >hashtable ] <@ ;
78 LAZY: 'array' ( -- parser )
80 'value' 'value-separator' list-of &>
83 LAZY: 'minus' ( -- parser )
86 LAZY: 'plus' ( -- parser )
89 LAZY: 'zero' ( -- parser )
90 "0" token [ drop 0 ] <@ ;
92 LAZY: 'decimal-point' ( -- parser )
95 LAZY: 'digit1-9' ( -- parser )
98 CHAR: 1 CHAR: 9 between?
102 ] satisfy [ digit> ] <@ ;
104 LAZY: 'digit0-9' ( -- parser )
105 [ digit? ] satisfy [ digit> ] <@ ;
107 : decimal>integer ( seq -- num ) 10 swap digits>integer ;
109 LAZY: 'int' ( -- parser )
111 'digit1-9' 'digit0-9' <*> <&:> [ decimal>integer ] <@ <|> ;
113 LAZY: 'e' ( -- parser )
114 "e" token "E" token <|> ;
116 : sign-number ( pair -- number )
117 #! Pair is { minus? num }
118 #! Convert the json number value to a factor number
119 dup second swap first [ -1 * ] when ;
121 LAZY: 'exp' ( -- parser )
123 'minus' 'plus' <|> <?> &>
124 'digit0-9' <+> [ decimal>integer ] <@ <&> [ sign-number ] <@ ;
126 : sequence>frac ( seq -- num )
127 #! { 1 2 3 } => 0.123
128 reverse 0 [ swap 10 / + ] reduce 10 / >float ;
130 LAZY: 'frac' ( -- parser )
131 'decimal-point' 'digit0-9' <+> &> [ sequence>frac ] <@ ;
133 : raise-to-power ( pair -- num )
134 #! Pair is { num exp }.
135 #! Multiply 'num' by 10^exp
136 dup second dup [ 10 swap first ^ swap first * ] [ drop first ] if ;
138 LAZY: 'number' ( -- parser )
140 [ 'int' , 'frac' 0 succeed <|> , ] [<&>] [ sum ] <@
141 'exp' <?> <&> [ raise-to-power ] <@ <&> [ sign-number ] <@ ;
143 LAZY: 'value' ( -- parser )
154 : json> ( string -- object )
155 #! Parse a json formatted string to a factor object
156 'value' parse dup nil? [
157 "Could not parse json" throw
159 car parse-result-parsed