scansion/parser.lua

changeset 0
2e31b584f8d9
child 2
60022b6e0874
--- /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;
+};

mercurial