@@ -0,0 +1,115 @@
1+let String = { mempty = ""; mappend = a: b: a + b; };
2+ List = { singleton = x: [x]; };
3+ pair = a: b: { _1 = a; _2 = b; };
4+ Pair = { pure = s: pair String.mempty s;
5+ mappend = a: b: pair (String.mappend a._1 b._1) b._2;
6+ map = f: p: pair (f p._1) p._2;
8+ compose = f: g: x: f (g x);
9+in with builtins; rec {
10+ # Parser a = String -> [(a, String)]
12+ let strL = stringLength str;
14+ in if str == substring 0 strL s
15+ then [ (pair str (substring strL sL s)) ]
18+ regex = capture_groups: re: s:
19+ let result = match "(${re})(.*)" s;
22+ else [ (pair (elemAt result 0) (elemAt result (1 + capture_groups))) ];
28+ else let c = head cs;
38+ then [ (Pair.pure s) ]
43+ then [ (Pair.pure s) ]
44+ else let p = head ps;
49+ else let r = head result;
50+ rest = chain ps' r._2;
53+ else let r' = head rest;
54+ in [ (Pair.mappend r r') ];
56+ idstring = regex 0 "[-\.0-9a-zA-Z]+";
58+ license-ref = let documentref = chain [ (string "DocumentRef-")
63+ (optional documentref)
64+ (string "LicenseRef-")
68+ simple-expression = choice [ license-ref
69+ (chain [ idstring (string "+") ])
73+ compound-expression = let wrap = compose (map (Pair.map List.singleton));
75+ (s: let result = simple-expression s;
78+ else let r = head result;
79+ rest = chain [(string " WITH ") idstring ] r._2;
82+ else [(pair r._1 (head rest)._2)]
84+ (s: let result = simple-expression s;
87+ else let r = head result;
89+ operator = choice [ (string " AND ")
95+ else let s' = (head operator)._2;
96+ licenses = compound-expression s';
99+ else let ls = head licenses;
100+ in [(pair ([firstLicense] ++ ls._1) ls._2)]
102+ (wrap simple-expression)
103+ (s: let openParen = string "(" s;
104+ in if openParen == []
106+ else let result = compound-expression (head openParen)._2;
109+ else let r = head result;
110+ closeParen = string ")" r._2;
111+ in if closeParen == []
113+ else [(pair r._1 (head closeParen)._2)])