1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
local function partial(f,x) return function(...) return f(x,...) end end
local function kv_syntax(block,line)
local k,v = line:match"^([a-z0-9_-]+)%s*=%s*(.*)$"
assert(k,"syntax error in kv line: "..line)
k = k:gsub("-","_")
block[k]=v
end
local function tuple_syntax(pattern) return function(block,line)
local matches = {line:match(pattern)}
assert(matches[1], "syntax error in tuple line: "..line)
table.insert(block, matches)
end end
local schema = {
pylon = kv_syntax,
bus = tuple_syntax"^(%S+)%s+(%S+)$",
}
local function parse_file(file)
local blocks = {}
for k in pairs(schema) do blocks[k] = {} end
local line_handler = function() error("line outside of block") end
for line in file:lines() do
line = line:gsub("#.*$",""):gsub("^%s*",""):gsub("%s*$","")
if line == '' then goto next end
local block_type, block_name = line:match"%[%s*(%S+)%s+(%S+)%s*%]"
if block_type then
local blocks_of_this_type = assert(blocks[block_type],"no such block type "..block_type)
local block = {}
blocks_of_this_type[block_name] = block
line_handler = partial(schema[block_type], block)
else
line_handler(line)
end
::next::
end
return blocks
end
return {parse=parse_file}
|