1 local lpeg = require('lpeg')
2 local re = require('re')
3 lpeg.setmaxstack(20000)
4 local P, R, S, C, Cmt, Carg, Cc
5 P, R, S, C, Cmt, Carg, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cmt, lpeg.Carg, lpeg.Cc
8 local inner = select(1, ...)
9 for i = 2, select('#', ...) do
11 local outer = select(i, ...)
12 table.insert(outer, 1, inner)
13 outer.source.start = inner.source.start
22 _with_0.nl = P("\r") ^ -1 * P("\n")
24 _with_0.at_break = lpeg.B(lpeg.S(";,. \r\n\t({[")) + -lpeg.B(1)
25 _with_0.tonumber = tonumber
26 _with_0.tochar = string.char
27 _with_0.unpack = unpack or table.unpack
28 _with_0["nil"] = Cc(nil)
29 _with_0.userdata = Carg(1)
30 _with_0.indentation = lpeg.Cmt(P(0), function(s, i)
31 local sub = string.sub
32 while i > 1 and sub(s, i - 1, i - 1) ~= '\n' do
35 return true, (s:match("^ *", i))
37 _with_0.utf8_char = (R("\194\223") * R("\128\191") + R("\224\239") * R("\128\191") * R("\128\191") + R("\240\244") * R("\128\191") * R("\128\191") * R("\128\191"))
38 _with_0.operator_char = S("#'`~@^&*+=<>?/%!|\\-") + (P("\xE2") * (R("\x88\x8B") + R("\xA8\xAB")) * R("\128\191"))
39 _with_0.Tree = function(t, userdata)
40 return userdata.make_tree(t, userdata)
46 __index = function(self, key)
48 local i = key:match("^ascii_(%d+)$")
50 local c = string.char(tonumber(i))
55 i = key:match("^number_(%d+)$")
57 local p = Cc(tonumber(i))
66 local peg_tidier = re.compile([[ file <- %nl* {~ (captured_def/line) (%nl+ (captured_def/line))* %nl* ~}
67 ident <- [a-zA-Z_][a-zA-Z0-9_]*
70 ({ident} (" "*) "(" {ident} ")" (" "*) "<-" {[^%nl]* (%nl+ " "+ [^%nl]*)*}) ->
71 "%1 <- ({| {:type:''->'%2':} {:start:{}:}
73 {:stop:{}:} |} %%userdata) -> Tree"
76 make_parser = function(peg, make_tree)
77 if make_tree == nil then
80 peg = assert(peg_tidier:match(peg))
81 peg = assert(re.compile(peg, DEFS))
82 return function(input, filename)
83 if filename == nil then
86 input = tostring(input)
94 make_tree = make_tree or (function(t)
95 return setmetatable(t, tree_mt)
100 local tree = peg:match(input, nil, userdata)
101 if not tree or type(tree) == 'number' then
102 error("File " .. tostring(filename) .. " failed to parse:\n" .. tostring(input))