-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse.np
50 lines (50 loc) · 2.6 KB
/
parse.np
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
grammar = type:$"grammar" rules:rule+ _ eof
rule = type:$"rule" name:ident arglist:argdeflist? _ "=" expr:expr0 eos
expr0 = type:$"choice" args:inter1(expr1, _ "/") / expr1
expr1 = type:$"apply" expr:expr2 !numer code:code_block / expr2
code_block = _ "{" @$code _ "}"
code = (scomm / mcommjs / string / code_block / [^}])*
expr2 = type:$"sequence" args:expr3+ / type:$"eps"
expr3 = type:$"named" name:ident _ ":" expr:expr4
/ _ type:expr3op expr:expr4 / expr4
expr3op = @$"saved" "@" / @$"negcheck" "!" / @$"poscheck" "&"
expr4 = type:$"stringify" _ "$" expr:expr5 / expr5
expr5 = expr:expr6 _ type:expr5op
/ expr:expr6 qty:numer { return qty.expr = expr, qty; } / expr6
expr5op = @$"kleene" "*" / @$"some" "+" / @$"maybe" "?"
numer = _ "{" @numer_range _ "}"
numer_range = type:$"exact" num:number
/ type:$"atleast" from:number _ ","
/ type:$"between" from:number _ "," to:number
expr6 = string / char_class / any_char / rule_ref / braced
char_class = type:$"class" _ "[" negated:("^" { return true; })?
ranges:class_constr* "]" case_insens:ichar
class_constr = type:$"range" from:class_char "-" to:class_char
/ type:$"single" chr:class_char
class_char = escape / [^\]]
any_char = type:$"any" _ "."
rule_ref = type:$"ref" name:ident arglist:arglist? !( _ "=")
braced = _ "(" @expr0 _ ")"
argdeflist = "(" @inter(ident, _ ",") _ ")"
arglist = "(" @inter(expr0, _ ",") _ ")"
number = _ n:[0-9]+ { return parseInt(n, 10); }
string = type:$"strlit" _ text:(string_("'") / string_('"')) case_insens:ichar
string_(sep) = sep a:(escape / !sep @[^\\])* sep { return a.join(""); }
escape = "\\" @(hex_escape / ucode_escape / c_escape / .)
hex_escape = "x" a:$hex{2} { return String.fromCharCode(parseInt(a, 16)); }
ucode_escape = "u" a:$hex{4} { return String.fromCharCode(parseInt(a, 16)); }
c_escape = a:[bfnrtv] { return "\b\f\n\r\t\x0B"["bfnrtv".indexOf(a)]; }
inter(a, b) = a:a b:(b @a)* { return b.unshift(a), b; }
inter1(a, b) = a:a b:(b @a)+ { return b.unshift(a), b; }
hex = [0-9a-f]i
ichar = ("i" { return true; })?
mcomm = "/*" (mcomm / !"*/" .)* "*/"
mcomm_nonl = "/*" (mcomm_nonl / !("*/" / nl) .)* "*/"
mcommjs = "/*" (!"*/" .)* "*/"
scomm = "//" ([^\r\n] .)* (nl / eof)
ident = _ @$([a-zA-Z_][a-zA-Z0-9_]*)
_ = (mcomm / scomm / [ \t] / nl)*
_nonl = (mcomm_nonl / scomm / [ \t])*
nl = "\r" / "\n\r" / "\n"
eos = _nonl nl / _ (";" / eof)
eof = !.