scansion/parser.lua

changeset 162
f888f236321f
parent 160
28aa762f11c7
child 163
0e2150680a25
equal deleted inserted replaced
161:fadae5511044 162:f888f236321f
7 7
8 local line_number = 0; 8 local line_number = 0;
9 local last_object; 9 local last_object;
10 local annotation; 10 local annotation;
11 11
12 local function parse_error(text)
13 return nil, text .. " (line " .. line_number .. ")";
14 end
15
12 for line in data:gmatch("([^\r\n]*)\r?\n") do 16 for line in data:gmatch("([^\r\n]*)\r?\n") do
13 line_number = line_number + 1; 17 line_number = line_number + 1;
14 if line:sub(1,1) == "[" then 18 if line:sub(1,1) == "[" then
15 local obj_type, name = line:match("^%[(%a+)%] (.+)$"); 19 local obj_type, name = line:match("^%[(%a+)%] (.+)$");
16 20
17 if parsed.objects[name] then 21 if parsed.objects[name] then
18 return nil, "Duplicate definition of "..name.." on line "..line_number; 22 return parse_error("Duplicate definition of '"..name.."'");
19 end 23 end
20 parsed.objects[name] = { 24 parsed.objects[name] = {
21 type = obj_type:lower(); 25 type = obj_type:lower();
22 name = name; 26 name = name;
23 defined_line = line_number; 27 defined_line = line_number;
24 }; 28 };
25 last_object = parsed.objects[name]; 29 last_object = parsed.objects[name];
26 elseif line:match("^%s+[%a_]+:.+$") then 30 elseif line:match("^%s+[%a_]+:.+$") then
27 if not last_object then 31 if not last_object then
28 return nil, "Line "..line_number.. "unexpected outside of an object definition"; 32 return parse_error("Unexpected outside of an object definition");
29 end 33 end
30 local k, v = line:match("^%s+([%a_]+):%s*(.+)$") 34 local k, v = line:match("^%s+([%a_]+):%s*(.+)$")
31 last_object[k] = v; 35 last_object[k] = v;
32 elseif #parsed.actions > 0 and line:sub(1,1) == "\t" then 36 elseif #parsed.actions > 0 and line:sub(1,1) == "\t" then
33 table.insert(parsed.actions[#parsed.actions].extra, line:sub(2)); 37 table.insert(parsed.actions[#parsed.actions].extra, line:sub(2));
67 end 71 end
68 else 72 else
69 last_object = nil; 73 last_object = nil;
70 local name, action, extra = line:match("^([^:]+) (%a+):?%s?(.*)$"); 74 local name, action, extra = line:match("^([^:]+) (%a+):?%s?(.*)$");
71 if not name then 75 if not name then
72 return nil, "Unable to parse action on line "..line_number; 76 return parse_error("Unable to parse action");
73 end 77 end
74 if not parsed.objects[name] then 78 if not parsed.objects[name] then
75 return nil, "The object '"..name.."' used on line "..line_number.." was not declared"; 79 return parse_error("The object '"..name.."' was not declared");
76 end 80 end
77 table.insert(parsed.actions, { 81 table.insert(parsed.actions, {
78 object_name = name; 82 object_name = name;
79 action = action:lower(); 83 action = action:lower();
80 extra = {#extra>0 and extra or nil}; 84 extra = {#extra>0 and extra or nil};

mercurial