1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2014 Alexis Laferrière <alexis.laf@xymus.net>
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 # Static interface to get Nit objects from a Json string.
19 # `String::json_to_nit_object` returns an equivalent Nit object from
20 # the Json source. This object can then be type checked by the usual
21 # languages features (`isa` and `as`).
25 private import json_parser
26 private import json_lexer
29 fun to_nit_object
: nullable Object is abstract
32 redef class Nvalue_number
33 redef fun to_nit_object
35 var text
= n_number
.text
36 if text
.chars
.has
('.') or text
.chars
.has
('e') or text
.chars
.has
('E') then return text
.to_f
41 redef class Nvalue_string
42 redef fun to_nit_object
do return n_string
.to_nit_string
45 redef class Nvalue_true
46 redef fun to_nit_object
do return true
49 redef class Nvalue_false
50 redef fun to_nit_object
do return false
53 redef class Nvalue_null
54 redef fun to_nit_object
do return null
58 # FIXME support \n, etc.
59 fun to_nit_string
: String do return text
.substring
(1, text
.length-2
).
60 replace
("\\\\", "\\").replace
("\\\"", "\
"").replace
("\\b", "\b").
61 replace
("\\/", "/").replace
("\\n", "\n").replace
("\\r", "\r").
65 redef class Nvalue_object
66 redef fun to_nit_object
68 var obj
= new HashMap[String, nullable Object]
69 var members
= n_members
70 if members
!= null then
71 var pairs
= members
.pairs
72 for pair
in pairs
do obj
[pair
.name
] = pair
.value
79 fun pairs
: Array[Npair] is abstract
82 redef class Nmembers_tail
85 var arr
= n_members
.pairs
91 redef class Nmembers_head
92 redef fun pairs
do return [n_pair
]
96 fun name
: String do return n_string
.to_nit_string
97 fun value
: nullable Object do return n_value
.to_nit_object
100 redef class Nvalue_array
101 redef fun to_nit_object
103 var arr
= new Array[nullable Object]
104 var elements
= n_elements
105 if elements
!= null then
106 var items
= elements
.items
107 for item
in items
do arr
.add
(item
.to_nit_object
)
113 redef class Nelements
114 fun items
: Array[Nvalue] is abstract
117 redef class Nelements_tail
120 var items
= n_elements
.items
126 redef class Nelements_head
127 redef fun items
do return [n_value
]
131 fun json_to_nit_object
: nullable Object
133 var lexer
= new Lexer_json(to_s
)
134 var parser
= new Parser_json
135 var tokens
= lexer
.lex
136 parser
.tokens
.add_all
(tokens
)
137 var root_node
= parser
.parse
138 if root_node
isa NStart then
139 return root_node
.n_0
.to_nit_object
140 else if root_node
isa NLexerError then
141 var pos
= root_node
.position
142 print
"Json lexer error: {root_node.message} at {pos or else "<unknown>"} for {root_node}"
144 else if root_node
isa NParserError then
145 var pos
= root_node
.position
146 print
"Json parsing error: {root_node.message} at {pos or else "<unknown>"} for {root_node}"