Tue, 27 Oct 2015 23:08:48 +0000
parser, objects.client: Experimental support for more liberal object names
local function parse(data) local parsed = { objects = {}; actions = {}; }; local line_number = 0; local last_object; local annotation; for line in data:gmatch("([^\r\n]*)\r?\n") do line_number = line_number + 1; 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]; 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+):%s*(.+)$") 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, save as annotation if #line == 0 then if annotation then annotation.closed = true; end else if (not annotation) or annotation.closed then annotation = { line }; else table.insert(annotation, line); end end else last_object = nil; local name, action, extra = line:match("^([^:]+) (%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}; annotation = annotation and table.concat(annotation, "\n") or nil; }); annotation = nil; end end return parsed; end return { parse = parse; };