(with_import "./collections.kp" (with_import "./rb.kp" (let ( ; Implementing "Purely Functional GLL Parsing" ; by L. Thomas van Binsbergena, Elizabeth Scott, Adrian Johnstone ; retrived from from http://ltvanbinsbergen.nl/publications/jcola-fgll.pdf ; discriptor is a triple of grammer-slot and 2 indicies of t-string ; corresponding to process ; ; I previously had this as nonterminal, rule-idx, idx into rule, l,r ; U - discriptors added to (worklist?), makes sure no duplicates added to "list" ; P - binary relation between pairs of commencments and right extants ; makes sure that later discoveries that use a sub-non-terminal that has already ; been processed can be completed since the sub-non-terminal won't be ; re-descended at the same index ; ; a commencement is a pair of a nonterminal and a left extent (the arguemnts to ; descend, since that's what we're skipping) to a set of right extants ; G - binary relation between commencments and continuations, modified to include ; actional continuation. ; The normal continuation is a pair of as slot and a left extent. ; So < -> > in G, with a new are is combined to form ; discriptor and BSR whenever k,r are discovered for X ; Note we haven't finished things with the above P, since some subs of the form ; or descriptors that follow them may not have been processed ; yet. When new Right extants are discovered, we must add descriptors ; and to R (if not in U) and add ; BSR elements and to Y ; Y - Our result BSR set! ; I've decided, a slot is [X [stff] int-for-dot] id (lambda (sigma) sigma) altStart (lambda (t s k c) id) altOp (lambda (p q) (lambda (t s k c) (lcompose (p t s k c) (q t s [] k c)))) term_parser (lambda (t [X b i] l k c) (lambda (sigma) (let (this_term (idx b (- i 1)) _ (println "term parser looking for " this_term " at position " k " in " t) ) (if (and (<= (+ k (len this_term)) (len t)) (= this_term (slice t k (+ k (len this_term))))) ((c [[X b i] l (+ (len this_term) k)]) sigma) sigma)))) ; the extra lambda layer of indirection is so that ; recursive nonterminals can be made with rec-let, which ; only works on functions. So both term types get wrapped in ; an extra function which is evaluated in seqOp and parse term (lambda (s) (lambda () [ s term_parser ])) continue (lambda (BSR_element c) (lambda ([U G P Y]) (let ( [slot l k r] BSR_element descriptor [slot l r] (X b i) slot Yp (if (or (!= 0 i) (= (len rhs) i)) (set-insert Y BSR_element) Y) Up (set-insert U descriptor) ) (if (set-contains? U descriptor) [U G P Yp] ((c descriptor) [Up G P Yp]))))) seqStart (lambda (t X b l c0) (continue [[X b 0] l l l] c0)) seqOp (lambda (p s_q) (lambda (t X b l c0) (let ( ; see term discussion about extra lambda wrap [s q] (s_q) c1 (lambda ([[X b i] l k]) (let ( c2 (lambda ([slot l r]) (continue [slot l k r] c0)) ) (q t [X b (+ 1 i)] l k c2))) ) (p t X (cons s b) l c1)))) cont_for (lambda (s p) (lambda ([[s d i] k r]) (lambda ([U G P Y]) (let ( composed (set-foldl (lambda (cp [g l c]) (lcompose cp (c [g l r]))) id (multimap-get G [s k])) ) (composed [U G (multimap-insert P [s k] r) Y]))))) nterm_parser (lambda (p) (lambda (t gram_slot l k c) (lambda ([U G P Y]) (let ( [X b i] gram_slot s (idx b (- i 1)) R (multimap-get P [s k]) sigmap [U (multimap-insert G [s k] [gram_slot l c]) P Y] ) (if (= 0 (size R)) ((p t s k (cont_for s p)) sigmap) (set-foldl (lambda (cp r) (lcompose cp (c [gram_slot l r]))) id R) ))))) ; see term discussion about extra lambda wrap nterm (lambda (s p) (lambda () [ s (nterm_parser p) ])) parse (lambda (s_f) (lambda (t) (let ( ; see term discussion about extra lambda wrap [s f] (s_f) X '__FUNGLL_UNIQUE_START_SYMBOL__ sigma [ set-empty multimap-empty multimap-empty set-empty ] c (lambda (descriptor) (lambda (sigma) sigma)) [U G P Y] ((f t ['X [s] 1] 0 0 c) sigma) ) (set-foldl cons [] Y)))) ) (provide altStart altOp term seqStart seqOp nterm parse) )))