blob: f34335ce9ae485729baba24a78376ffd652f4750 [file] [log] [blame]
--[[
Licensed according to the included 'LICENSE' document
Author: Thomas Harning Jr <harningt@gmail.com>
]]
local lpeg = require("lpeg")
local select = select
local pairs, ipairs = pairs, ipairs
local tonumber = tonumber
local string_char = require("string").char
local rawset = rawset
local error = error
local setmetatable = setmetatable
module("json.decode.util")
-- 09, 0A, 0B, 0C, 0D, 20
ascii_space = lpeg.S("\t\n\v\f\r ")
do
local chr = string_char
local u_space = ascii_space
-- \u0085 \u00A0
u_space = u_space + lpeg.P(chr(0xC2)) * lpeg.S(chr(0x85) .. chr(0xA0))
-- \u1680 \u180E
u_space = u_space + lpeg.P(chr(0xE1)) * (lpeg.P(chr(0x9A, 0x80)) + chr(0xA0, 0x8E))
-- \u2000 - \u200A, also 200B
local spacing_end = ""
for i = 0x80,0x8b do
spacing_end = spacing_end .. chr(i)
end
-- \u2028 \u2029 \u202F
spacing_end = spacing_end .. chr(0xA8) .. chr(0xA9) .. chr(0xAF)
u_space = u_space + lpeg.P(chr(0xE2, 0x80)) * lpeg.S(spacing_end)
-- \u205F
u_space = u_space + lpeg.P(chr(0xE2, 0x81, 0x9F))
-- \u3000
u_space = u_space + lpeg.P(chr(0xE3, 0x80, 0x80))
-- BOM \uFEFF
u_space = u_space + lpeg.P(chr(0xEF, 0xBB, 0xBF))
_M.unicode_space = u_space
end
identifier = lpeg.R("AZ","az","__") * lpeg.R("AZ","az", "__", "09") ^0
hex = lpeg.R("09","AF","af")
hexpair = hex * hex
comments = {
cpp = lpeg.P("//") * (1 - lpeg.P("\n"))^0 * lpeg.P("\n"),
c = lpeg.P("/*") * (1 - lpeg.P("*/"))^0 * lpeg.P("*/")
}
comment = comments.cpp + comments.c
ascii_ignored = (ascii_space + comment)^0
unicode_ignored = (unicode_space + comment)^0
local types = setmetatable({false}, {
__index = function(self, k)
error("Unknown type: " .. k)
end
})
function register_type(name)
types[#types + 1] = name
types[name] = #types
return #types
end
_M.types = types
function append_grammar_item(grammar, name, capture)
local id = types[name]
local original = grammar[id]
if original then
grammar[id] = original + capture
else
grammar[id] = capture
end
end
-- Parse the lpeg version skipping patch-values
-- LPEG <= 0.7 have no version value... so 0.7 is value
DecimalLpegVersion = lpeg.version and tonumber(lpeg.version():match("^(%d+%.%d+)")) or 0.7
function get_invalid_character_info(input, index)
local parsed = input:sub(1, index)
local bad_character = input:sub(index, index)
local _, line_number = parsed:gsub('\n',{})
local last_line = parsed:match("\n([^\n]+.)$") or parsed
return line_number, #last_line, bad_character, last_line
end
function setObjectKeyForceNumber(t, key, value)
key = tonumber(key) or key
return rawset(t, key, value)
end