aboutsummaryrefslogtreecommitdiff
path: root/parser.lua
diff options
context:
space:
mode:
authorBruce Hill <bitbucket@bruce-hill.com>2018-09-14 14:42:12 -0700
committerBruce Hill <bitbucket@bruce-hill.com>2018-09-14 14:42:20 -0700
commit13ce4e7ee9607aa7c3578af14d0f1f5d51b50287 (patch)
tree31430cf094b0c26ae2961250f1bcf245d131299c /parser.lua
parent31f593fb097fcf31a07fb6e1a5d501904cabcb28 (diff)
Renaming parser2 to parser.
Diffstat (limited to 'parser.lua')
-rw-r--r--parser.lua88
1 files changed, 88 insertions, 0 deletions
diff --git a/parser.lua b/parser.lua
new file mode 100644
index 0000000..0694e3e
--- /dev/null
+++ b/parser.lua
@@ -0,0 +1,88 @@
+local lpeg = require('lpeg')
+local re = require('re')
+lpeg.setmaxstack(20000)
+local P, R, S, C, Cmt, Carg, Cc
+P, R, S, C, Cmt, Carg, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cmt, lpeg.Carg, lpeg.Cc
+local repr
+repr = require('utils').repr
+local DEFS
+do
+ local _with_0 = { }
+ _with_0.nl = P("\r") ^ -1 * P("\n")
+ _with_0.tab = P("\t")
+ _with_0.tonumber = tonumber
+ _with_0.tochar = string.char
+ _with_0.unpack = unpack or table.unpack
+ _with_0["nil"] = Cc(nil)
+ _with_0.userdata = Carg(1)
+ _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"))
+ _with_0.Tree = function(t, userdata)
+ return userdata.make_tree(t, userdata)
+ end
+ DEFS = _with_0
+end
+setmetatable(DEFS, {
+ __index = function(self, key)
+ do
+ local i = key:match("^ascii_(%d+)$")
+ if i then
+ local c = string.char(tonumber(i))
+ self[key] = c
+ return c
+ else
+ do
+ i = key:match("^number_(%d+)$")
+ if i then
+ local p = Cc(tonumber(i))
+ self[key] = p
+ return p
+ end
+ end
+ end
+ end
+ end
+})
+local peg_tidier = re.compile([[file <- %nl* {~ (def/comment) (%nl+ (def/comment))* %nl* ~}
+def <- anon_def / captured_def
+anon_def <-
+ ({ident} (" "*) ":" {[^%nl]* (%nl+ " "+ [^%nl]*)*})
+ -> "%1 <- %2"
+captured_def <-
+ ({ident} (" "*) "(" {ident} ")" (" "*) ":" {[^%nl]* (%nl+ " "+ [^%nl]*)*})
+ -> "%1 <- ({| {:start:{}:} %3 {:stop:{}:} {:type: (''->'%2') :} |} %%userdata) -> Tree"
+ident <- [a-zA-Z_][a-zA-Z0-9_]*
+comment <- "--" [^%nl]*
+]])
+local make_parser
+make_parser = function(peg, make_tree)
+ if make_tree == nil then
+ make_tree = nil
+ end
+ peg = assert(peg_tidier:match(peg))
+ peg = assert(re.compile(peg, DEFS))
+ return function(input, filename)
+ if filename == nil then
+ filename = '???'
+ end
+ input = tostring(input)
+ local tree_mt = {
+ __index = {
+ source = input,
+ filename = filename
+ }
+ }
+ local userdata = {
+ make_tree = make_tree or (function(t)
+ return setmetatable(t, tree_mt)
+ end),
+ filename = filename,
+ source = input
+ }
+ local tree = peg:match(input, nil, userdata)
+ if not tree then
+ error("File " .. tostring(filename) .. " failed to parse:\n" .. tostring(input))
+ end
+ return tree
+ end
+end
+return make_parser