-
Notifications
You must be signed in to change notification settings - Fork 0
/
quercus.q
58 lines (54 loc) · 1.51 KB
/
quercus.q
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
51
52
53
54
55
56
57
/ quercus: parser combinators for q
\d .qu
ret:{enlist(x;y)};
bind:{raze({(a;s):y;x[a]s}[x]')y@};
map:{bind[(ret x::)]};
trav:{({bind[{map[{raze(x;y)}[y]][x]}[y]]x}/)(x')y};
seqA:trav[::];
zero:{[x]()};
plus:{{x[z],y z}[x;y]};
mget:{enlist(x;x)};
mset:{[x;y]enlist(();x)};
mmod:{enlist(();x y)};
fil:{bind[{(zero;ret y)x y}[x]][y]};
opt:{plus[x;ret()]};
many:{plus[bind[{map[(enlist[z],)]y x}[x;.z.s];x];ret()]};
many1:{bind[{map[(enlist[y],)]many x}[x];x]};
upto:{fil[{x>=count y}[x]]many y};
among:{fil[{(x<=c)&(c:count[z])<=y}[x;y]]many z};
upto:among[0];
times:{$[x<1;ret();seqA x#y]};
sep1:{bind[{map[{enlist[x],y}[z]]many seqr[x;y]}[y;x]]x};
sep:{plus[sep1[x;y];ret()]};
skip:map zero;
item:{$[""~x;();enlist(first x;1_ x)]};
seqf:{bind[{map[{x(y;z)}[x;z]][y]}[x;z]]y};
seql:seqf[first];seqr:seqf[last];seq:seqf[enlist .];
sat:{bind[{$[x y;ret y;zero]}[x];item]};
oneof:{sat in[;x]};
noneof:{sat(not in[;x]::)};
between:{seqr[x;seql[z;y]]};
range:{sat{(x<=z)&z<=y}[x;y]};
digit:range ."09";
lwr:range ."az";
upr:range ."AZ";
letter:plus[lwr;upr];
alphanum:plus[letter;digit];
str:{{$[x~count[x]#y;enlist(x;count[x]_y);()]}[x]};
word:many1 letter;
num:many1 digit;
chr:{[x:`c]sat[(x=)]};
spaces:skip many space:chr" ";
eof:{$[""~x;ret[()]x;zero x]};
eol:chr"\n";
parens:between[chr"(";chr")"];
braces:between[chr"{";chr"}"];
lift:map enlist;
tok:{map(x$)};
(S;D;F;J;T):tok[`],(tok')"DFJT";
c:item;
j:J num;
s:S word;
rparse:{$[()~r:x y;'`parse;1<count r;'`ambig;[(a;s):r 0;not ""~s];'`spare;a]};
vparse:{.[{[x]1b}rparse::;(x;y);0b]};
\d .