Skip to content

Instantly share code, notes, and snippets.

@tianchaijz
Created October 30, 2018 07:16
Show Gist options
  • Select an option

  • Save tianchaijz/2d9866b9643e69788b043ba4308ce7cc to your computer and use it in GitHub Desktop.

Select an option

Save tianchaijz/2d9866b9643e69788b043ba4308ce7cc to your computer and use it in GitHub Desktop.
-- https://news.ycombinator.com/item?id=14605922
-- Here's a JSON parser in LPeg, the excellent PEG parser from one of the Lua authors. The function "decode" returns the final, complete tree data structure.
local lpeg = require"lpeg"
local P, S, R, V = lpeg.P, lpeg.S, lpeg.R, lpeg.V
local C, Cc, Cf, Cg, Ct = lpeg.C, lpeg.Cc, lpeg.Cf, lpeg.Cg, lpeg.Ct
local function to8(n)
... -- Lua code to normalize UTF-16 to UTF-8
end
local unicode = P"u" * (R("09", "AF", "af")^4 / to8)
local named = C'"' + C"\\" + C"/" + (P"b" * Cc"\b") + (P"f" * Cc"\f") + (P"n" * Cc"\n") + (P"r" * Cc"\r") + (P"t" * Cc"\t")
local escaped = P"\\" * (named + unicode)
local unescaped = C((P(1) - S'\\"')^1)
local qstring = Ct(P'"' * (unescaped + escaped)^0 * P'"') / table.concat
local exp = S"Ee" * S"-+"^-1 * R"09"^1
local frac = P"." * R"09"^1
local number = (S"-+"^-1 * R"09"^1 * frac^-1 * exp^-1) / tonumber
local boolean = (P"true" * Cc(true)) + (P"false" * Cc(false))
local null = P"null" * Cc(nil)
local space = S" \t\r\n"^0
local JSON = { "Value",
Value = space * (V"Object" + V"Array" + V"Simple") * space,
Object = Cf(Ct"{" * space * Cg(qstring * space * P":" * V"Value" * P","^-1 * space)^0 * P"}", rawset),
Array = Ct(P"[" * space * (V"Value" * P","^-1 * space)^0 * P"]"),
Simple = number + boolean + null + qstring,
}
local function decode(txt)
return lpeg.match(JSON, txt)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment