-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconcept.lua
65 lines (51 loc) · 1.36 KB
/
concept.lua
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
require "lpeg"
--[[
Implements the following grammar (meta_g) with higher-order productions
S <- <listof num>
num <- [0-9]+
listof r <- <r> ',' <listof r> / <r>
meta_g is the "uncooked" grammar, obtained by "compiling" the above leg grammar
fix takes an "uncooked" grammar and an initial symbol and cooks it, returning a parser
]]
-- function to synthesize rule names
function make_name(g, name, ...)
local names = { tostring(g), name }
for arg in ipairs{ ... } do names[#names+1] = tostring(arg) end
return table.concat(names, "_")
end
local meta_g = { }
-- listof grammar rule
function meta_g:listof(fix, r)
local name = make_name(self, "listof", r)
if not fix[name] then
fix[name] = true
fix[name] = r(self, fix) * "," * self:listof(fix, r) + r(self, fix)
end
return lpeg.V(name)
end
-- num grammar rule
function meta_g:num(fix)
local name = make_name(self, "num")
if not fix[name] then
fix[name] = true
fix[name] = lpeg.R('09')^1
end
return lpeg.V(name)
end
-- S grammar rule
function meta_g:S(fix)
local name = make_name(self, "S")
if not fix[name] then
fix[name] = true
fix[name] = self:listof(fix, self.num)
end
return lpeg.V(name)
end
function fix_meta(g, s)
local fix_t = {}
fix_t[1] = g[s](g,fix_t)
return lpeg.P(fix_t)
end
local patt = fix_meta(meta_g, "S")
lpeg.print(patt)
print(patt:match("12,34,323"))