--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scansion/parser.lua Sat Sep 05 14:42:23 2015 +0100 @@ -0,0 +1,57 @@ +local function parse(data) + local parsed = { + objects = {}; + actions = {}; + }; + + local line_number = 0; + local last_object; + + for line in data:gmatch("([^\r\n]+)\r?\n") do + line_number = line_number + 1; + print(line_number, line); + if line:sub(1,1) == "[" then + local obj_type, name, extra = line:match("^%[(%a+)%] (.+)$"); + + if parsed.objects[name] then + return nil, "Duplicate definition of "..name.." on line "..line_number; + end + parsed.objects[name] = { + type = obj_type:lower(); + name = name; + defined_line = line_number; + }; + last_object = parsed.objects[name]; + print(("%q"):format(obj_type)) + elseif line:match("^%s+%a+:.+$") then + if not last_object then + return nil, "Line "..line_number.. "unexpected outside of an object definition"; + end + local k, v = line:match("^%s+(%a+):(.+)$") + last_object[k] = v; + elseif #parsed.actions > 0 and line:sub(1,1) == "\t" then + table.insert(parsed.actions[#parsed.actions].extra, line:sub(2)); + elseif line:match("^%s*$") or line:match("^#") or line:match("^([/-])%1") then + -- Blank line or comment + else + last_object = nil; + local name, action, extra = line:match("^(%a+) (%a+):?%s?(.*)$"); + if not name then + return nil, "Unable to parse action on line "..line_number; + end + if not parsed.objects[name] then + return nil, "The object '"..name.."' used on line "..line_number.." was not declared"; + end + table.insert(parsed.actions, { + object_name = name; + action = action:lower(); + extra = {#extra>0 and extra or nil}; + }); + end + end + return parsed; +end + +return { + parse = parse; +};