2 Licensed according to the included 'LICENSE' document
3 Author: Thomas Harning Jr <harningt@gmail.com>
5 local lpeg
= require("lpeg")
7 local util
= require("json.decode.util")
8 local jsonutil
= require("json.util")
13 module("json.decode.array")
15 -- Utility function to help manage slighly sparse arrays
16 local function processArray(array
)
18 for i
,v
in ipairs(array
) do
19 if v
== jsonutil
.null
then
23 if #array
== array
.n
then
26 if jsonutil
.InitArray
then
27 array
= jsonutil
.InitArray(array
) or array
32 local defaultOptions
= {
36 default
= nil -- Let the buildCapture optimization take place
41 local function buildCapture(options
, global_options
, state
)
42 local ignored
= global_options
.ignored
43 -- arrayItem == element
44 local arrayItem
= lpeg
.V(util
.types
.VALUE
)
45 -- If match-time capture supported, use it to remove stack limit for JSON
47 arrayItem
= lpeg
.Cmt(lpeg
.Cp(), function(str
, i
)
48 -- Decode one value then return
51 -- Found empty segment
52 #lpeg
.P(']' * lpeg
.Cc(END_MARKER
) * lpeg
.Cp())
53 -- Found a value + captured, check for required , or ] + capture next pos
54 + state
.VALUE_MATCH
* #(lpeg
.P(',') + lpeg
.P(']')) * lpeg
.Cp()
55 local capture
, i
= pattern
:match(str
, i
)
56 if END_MARKER
== capture
then
58 elseif (i
== nil and capture
== nil) then
65 local arrayElements
= lpeg
.Ct(arrayItem
* (ignored
* lpeg
.P(',') * ignored
* arrayItem
)^
0 + 0) / processArray
67 options
= options
and jsonutil
.merge({}, defaultOptions
, options
) or defaultOptions
68 local capture
= lpeg
.P("[")
69 capture
= capture
* ignored
70 * arrayElements
* ignored
71 if options
.trailingComma
then
72 capture
= capture
* (lpeg
.P(",") + 0) * ignored
74 capture
= capture
* lpeg
.P("]")
78 function register_types()
79 util
.register_type("ARRAY")
82 function load_types(options
, global_options
, grammar
, state
)
83 local capture
= buildCapture(options
, global_options
, state
)
84 local array_id
= util
.types
.ARRAY
85 grammar
[array_id
] = capture
86 util
.append_grammar_item(grammar
, "VALUE", lpeg
.V(array_id
))