fix alg1
This commit is contained in:
parent
e9d96b20d9
commit
2a90c58c50
101
alg1.lua
101
alg1.lua
@ -1,4 +1,6 @@
|
||||
local function stringToTable(str)
|
||||
local parseTable -- defined later, but we need it in parseValue
|
||||
|
||||
local function parseValue(s, i)
|
||||
s = s:match("^%s*(.-)%s*$", i) -- Trim leading/trailing spaces
|
||||
i = 1
|
||||
@ -6,57 +8,110 @@ local function stringToTable(str)
|
||||
if s:sub(1, 1) == "{" then
|
||||
return parseTable(s)
|
||||
elseif s:sub(1, 4) == "true" then
|
||||
return true, 5
|
||||
return true, 4
|
||||
elseif s:sub(1, 5) == "false" then
|
||||
return false, 6
|
||||
return false, 5
|
||||
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
|
||||
return nil, 3
|
||||
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
|
||||
if s:sub(i, i) == quote then
|
||||
local j = i - 1
|
||||
local escaped = false
|
||||
while (s:sub(j,j)) == "\\" do
|
||||
escaped = not escaped
|
||||
j = j - 1
|
||||
end
|
||||
if not escaped then
|
||||
value = value:gsub("\\(.)", "%1")
|
||||
return value, i
|
||||
end
|
||||
end
|
||||
value = value .. s:sub(i, i)
|
||||
end
|
||||
error("Unclosed string")
|
||||
end
|
||||
local _, next_i = s:find("^[+-]?%d+%.?%d*[eE][+-]?%d+%s*")
|
||||
if not next_i then
|
||||
_, next_i = s:find("^[+-]?%d+%.?%d*%s*")
|
||||
end
|
||||
if next_i then
|
||||
return tonumber(s:match("^[+-]?%d+%.?%d*[eE][+-]?%d+") or s:match("^([+-]?%d+%.?%d*)")), next_i
|
||||
else
|
||||
print(s)
|
||||
error("Invalid value")
|
||||
end
|
||||
end
|
||||
|
||||
local function parseTable(s)
|
||||
local function parseKey(s, i)
|
||||
s = s:match("^%s*(.-)%s*$", i) -- Trim leading/trailing spaces
|
||||
i = 1
|
||||
if s:find("^[%a_]") then
|
||||
local key = s:match("^[%a%d_]*")
|
||||
if key ~= "true" and key ~= "false" and key ~= "nil" then
|
||||
return key, #key
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function parseTable(s)
|
||||
local tbl = {}
|
||||
local i = 2 -- Start after the opening '{'
|
||||
local key = nil
|
||||
local key, value
|
||||
local value_found -- we cannot check for value, bc {nil} is valid
|
||||
local next_key = 1
|
||||
local next_i
|
||||
|
||||
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
|
||||
|
||||
while i <= #s do
|
||||
if s:sub(i, i) == "}" then
|
||||
return tbl, i + 1
|
||||
elseif s:sub(i, i) == "," then
|
||||
local char = s:sub(i, i)
|
||||
if char == "}" then
|
||||
return tbl, i
|
||||
elseif char == " " then
|
||||
i = i + 1
|
||||
elseif s:sub(i, i) == "[" then
|
||||
local value, next_i = parseValue(s:sub(i + 1))
|
||||
i = i + next_i
|
||||
elseif char == "," or char == ";" then
|
||||
if key ~= nil or (not value_found) then
|
||||
error("value expected")
|
||||
end
|
||||
value_found = false
|
||||
i = i + 1
|
||||
elseif char == "[" then
|
||||
if key ~= nil then
|
||||
error("Expected value, not a key")
|
||||
end
|
||||
key, next_i = parseValue(s:sub(i + 1))
|
||||
i = i + next_i + 1
|
||||
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
|
||||
key, next_i = parseKey(s:sub(i))
|
||||
if not key then -- not a valid key
|
||||
value, next_i = parseValue(s:sub(i))
|
||||
key = getNextKey()
|
||||
tbl[key] = value
|
||||
value_found = true
|
||||
key = nil
|
||||
end
|
||||
i = i + next_i
|
||||
elseif char == "=" then
|
||||
i = i + 1
|
||||
local value, next_i = parseValue(s:sub(i))
|
||||
value, next_i = parseValue(s:sub(i))
|
||||
tbl[key] = value
|
||||
value_found = true
|
||||
key = nil
|
||||
i = i + next_i - 1
|
||||
i = i + next_i + 1
|
||||
else
|
||||
error("Unexpected character: " .. s:sub(i, i))
|
||||
end
|
||||
|
6
init.lua
6
init.lua
@ -13,7 +13,7 @@ local tests = {
|
||||
'{a = {b = {c = 3}}}',
|
||||
'{1, "hello", true, false, nil, 3.14}',
|
||||
'{[1] = "one", [2] = "two", ["three"] = 3}',
|
||||
'{"quoted string", \'single quoted\'}',
|
||||
'{"quoted string with an escaped quote \\"", \'single quoted\'}',
|
||||
'{nested = {tables = {are = {supported = true}}}}',
|
||||
"{key1 = 123, key2 = true, key3 = {nestedKey1 = 'value1', nestedKey2 = false}}",
|
||||
"{}", "{ }",
|
||||
@ -41,13 +41,13 @@ local function test(alg)
|
||||
for _, case in ipairs(tests) do
|
||||
local ret = {case, test_string_to_table[alg](case)}
|
||||
table.insert(outcome, ret)
|
||||
minetest.log(dump(ret))
|
||||
end
|
||||
local t2 = minetest.get_us_time()
|
||||
minetest.log("action",alg .. " = " .. (t2-t1))
|
||||
print(dump(outcome))
|
||||
end
|
||||
|
||||
-- test("s2t1")
|
||||
test("s2t1")
|
||||
test("s2t2")
|
||||
-- test("s2t3")
|
||||
test("s2ttour")
|
Loading…
Reference in New Issue
Block a user