diff options
Diffstat (limited to 'nomnom/parser.nom')
| -rw-r--r-- | nomnom/parser.nom | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/nomnom/parser.nom b/nomnom/parser.nom new file mode 100644 index 0000000..fe237e8 --- /dev/null +++ b/nomnom/parser.nom @@ -0,0 +1,91 @@ +#!/usr/bin/env nomsu -V4.8.10 +# This file contains the parser, which converts text into abstract syntax trees +#use "nomonom/ast.nom" +%lpeg = (=lua "require('lpeg')") +%re = (=lua "require('re')") +call %lpeg.setmaxstack with [20000] +set {..} + ((P 1)'s meaning):%lpeg.P, ((R 1)'s meaning):%lpeg.R + ((Carg 1)'s meaning):%lpeg.Carg, ((S 1)'s meaning):%lpeg.S + ((Cc 1)'s meaning):%lpeg.Cc, ((lpeg re pattern 1)'s meaning):%re.compile + ((lpeg re pattern 1 using 2)'s meaning):%re.compile + ((lpeg pattern 1's match of 2)'s meaning):%lpeg.match + ((lpeg pattern 1's match of 2 with 3)'s meaning): (..) + [%1, %2, %3] -> (call %lpeg.match with [%1, %2, nil, %3]) + +%source_code_for_tree = {} +%defs = (..) + {..} + nl: (P "\r")^(-1) * (P "\n") + tab: P "\t" + tonumber: %tonumber + tochar: %string.char + unpack: %unpack + nil: Cc (nil) + userdata: Carg 1 + 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") + + Tree: [%t, %userdata] ->: + %source = (..) + Source {filename:%userdata.filename, start:%t.start, stop:%t.stop} + set {%t.start: nil, %t.stop: nil, %t.source: %source} + %t = (a Syntax Tree with %t) + (Syntax Tree).source_code_for_tree.%t = %userdata.source + return %t + ..with fallback %key ->: + if: + (%key::matches "^ascii_(%d+)$"): + %i = (%key::matching "^ascii_(%d+)$") + return (call %string.char with [%i as a number]) + + (%key::matches "^number_(%d+)$"): + %i = (%key::matching "^number_(%d+)$") + return (Cc (%i as a number)) + +%id_patt = (..) + ((P "") - (R "09")) * (..) + (%defs.utf8_char + (R "az") + (R "AZ") + (P "_") + (R "09")) ^ 1 * -1 + +%operator_patt = ((S "'`~!@$^&*+=|<>?/-") ^ 1 * -1) +externally [%text is a nomsu id, %text is a nomsu identifier] all mean (..) + lpeg pattern %id_patt's match of %text + +externally (%text is a nomsu operator) means (..) + lpeg pattern %operator_patt's match of %text + +%peg_tidier = (..) + lpeg re pattern "\ + ..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]* + " + +externally (make parser from %peg) means (make parser from %peg using (nil)) +externally (make parser from %peg using %make_tree) means: + %peg = (lpeg pattern %peg_tidier's match of %peg) + %peg = (lpeg re pattern %peg using %defs) + (%input from %filename parsed) means: + %input = "\%input" + %tree_mt = {__index:{source:%input, filename:%filename}} + %userdata = {..} + make_tree:%make_tree or ([%] -> (: set %'s metatable to %tree_mt; return %)) + filename:%filename, source:%input + + %tree = (lpeg pattern %peg's match of %input with %userdata) + assume %tree or barf "\ + ..File \%filename failed to parse: + \%input" + + return %tree + + return ((1 from 2 parsed)'s meaning) |
