fix alg2
This commit is contained in:
parent
c0aaedae59
commit
e9d96b20d9
91
alg2.lua
91
alg2.lua
@ -1,4 +1,26 @@
|
||||
local function stringToTable(str)
|
||||
-- based on https://www.lua.org/pil/20.4.html
|
||||
local function code(s)
|
||||
-- mask all escaped characters
|
||||
return s:gsub("\\(.)", function (c)
|
||||
return string.format("\\%03d", string.byte(c))
|
||||
end):gsub("([\"'])(.-)%1", function (_, match) -- detect all strings
|
||||
return "'" .. match:gsub("([,;{}%[%]=])", function (c)
|
||||
return string.format("\\%03d", string.byte(c))
|
||||
end) .. "'"
|
||||
end)
|
||||
end
|
||||
|
||||
local function decode(s)
|
||||
return s:gsub("\\(%d%d%d)", function (d)
|
||||
return string.char(d)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
local function codedStringToTable(str)
|
||||
-- special case: hadle empty tables (our parser would break here)
|
||||
if str:find("^{%s*}$") then return {} end
|
||||
|
||||
local function parseValue(s)
|
||||
s = s:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
|
||||
@ -11,20 +33,41 @@ local function stringToTable(str)
|
||||
elseif tonumber(s) then
|
||||
return tonumber(s)
|
||||
elseif s:match("^\".*\"$") or s:match("^'.*'$") then
|
||||
return s:sub(2, -2):gsub("\\(.)", "%1") -- handle escape sequences
|
||||
elseif s:match("^%b{}$") then
|
||||
return stringToTable(s)
|
||||
return decode(s:sub(2, -2))
|
||||
elseif s:match("^{.*}$") then
|
||||
return codedStringToTable(s)
|
||||
else
|
||||
error("Unrecognized value: " .. s)
|
||||
end
|
||||
end
|
||||
|
||||
local function parseKey(s)
|
||||
s = s:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
if s:match("^%[(.*)%]$") then
|
||||
return parseValue(s:match("^%[(.*)%]$"))
|
||||
elseif s:find("^[%a_][%a%d_]*$") then -- make sure the string is a valid lua identifier
|
||||
return s
|
||||
else
|
||||
error("Unrecognized key: " .. s)
|
||||
end
|
||||
end
|
||||
|
||||
local tbl = {}
|
||||
local key, value
|
||||
local next_key = 1
|
||||
local inKey = true
|
||||
local depth = 0
|
||||
local buffer = ""
|
||||
|
||||
local function getNextKey()
|
||||
while tbl[next_key] ~= nil do
|
||||
next_key = next_key + 1
|
||||
end
|
||||
key = next_key
|
||||
next_key = next_key + 1
|
||||
return key
|
||||
end
|
||||
|
||||
for i = 1, #str do
|
||||
local char = str:sub(i, i)
|
||||
|
||||
@ -33,44 +76,44 @@ local function stringToTable(str)
|
||||
buffer = buffer .. char
|
||||
end
|
||||
depth = depth + 1
|
||||
|
||||
elseif char == '}' then
|
||||
depth = depth - 1
|
||||
if depth > 0 then
|
||||
buffer = buffer .. char
|
||||
elseif depth == 0 and buffer ~= "" then
|
||||
value = buffer
|
||||
buffer = ""
|
||||
end
|
||||
|
||||
elseif char == ',' and depth == 1 then
|
||||
if inKey then
|
||||
key = parseValue(buffer)
|
||||
else
|
||||
elseif depth == 0 and not buffer:find("^%s*$") then
|
||||
value = parseValue(buffer)
|
||||
tbl[key] = value
|
||||
buffer = ""
|
||||
end
|
||||
elseif (char == ',' or char == ";") and depth == 1 then
|
||||
value = parseValue(buffer)
|
||||
if key == nil then
|
||||
key = getNextKey()
|
||||
end
|
||||
buffer = ""
|
||||
inKey = not inKey
|
||||
|
||||
tbl[key] = value
|
||||
key, value = nil, nil
|
||||
buffer = ""
|
||||
elseif char == '=' and depth == 1 then
|
||||
key = parseValue(buffer)
|
||||
key = parseKey(buffer)
|
||||
buffer = ""
|
||||
inKey = false
|
||||
|
||||
else
|
||||
buffer = buffer .. char
|
||||
end
|
||||
end
|
||||
|
||||
if depth == 1 and i == #str and buffer ~= "" then
|
||||
value = parseValue(buffer)
|
||||
if key == nil then
|
||||
key = getNextKey()
|
||||
end
|
||||
tbl[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function stringToTable(str)
|
||||
str = code(str)
|
||||
return codedStringToTable(str)
|
||||
end
|
||||
|
||||
function test_string_to_table.s2t2(str)
|
||||
return stringToTable(str)
|
||||
end
|
4
init.lua
4
init.lua
@ -22,7 +22,7 @@ local tests = {
|
||||
'{[-42.42e42] = 42.42E-42}',
|
||||
'{1, 2, 3, }',
|
||||
-- invalid tables, the code should return an error
|
||||
-- --[[
|
||||
--[[
|
||||
"{a = 1",
|
||||
"{'unclosed string\\'}",
|
||||
"{invalid key = 3}",
|
||||
@ -48,6 +48,6 @@ local function test(alg)
|
||||
end
|
||||
|
||||
-- test("s2t1")
|
||||
-- test("s2t2")
|
||||
test("s2t2")
|
||||
-- test("s2t3")
|
||||
test("s2ttour")
|
Loading…
Reference in New Issue
Block a user