initial release
This commit is contained in:
103
cosmic rage/lua/json/decode/object.lua
Normal file
103
cosmic rage/lua/json/decode/object.lua
Normal file
@@ -0,0 +1,103 @@
|
||||
--[[
|
||||
Licensed according to the included 'LICENSE' document
|
||||
Author: Thomas Harning Jr <harningt@gmail.com>
|
||||
--]]
|
||||
local lpeg = require("lpeg")
|
||||
|
||||
local util = require("json.decode.util")
|
||||
local merge = require("json.util").merge
|
||||
|
||||
local tonumber = tonumber
|
||||
local unpack = unpack
|
||||
local print = print
|
||||
local tostring = tostring
|
||||
|
||||
local rawset = rawset
|
||||
|
||||
module("json.decode.object")
|
||||
|
||||
-- BEGIN LPEG < 0.9 SUPPORT
|
||||
local initObject, applyObjectKey
|
||||
if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then
|
||||
function initObject()
|
||||
return {}
|
||||
end
|
||||
function applyObjectKey(tab, key, val)
|
||||
tab[key] = val
|
||||
return tab
|
||||
end
|
||||
end
|
||||
-- END LPEG < 0.9 SUPPORT
|
||||
|
||||
local defaultOptions = {
|
||||
number = true,
|
||||
identifier = true,
|
||||
trailingComma = true
|
||||
}
|
||||
|
||||
default = nil -- Let the buildCapture optimization take place
|
||||
|
||||
strict = {
|
||||
number = false,
|
||||
identifier = false,
|
||||
trailingComma = false
|
||||
}
|
||||
|
||||
local function buildItemSequence(objectItem, ignored)
|
||||
return (objectItem * (ignored * lpeg.P(",") * ignored * objectItem)^0) + 0
|
||||
end
|
||||
|
||||
local function buildCapture(options, global_options)
|
||||
local ignored = global_options.ignored
|
||||
local string_type = lpeg.V(util.types.STRING)
|
||||
local integer_type = lpeg.V(util.types.INTEGER)
|
||||
local value_type = lpeg.V(util.types.VALUE)
|
||||
options = options and merge({}, defaultOptions, options) or defaultOptions
|
||||
local key = string_type
|
||||
if options.identifier then
|
||||
key = key + lpeg.C(util.identifier)
|
||||
end
|
||||
if options.number then
|
||||
key = key + integer_type
|
||||
end
|
||||
local objectItems
|
||||
local objectItem = (key * ignored * lpeg.P(":") * ignored * value_type)
|
||||
-- BEGIN LPEG < 0.9 SUPPORT
|
||||
if not (lpeg.Cg and lpeg.Cf and lpeg.Ct) then
|
||||
local set_key = applyObjectKey
|
||||
if options.setObjectKey then
|
||||
local setObjectKey = options.setObjectKey
|
||||
set_key = function(tab, key, val)
|
||||
setObjectKey(tab, key, val)
|
||||
return tab
|
||||
end
|
||||
end
|
||||
|
||||
objectItems = buildItemSequence(objectItem / set_key, ignored)
|
||||
objectItems = lpeg.Ca(lpeg.Cc(false) / initObject * objectItems)
|
||||
-- END LPEG < 0.9 SUPPORT
|
||||
else
|
||||
objectItems = buildItemSequence(lpeg.Cg(objectItem), ignored)
|
||||
objectItems = lpeg.Cf(lpeg.Ct(0) * objectItems, options.setObjectKey or rawset)
|
||||
end
|
||||
|
||||
|
||||
local capture = lpeg.P("{") * ignored
|
||||
capture = capture * objectItems * ignored
|
||||
if options.trailingComma then
|
||||
capture = capture * (lpeg.P(",") + 0) * ignored
|
||||
end
|
||||
capture = capture * lpeg.P("}")
|
||||
return capture
|
||||
end
|
||||
|
||||
function register_types()
|
||||
util.register_type("OBJECT")
|
||||
end
|
||||
|
||||
function load_types(options, global_options, grammar)
|
||||
local capture = buildCapture(options, global_options)
|
||||
local object_id = util.types.OBJECT
|
||||
grammar[object_id] = capture
|
||||
util.append_grammar_item(grammar, "VALUE", lpeg.V(object_id))
|
||||
end
|
||||
Reference in New Issue
Block a user