diff options
| author | Bruce Hill <bitbucket@bruce-hill.com> | 2018-09-14 14:00:48 -0700 |
|---|---|---|
| committer | Bruce Hill <bitbucket@bruce-hill.com> | 2018-09-14 14:01:07 -0700 |
| commit | 7c1f2dfd69afe119322e19b3a4061876b3dd1033 (patch) | |
| tree | ee540007cdad2681b03a208c657811591da58cc9 /parser.lua | |
| parent | 4d48bf359df98512a2a741d48ea222d055b733c0 (diff) | |
Fixes and improvements, and ported nomsu.3.peg to new tidier syntax.
Diffstat (limited to 'parser.lua')
| -rw-r--r-- | parser.lua | 119 |
1 files changed, 1 insertions, 118 deletions
@@ -113,126 +113,9 @@ setmetatable(NOMSU_DEFS, { end }) local Parser = { - version = 3, + version = 4, patterns = { } } -do - local peg_tidier = re.compile([[ file <- %nl* {~ (def/comment) (%nl+ (def/comment))* %nl* ~} - def <- anon_def / captured_def - anon_def <- ({ident} (" "*) ":" - {~ ((%nl " "+ def_line?)+) / def_line ~}) -> "%1 <- %2" - captured_def <- ({ident} (" "*) "(" {ident} ")" (" "*) ":" - {~ ((%nl " "+ def_line?)+) / def_line ~}) -> "%1 <- (({} {| %3 |} {} %%userdata) -> %2)" - def_line <- (err / [^%nl])+ - err <- ("(!!" { (!("!!)") .)* } "!!)") -> "(({} (%1) %%userdata) => error)" - ident <- [a-zA-Z_][a-zA-Z0-9_]* - comment <- "--" [^%nl]* - ]]) - for version = 1, Parser.version do - local peg_file = io.open("nomsu." .. tostring(version) .. ".peg") - if not peg_file and package.nomsupath then - for path in package.nomsupath:gmatch("[^;]+") do - peg_file = io.open(path .. "/nomsu." .. tostring(version) .. ".peg") - if peg_file then - break - end - end - end - assert(peg_file, "could not find nomsu .peg file") - local nomsu_peg = peg_tidier:match(peg_file:read('*a')) - peg_file:close() - Parser.patterns[version] = re.compile(nomsu_peg, NOMSU_DEFS) - end -end -local _anon_chunk = 0 -Parser.parse = function(nomsu_code, source, version) - if source == nil then - source = nil - end - if version == nil then - version = nil - end - source = source or nomsu_code.source - nomsu_code = tostring(nomsu_code) - if not (source) then - source = Source("anonymous chunk #" .. tostring(_anon_chunk), 1, #nomsu_code) - _anon_chunk = _anon_chunk + 1 - end - version = version or nomsu_code:match("^#![^\n]*nomsu[ ]+-V[ ]*([0-9.]+)") - local syntax_version = version and tonumber(version:match("^[0-9]+")) or Parser.version - local userdata = { - errors = { }, - source = source, - comments = { } - } - local tree = Parser.patterns[syntax_version]:match(nomsu_code, nil, userdata) - if not tree or type(tree) == 'number' then - error("In file " .. tostring(colored.blue(tostring(source or "<unknown>"))) .. " failed to parse:\n" .. tostring(colored.onyellow(colored.black(nomsu_code)))) - end - if next(userdata.errors) then - local keys - do - local _accum_0 = { } - local _len_0 = 1 - for k, v in pairs(userdata.errors) do - _accum_0[_len_0] = k - _len_0 = _len_0 + 1 - end - keys = _accum_0 - end - table.sort(keys) - local errors - do - local _accum_0 = { } - local _len_0 = 1 - for _index_0 = 1, #keys do - local k = keys[_index_0] - _accum_0[_len_0] = userdata.errors[k] - _len_0 = _len_0 + 1 - end - errors = _accum_0 - end - error("Errors occurred while parsing (v" .. tostring(syntax_version) .. "):\n\n" .. table.concat(errors, "\n\n"), 0) - end - local comments - do - local _accum_0 = { } - local _len_0 = 1 - for p, c in pairs(userdata.comments) do - _accum_0[_len_0] = { - comment = c, - pos = p - } - _len_0 = _len_0 + 1 - end - comments = _accum_0 - end - table.sort(comments, function(a, b) - return a.pos > b.pos - end) - local comment_i = 1 - local walk_tree - walk_tree = function(t) - local comment_buff = { } - while comments[#comments] and comments[#comments].pos <= t.source.start do - table.insert(comment_buff, table.remove(comments)) - end - for _index_0 = 1, #t do - local x = t[_index_0] - if AST.is_syntax_tree(x) then - walk_tree(x) - end - end - while comments[#comments] and comments[#comments].pos <= t.source.stop do - table.insert(comment_buff, table.remove(comments)) - end - if #comment_buff > 0 then - t.comments = comment_buff - end - end - walk_tree(tree) - return tree -end Parser.is_operator = function(s) return not not (NOMSU_DEFS.operator_char ^ 1 * -1):match(s) end |
