Mehgit add *
This commit is contained in:
commit
09e8eec932
73
alg1.lua
Normal file
73
alg1.lua
Normal file
@ -0,0 +1,73 @@
|
||||
local function stringToTable(str)
|
||||
local function parseValue(s, i)
|
||||
s = s:match("^%s*(.-)%s*$", i) -- Trim leading/trailing spaces
|
||||
i = 1
|
||||
|
||||
if s:sub(1, 1) == "{" then
|
||||
return parseTable(s)
|
||||
elseif s:sub(1, 4) == "true" then
|
||||
return true, 5
|
||||
elseif s:sub(1, 5) == "false" then
|
||||
return false, 6
|
||||
elseif s:sub(1, 3) == "nil" then
|
||||
return nil, 4
|
||||
elseif s:match("^%d+%.?%d*") then
|
||||
local num = tonumber(s:match("^%d+%.?%d*"))
|
||||
return num, #tostring(num) + 1
|
||||
elseif s:sub(1, 1) == '"' or s:sub(1, 1) == "'" then
|
||||
local quote = s:sub(1, 1)
|
||||
local value = ""
|
||||
for i = 2, #s do
|
||||
if s:sub(i, i) == quote and s:sub(i-1, i-1) ~= "\\" then
|
||||
return value, i + 1
|
||||
end
|
||||
value = value .. s:sub(i, i)
|
||||
end
|
||||
error("Unclosed string")
|
||||
else
|
||||
error("Invalid value")
|
||||
end
|
||||
end
|
||||
|
||||
local function parseTable(s)
|
||||
local tbl = {}
|
||||
local i = 2 -- Start after the opening '{'
|
||||
local key = nil
|
||||
|
||||
while i <= #s do
|
||||
if s:sub(i, i) == "}" then
|
||||
return tbl, i + 1
|
||||
elseif s:sub(i, i) == "," then
|
||||
i = i + 1
|
||||
elseif s:sub(i, i) == "[" then
|
||||
local value, next_i = parseValue(s:sub(i + 1))
|
||||
i = i + next_i
|
||||
if s:sub(i, i) ~= "]" then
|
||||
error("Expected closing bracket")
|
||||
end
|
||||
key = value
|
||||
i = i + 1
|
||||
elseif key == nil then
|
||||
local value, next_i = parseValue(s:sub(i))
|
||||
key = value
|
||||
i = i + next_i - 1
|
||||
elseif s:sub(i, i) == "=" then
|
||||
i = i + 1
|
||||
local value, next_i = parseValue(s:sub(i))
|
||||
tbl[key] = value
|
||||
key = nil
|
||||
i = i + next_i - 1
|
||||
else
|
||||
error("Unexpected character: " .. s:sub(i, i))
|
||||
end
|
||||
end
|
||||
error("Unclosed table")
|
||||
end
|
||||
|
||||
local result, _ = parseValue(str)
|
||||
return result
|
||||
end
|
||||
|
||||
function test_string_to_table.s2t1(str)
|
||||
return stringToTable(str)
|
||||
end
|
76
alg2.lua
Normal file
76
alg2.lua
Normal file
@ -0,0 +1,76 @@
|
||||
local function stringToTable(str)
|
||||
local function parseValue(s)
|
||||
s = s:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
|
||||
if s == "nil" then
|
||||
return nil
|
||||
elseif s == "true" then
|
||||
return true
|
||||
elseif s == "false" then
|
||||
return false
|
||||
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)
|
||||
else
|
||||
error("Unrecognized value: " .. s)
|
||||
end
|
||||
end
|
||||
|
||||
local tbl = {}
|
||||
local key, value
|
||||
local inKey = true
|
||||
local depth = 0
|
||||
local buffer = ""
|
||||
|
||||
for i = 1, #str do
|
||||
local char = str:sub(i, i)
|
||||
|
||||
if char == '{' then
|
||||
if depth > 0 then
|
||||
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
|
||||
value = parseValue(buffer)
|
||||
tbl[key] = value
|
||||
end
|
||||
buffer = ""
|
||||
inKey = not inKey
|
||||
|
||||
elseif char == '=' and depth == 1 then
|
||||
key = parseValue(buffer)
|
||||
buffer = ""
|
||||
inKey = false
|
||||
|
||||
else
|
||||
buffer = buffer .. char
|
||||
end
|
||||
|
||||
if depth == 1 and i == #str and buffer ~= "" then
|
||||
value = parseValue(buffer)
|
||||
tbl[key] = value
|
||||
end
|
||||
end
|
||||
|
||||
return tbl
|
||||
end
|
||||
|
||||
function test_string_to_table.s2t2(str)
|
||||
return stringToTable(str)
|
||||
end
|
83
alg3.lua
Normal file
83
alg3.lua
Normal file
@ -0,0 +1,83 @@
|
||||
local function stringToTable(str)
|
||||
local function errorAtPos(msg, pos)
|
||||
error(msg .. " at position " .. pos)
|
||||
end
|
||||
|
||||
local function parseValue(s, i)
|
||||
s = s:match("^%s*(.-)%s*$", i) -- Trim leading/trailing spaces
|
||||
i = 1
|
||||
|
||||
if s:sub(i, i) == "{" then
|
||||
return parseTable(s, i)
|
||||
elseif s:sub(i, i+3) == "true" then
|
||||
return true, i + 4
|
||||
elseif s:sub(i, i+4) == "false" then
|
||||
return false, i + 5
|
||||
elseif s:sub(i, i+2) == "nil" then
|
||||
return nil, i + 3
|
||||
elseif s:match("^%-?%d+%.?%d*[eE]%-?%d+") or s:match("^%-?%d+%.?%d*") then
|
||||
local num = tonumber(s:match("^%-?%d+%.?%d*[eE]%-?%d*"))
|
||||
return num, i + #tostring(num)
|
||||
elseif s:sub(i, i) == '"' or s:sub(i, i) == "'" then
|
||||
local quote = s:sub(i, i)
|
||||
local value = ""
|
||||
i = i + 1
|
||||
while i <= #s do
|
||||
if s:sub(i, i) == quote and s:sub(i-1, i-1) ~= "\\" then
|
||||
return value, i + 1
|
||||
end
|
||||
value = value .. s:sub(i, i)
|
||||
i = i + 1
|
||||
end
|
||||
errorAtPos("Unclosed string", i)
|
||||
else
|
||||
errorAtPos("Invalid value", i)
|
||||
end
|
||||
end
|
||||
|
||||
local function parseTable(s, i)
|
||||
local tbl = {}
|
||||
local key = nil
|
||||
i = i + 1 -- Start after the opening '{'
|
||||
|
||||
while i <= #s do
|
||||
i = i + (s:match("^%s*", i) or 0) -- Skip any whitespace
|
||||
|
||||
if s:sub(i, i) == "}" then
|
||||
return tbl, i + 1
|
||||
elseif s:sub(i, i) == "," then
|
||||
i = i + 1
|
||||
elseif s:sub(i, i) == "[" then
|
||||
key, i = parseValue(s, i + 1)
|
||||
i = i + (s:match("^%s*", i) or 0)
|
||||
if s:sub(i, i) ~= "]" then
|
||||
errorAtPos("Expected closing bracket", i)
|
||||
end
|
||||
i = i + 1
|
||||
elseif key == nil then
|
||||
key, i = parseValue(s, i)
|
||||
elseif s:sub(i, i) == "=" then
|
||||
i = i + 1
|
||||
local value
|
||||
value, i = parseValue(s, i)
|
||||
tbl[key] = value
|
||||
key = nil
|
||||
else
|
||||
errorAtPos("Unexpected character", i)
|
||||
end
|
||||
end
|
||||
errorAtPos("Unclosed table", i)
|
||||
end
|
||||
|
||||
local function preprocess(str)
|
||||
return str:gsub("%s+", " ") -- Replace multiple spaces with a single space
|
||||
end
|
||||
|
||||
str = preprocess(str)
|
||||
local result, _ = parseValue(str, 1)
|
||||
return result
|
||||
end
|
||||
|
||||
function test_string_to_table.s2t3(str)
|
||||
return stringToTable(str)
|
||||
end
|
36
init.lua
Normal file
36
init.lua
Normal file
@ -0,0 +1,36 @@
|
||||
test_string_to_table ={}
|
||||
|
||||
test_string_to_table.modpath = minetest.get_modpath("test_string_to_table") .. DIR_DELIM
|
||||
|
||||
dofile(test_string_to_table.modpath .. "alg1.lua")
|
||||
dofile(test_string_to_table.modpath .. "alg2.lua")
|
||||
dofile(test_string_to_table.modpath .. "alg3.lua")
|
||||
|
||||
local tests = {
|
||||
'{1, 2, 3}',
|
||||
'{a = 1, b = 2, c = 3}',
|
||||
'{a = {b = {c = 3}}}',
|
||||
'{1, "hello", true, false, nil, 3.14}',
|
||||
'{[1] = "one", [2] = "two", ["three"] = 3}',
|
||||
'{"quoted string", \'single quoted\'}',
|
||||
'{nested = {tables = {are = {supported = true}}}}',
|
||||
"{key1 = 123, key2 = true, key3 = {nestedKey1 = 'value1', nestedKey2 = false}}"
|
||||
}
|
||||
|
||||
|
||||
|
||||
local function test(alg)
|
||||
-- alg1
|
||||
local outcome = {}
|
||||
local t1 = minetest.get_us_time()
|
||||
for _, case in ipairs(tests) do
|
||||
local ret = {case, test_string_to_table[alg](case)}
|
||||
table.insert(outcome, ret)
|
||||
end
|
||||
local t2 = minetest.get_us_time()
|
||||
minetest.log("action",alg .. " = " .. (t2-t1))
|
||||
end
|
||||
|
||||
-- test("s2t1")
|
||||
-- test("s2t2")
|
||||
test("s2t3")
|
Loading…
Reference in New Issue
Block a user