12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- -- things between spaces, () separate depths
- local tokenize
- tokenize = function(str)
- if not str then return nil end
- local ast = {}
- local open = str:find("(", 0, true) or math.huge
- local close = str:find(")", 0, true) or math.huge
- local space = str:find(" ", 0, true) or math.huge
- local ret
- if open < close and open < space then
- -- tokenize what came before (call on substring, unpack here), call tokenize on what comes after
- ret = tokenize(str:sub(1, open - 1))
- if ret then
- while #ret > 0 do
- table.insert(ast, table.remove(ret, 1))
- end
- end
- ret, str = tokenize(str:sub(open + 1))
- if ret and #ret > 0 then
- table.insert(ast, ret)
- end
- ret = tokenize(str)
- if ret then
- while #ret > 0 do
- table.insert(ast, table.remove(ret, 1))
- end
- end
- return ast
- elseif close < open and close < space then
- return ast, str:sub(close + 1)
- elseif space < open and space < close then
- ret = str:sub(1, space - 1)
- if ret and #ret > 0 then
- table.insert(ast, ret)
- end
- ret, str = tokenize(str:sub(space + 1))
- if ret and #ret > 0 then
- table.insert(ast, ret)
- end
- ret = tokenize(str)
- if ret then
- while #ret > 0 do
- table.insert(ast, table.remove(ret, 1))
- end
- end
- return ast
- else
- table.insert(ast, str:sub(1, space - 1))
- return ast
- end
- end
-
- local ptable
- ptable = function(tab, depth)
- local str = ""
- depth = depth or 0
- if "table" == type(tab) then
- for k,v in pairs(tab) do
- str = str .. string.rep(" ", depth) .. ptable(k, depth) .. "\n"
- str = str .. string.rep(" ", depth) .. ptable(v, depth + 1) .. "\n"
- end
- else
- return tostring(tab)
- end
- return str
- end
-
- local a = "(echo (: 'value' ($ name)))"
- ast = tokenize(a)
- print(ptable(ast))
|