ometa ClientURIParser{ word = (letter|``-''|``_'')+:l -> l.join(''), dgit = ^digit:d -> d.digitValue(), nmbr = nmbr:n dgit:d -> (n * 10 + d) | dgit, part = (letter|digit|``-''|``_'')+:l -> l.join(''), parm = part:t (``.'' word:o -> o| -> {f=t;t=[];f}):f (``='' ->`eq|``!=''->`ne|``~'' ->`lk):o part:v ``;''? -> [o,t,f,v], imod = ``del'' | ``add'' | ``view'' | ``edit'' , cmod = ``del'' | ``filt'' | ``sort'' , iact = (``*'' imod:a (``:'' parm+ | -> []):p -> [a].concat(p))+ | -> [] , cact = (``*'' cmod:a (``:'' parm+ | -> []):p -> [a].concat(p))+ | -> [] , cole = part:t cact:s -> [[t]].concat([[`mod].concat(s)]), inst = part:t ``.'' word:f iact:s -> [[t,f]].concat([[`mod].concat([[`filt, [`eq, [], `name, f]]]).concat(s)]), inst = part:t ``.'' nmbr:f iact:s -> [[t,f]].concat([[`mod].concat([[`filt, [`eq, [], `id, f]]]).concat(s)]), inst = part:t iact:s -> [[t]].concat([[`mod].concat(s)]), frbd = (``/''? frag:f -> [f] |``/''? ``('' (frag:g ``,''? -> g)+:r ``)'' -> r |``/''? -> []):f &(end|``/''|``)''|``,'') -> f, frag = cole:w frbd:f -> [`col].concat(w.concat(f)) | inst:w frbd:f -> [`ins].concat(w.concat(f)), expr = ``#!/'' (frag:f end -> f):f -> [`uri, f] | ``'' -> [] } uri0 = '#!/' uri1 = '#!/data/course' uri2 = '#!/data/course/course*add/' //uri3 = '#!/data/course/course*del:name=b*del:name=d/' uri3 = '#!/data/course/(course.1*del,course.math*del)' //uri4 = '#!/data/course/course*del:name=b;id=c*del:name=d/' //uri5 = '#!/data/(course/course*del:name=b;id=c*del:name=d,student)' //uri6 = '#!/data/(course/course*del:name=b;id=c*del:name=d,student/student~is_registered_for~course)' uri6 = '#!/data/(course/course.4*del,student/student~is_registered_for~course)' uri7 = '#!/data/student.John' uri8 = '#!/data/student.134' //uri9 = '#!/data/(course/course*del:name=b;id=c*del:name=d,student.John/student~is_registered_for~course)' uri9 = '#!/data/(course/course.4*del,student.John/student~is_registered_for~course)' //uriA = '#!/data/(course/course*del:name=b;id=c*del:name=d,student.John/student~is_registered_for~course*filt:course.id=19)' //uriB = '#!/data/(course*del:name=b;id=c*del:name=d,student.John*edit:name=Nick/student~is_registered_for~course*filt:course.id=19)' uriC = '#!/data/student.134*del' uriD = '#!/data' uriE = '#!/data/(course/(course.1*del,course.math*del),student)' uriF = '#!/data/(course/(course.provID1*del,course.math*del),student)' uri11 = '' //Converts a tree to a nested list. ometa Prettify { // elem = [{this.d++} (string|elem|number)*:e {s=this.s(this.d--)}] -> ('['+e.join(',\n'+s+' ')+'\n'+s+']') elem = [{this.d++} (string|elem|number)*:e {s=this.s(this.d--)}] -> ('['+e.join(',\n'+s)+']') } Prettify.d = 1 Prettify.s = function(d){a=' ';for(var i=0;i l.join(''), nmbr = number, trans = [:t apply(t):a] -> a, uri trans:t -> ('#!/' + t), name = [word:w nmbr:n] -> (w + '.' + n), name = [word:w word:o] -> (w + '.' + o), name = [word:w] -> (w), col = name:n mod:m trans:t trans+:r {t=[t].concat(r)} -> (n + m + '/(' + t.join(',') + ')'), col = name:n mod:m trans:t -> (n + m + '/' + t), col = name:n mod:m -> (n + m), ins = name:n mod:m trans:t trans+:r {t=[t].concat(r)} -> (n + m + '/(' + t.join(',') + ')'), ins = name:n mod:m trans:t -> (n + m + '/' + t), ins = name:n mod:m -> (n + m), mod = ['mod' actn+:a] -> a.join('') | ['mod'] -> '', actn = (add|filt|del|edit), add = ['add'] -> '*add', del = ['del'] -> '*del', edit = ['edit'] -> '*edit', filt = ['filt' eqi:o] -> '', filt = ['filt' op*:o] -> ('*filt:' + o), op = eq|ne|lk, eqi = ['eq' ([]|word) 'id' nmbr] -> '', eqi = ['eq' ([]|word) 'name' word] -> '', eq = ['eq' ([]|word) word (word|nmbr)], ne = ['ne' ([]|word) word (word|nmbr)], lk = ['lk' ([]|word) word (word|nmbr)] } tree = ClientURIParser.matchAll(uri11,'expr') //tree = ClientURIUnparser.match(["col",["plane"],["mod"],["ins",["plane",1],["mod",["filt",["eq","plane","id",1]]]],["ins",["plane",2],["mod"]]], 'trans') //Prettify.match(["col",["pilot"],["mod"],["ins",["pilot",4],["mod",["filt",["eq",[],"id",4]]]],["ins",["pilot"],["mod",["add"]]]],'elem')