lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


2017-04-17 9:02 GMT+02:00 Marc Balmer <marc@msys.ch>:
>
>
> Am 17.04.17 um 08:47 schrieb Dirk Laurie:
>> My primitive JSON decoder, which operates by lexically translating
>> a JSON code to a Lua table literal, now does three things:
>>
>> 1. Unicode codepoints translated, e.g. from \u00e9 to \u{00e9}.
>> 2. List delimiters translated from […] to {…}.
>> 3. Keys translated e.g. from "item": to ["item"]=.
>>
>> local function json_decode (s)
>>   s = s:gsub("\\u(%d%d%d%d)","\\u{%1}")
>>   local function do_json_list(s,is_list)
>>     if is_list then s = s:sub(2,-2) end
>>     s = s:gsub("(%b[])()",do_json_list)
>>     if is_list then s = '{' .. s ..'}' end
>>     return s
>>   end
>>   local t = load('return '..do_json_list(s):gsub('("[%w_-]-"):','[%1]='))
>>   if t then return t() else return s end
>> end

First: thanks for giving me the opportunity for correcting an error
(the code was correct in the interpreter but not yet in the Lua source).
The first line should be

    s = s:gsub("\\u(%x%x%x%x)","\\u{%1}")

>>
>> Please show me some sample JSON code that this decoder can't handle
>> properly.
>
> Does it decode numbers to lua numbers?  Does it handle numeric subtypes?

Yes and yes, because Lua does. The three steps are for example:

    [{"list": [1], "array":{"utf8": "\u00e9", "next": null}}]
    [{"list": [1], "array":{"utf8": "\u{00e9}", "next": null}}]
    {{"list": {1}, "array":{"utf8": "\u{00e9}", "next": null}}}
    {{["list"]= {1}, ["array"] = {["utf8"]= "\u{00e9}", ["next"]= null}}}

>> I already know about:
>>   1. Integer overflow. (Thanks, Sean!) --> won't happen
>>   2. JSON null is not Lua nil. --> define a suitable global called 'null'
>
> I let the used choose how JSON null values are to be handled (see
> https://github.com/arcapos/luajson/blob/master/luajson.c), it can either
> map to a json-null object (which has a json-null metatable), to nil, or
> to an empty string.  You could reuse that idea in above code.

I think that defining a global 'null' takes care of all three possibilities.

BTW both cjson (light userdata) and rapidjson (function) provide
unique immutable null objects that cannot have their own metatable,