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}; |