|
|
@ -7,7 +7,8 @@
|
|
|
|
"grammar.ss"
|
|
|
|
"grammar.ss"
|
|
|
|
"graph.ss"
|
|
|
|
"graph.ss"
|
|
|
|
"array2d.ss"
|
|
|
|
"array2d.ss"
|
|
|
|
(lib "list.ss"))
|
|
|
|
(lib "list.ss")
|
|
|
|
|
|
|
|
(lib "class.ss"))
|
|
|
|
|
|
|
|
|
|
|
|
(provide compute-LA)
|
|
|
|
(provide compute-LA)
|
|
|
|
|
|
|
|
|
|
|
@ -16,33 +17,34 @@
|
|
|
|
;; which can transition out of the resulting state
|
|
|
|
;; which can transition out of the resulting state
|
|
|
|
(define (compute-DR a g)
|
|
|
|
(define (compute-DR a g)
|
|
|
|
(lambda (tk)
|
|
|
|
(lambda (tk)
|
|
|
|
(let ((r (run-automaton (trans-key-st tk) (trans-key-gs tk) a)))
|
|
|
|
(let ((r (send a run-automaton (trans-key-st tk) (trans-key-gs tk))))
|
|
|
|
(term-list->bit-vector
|
|
|
|
(term-list->bit-vector
|
|
|
|
(filter
|
|
|
|
(filter
|
|
|
|
(lambda (term)
|
|
|
|
(lambda (term)
|
|
|
|
(run-automaton r term a))
|
|
|
|
(send a run-automaton r term))
|
|
|
|
(grammar-terms g))))))
|
|
|
|
(grammar-terms g))))))
|
|
|
|
|
|
|
|
|
|
|
|
;; compute-reads:
|
|
|
|
;; compute-reads:
|
|
|
|
;; LR0-automaton * grammar -> (trans-key -> trans-key list)
|
|
|
|
;; LR0-automaton * grammar -> (trans-key -> trans-key list)
|
|
|
|
(define (compute-reads a g)
|
|
|
|
(define (compute-reads a g)
|
|
|
|
(lambda (tk)
|
|
|
|
(lambda (tk)
|
|
|
|
(let ((r (run-automaton (trans-key-st tk) (trans-key-gs tk) a)))
|
|
|
|
(let ((r (send a run-automaton (trans-key-st tk) (trans-key-gs tk))))
|
|
|
|
(map (lambda (x) (make-trans-key r x))
|
|
|
|
(map (lambda (x) (make-trans-key r x))
|
|
|
|
(filter (lambda (non-term)
|
|
|
|
(filter (lambda (non-term)
|
|
|
|
(and (nullable? g non-term)
|
|
|
|
(and (nullable? g non-term)
|
|
|
|
(run-automaton r non-term a)))
|
|
|
|
(send a run-automaton r non-term)))
|
|
|
|
(grammar-non-terms g))))))
|
|
|
|
(grammar-non-terms g))))))
|
|
|
|
|
|
|
|
|
|
|
|
;; compute-read: LR0-automaton * grammar -> (trans-key -> term list)
|
|
|
|
;; compute-read: LR0-automaton * grammar -> (trans-key -> term list)
|
|
|
|
(define (compute-read a g)
|
|
|
|
(define (compute-read a g)
|
|
|
|
(let* ((dr (compute-DR a g))
|
|
|
|
(let* ((dr (compute-DR a g))
|
|
|
|
(reads (compute-reads a g)))
|
|
|
|
(reads (compute-reads a g)))
|
|
|
|
(digraph (get-mapped-lr0-non-term-keys a)
|
|
|
|
(digraph-tk->terml (send a get-mapped-non-term-keys)
|
|
|
|
reads
|
|
|
|
reads
|
|
|
|
dr
|
|
|
|
dr
|
|
|
|
bitwise-ior
|
|
|
|
(vector-length (send a get-states))
|
|
|
|
(lambda () 0))))
|
|
|
|
(length (grammar-terms g))
|
|
|
|
|
|
|
|
(length (grammar-non-terms g)))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; comput-includes-and-lookback:
|
|
|
|
;; comput-includes-and-lookback:
|
|
|
@ -50,13 +52,13 @@
|
|
|
|
;; (kernel * prod -> trans-key list))
|
|
|
|
;; (kernel * prod -> trans-key list))
|
|
|
|
(define (compute-includes-and-lookback a g)
|
|
|
|
(define (compute-includes-and-lookback a g)
|
|
|
|
(let* ((non-terms (grammar-non-terms g))
|
|
|
|
(let* ((non-terms (grammar-non-terms g))
|
|
|
|
(num-states (vector-length (lr0-states a)))
|
|
|
|
(num-states (vector-length (send a get-states)))
|
|
|
|
(num-non-terms (length non-terms))
|
|
|
|
(num-non-terms (length non-terms))
|
|
|
|
(includes (make-array2d num-states num-non-terms null))
|
|
|
|
(includes (make-array2d num-states num-non-terms null))
|
|
|
|
(lookback (make-array2d num-states
|
|
|
|
(lookback (make-array2d num-states
|
|
|
|
(grammar-num-prods g)
|
|
|
|
(grammar-num-prods g)
|
|
|
|
null)))
|
|
|
|
null)))
|
|
|
|
(for-each-state
|
|
|
|
(send a for-each-state
|
|
|
|
(lambda (state)
|
|
|
|
(lambda (state)
|
|
|
|
(for-each
|
|
|
|
(for-each
|
|
|
|
(lambda (non-term)
|
|
|
|
(lambda (non-term)
|
|
|
@ -65,8 +67,8 @@
|
|
|
|
(let loop ((i (make-item prod 0))
|
|
|
|
(let loop ((i (make-item prod 0))
|
|
|
|
(p state))
|
|
|
|
(p state))
|
|
|
|
(if (and p i)
|
|
|
|
(if (and p i)
|
|
|
|
(let ((new-i (move-dot-right i))
|
|
|
|
(let* ((next-sym (sym-at-dot i))
|
|
|
|
(next-sym (sym-at-dot i)))
|
|
|
|
(new-i (move-dot-right i)))
|
|
|
|
(if (and (non-term? next-sym)
|
|
|
|
(if (and (non-term? next-sym)
|
|
|
|
(nullable-after-dot? new-i g))
|
|
|
|
(nullable-after-dot? new-i g))
|
|
|
|
(array2d-add! includes
|
|
|
|
(array2d-add! includes
|
|
|
@ -80,10 +82,10 @@
|
|
|
|
(make-trans-key state non-term)))
|
|
|
|
(make-trans-key state non-term)))
|
|
|
|
(if next-sym
|
|
|
|
(if next-sym
|
|
|
|
(loop new-i
|
|
|
|
(loop new-i
|
|
|
|
(run-automaton p next-sym a)))))))
|
|
|
|
(send a run-automaton p next-sym)))))))
|
|
|
|
(get-nt-prods g non-term)))
|
|
|
|
(get-nt-prods g non-term)))
|
|
|
|
non-terms))
|
|
|
|
non-terms)))
|
|
|
|
a)
|
|
|
|
|
|
|
|
(values (lambda (tk)
|
|
|
|
(values (lambda (tk)
|
|
|
|
(array2d-ref includes
|
|
|
|
(array2d-ref includes
|
|
|
|
(kernel-index (trans-key-st tk))
|
|
|
|
(kernel-index (trans-key-st tk))
|
|
|
@ -93,15 +95,15 @@
|
|
|
|
(kernel-index state)
|
|
|
|
(kernel-index state)
|
|
|
|
(prod-index prod))))))
|
|
|
|
(prod-index prod))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; compute-follow: LR0-automaton * grammar -> (trans-key -> term list)
|
|
|
|
;; compute-follow: LR0-automaton * grammar -> (trans-key -> term list)
|
|
|
|
(define (compute-follow a g includes)
|
|
|
|
(define (compute-follow a g includes)
|
|
|
|
(let ((read (compute-read a g)))
|
|
|
|
(let ((read (compute-read a g)))
|
|
|
|
(digraph (get-mapped-lr0-non-term-keys a)
|
|
|
|
(digraph-tk->terml (send a get-mapped-non-term-keys)
|
|
|
|
includes
|
|
|
|
includes
|
|
|
|
read
|
|
|
|
read
|
|
|
|
bitwise-ior
|
|
|
|
(vector-length (send a get-states))
|
|
|
|
(lambda () 0))))
|
|
|
|
(length (grammar-terms g))
|
|
|
|
|
|
|
|
(length (grammar-non-terms g)))))
|
|
|
|
|
|
|
|
|
|
|
|
;; compute-LA: LR0-automaton * grammar -> (kernel * prod -> term list)
|
|
|
|
;; compute-LA: LR0-automaton * grammar -> (kernel * prod -> term list)
|
|
|
|
(define (compute-LA a g)
|
|
|
|
(define (compute-LA a g)
|
|
|
@ -128,7 +130,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
(define (print-input-st-sym f name a g print-output)
|
|
|
|
(define (print-input-st-sym f name a g print-output)
|
|
|
|
(printf "~a:~n" name)
|
|
|
|
(printf "~a:~n" name)
|
|
|
|
(for-each-state
|
|
|
|
(send a for-each-state
|
|
|
|
(lambda (state)
|
|
|
|
(lambda (state)
|
|
|
|
(for-each
|
|
|
|
(for-each
|
|
|
|
(lambda (non-term)
|
|
|
|
(lambda (non-term)
|
|
|
@ -139,13 +141,12 @@
|
|
|
|
state
|
|
|
|
state
|
|
|
|
(gram-sym-symbol non-term)
|
|
|
|
(gram-sym-symbol non-term)
|
|
|
|
(print-output res)))))
|
|
|
|
(print-output res)))))
|
|
|
|
(grammar-non-terms g)))
|
|
|
|
(grammar-non-terms g))))
|
|
|
|
a)
|
|
|
|
|
|
|
|
(newline))
|
|
|
|
(newline))
|
|
|
|
|
|
|
|
|
|
|
|
(define (print-input-st-prod f name a g print-output)
|
|
|
|
(define (print-input-st-prod f name a g print-output)
|
|
|
|
(printf "~a:~n" name)
|
|
|
|
(printf "~a:~n" name)
|
|
|
|
(for-each-state
|
|
|
|
(send a for-each-state
|
|
|
|
(lambda (state)
|
|
|
|
(lambda (state)
|
|
|
|
(for-each
|
|
|
|
(for-each
|
|
|
|
(lambda (non-term)
|
|
|
|
(lambda (non-term)
|
|
|
@ -159,8 +160,7 @@
|
|
|
|
(prod-index prod)
|
|
|
|
(prod-index prod)
|
|
|
|
(print-output res)))))
|
|
|
|
(print-output res)))))
|
|
|
|
(get-nt-prods g non-term)))
|
|
|
|
(get-nt-prods g non-term)))
|
|
|
|
(grammar-non-terms g)))
|
|
|
|
(grammar-non-terms g)))))
|
|
|
|
a))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(define (print-output-terms r)
|
|
|
|
(define (print-output-terms r)
|
|
|
|
(map
|
|
|
|
(map
|
|
|
@ -176,7 +176,77 @@
|
|
|
|
(gram-sym-symbol (trans-key-gs p))))
|
|
|
|
(gram-sym-symbol (trans-key-gs p))))
|
|
|
|
r))
|
|
|
|
r))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; digraph-tk->terml:
|
|
|
|
|
|
|
|
;; (trans-key list) * (trans-key -> trans-key list) * (trans-key -> term list) * int * int * int
|
|
|
|
|
|
|
|
;; -> (trans-key -> term list)
|
|
|
|
|
|
|
|
;; DeRemer and Pennello 1982
|
|
|
|
|
|
|
|
;; Computes (f x) = (f- x) union Union{(f y) | y in (edges x)}
|
|
|
|
|
|
|
|
;; A specialization of digraph in the file graph.ss
|
|
|
|
|
|
|
|
(define (digraph-tk->terml nodes edges f- num-states num-terms num-non-terms)
|
|
|
|
|
|
|
|
(letrec (
|
|
|
|
|
|
|
|
;; Will map elements of trans-key to term sets represented as bit vectors
|
|
|
|
|
|
|
|
(results-terms (make-array2d num-states num-terms 0))
|
|
|
|
|
|
|
|
(results-non-terms (make-array2d num-states num-non-terms 0))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; Maps elements of trans-keys to integers.
|
|
|
|
|
|
|
|
(N-terms (make-array2d num-states num-terms 0))
|
|
|
|
|
|
|
|
(N-non-terms (make-array2d num-states num-non-terms 0))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(lookup-tk-map
|
|
|
|
|
|
|
|
(lambda (map-term map-non-term)
|
|
|
|
|
|
|
|
(lambda (tk)
|
|
|
|
|
|
|
|
(let ((st (trans-key-st tk))
|
|
|
|
|
|
|
|
(gs (trans-key-gs tk)))
|
|
|
|
|
|
|
|
(if (term? gs)
|
|
|
|
|
|
|
|
(array2d-ref map-term (kernel-index st) (term-index gs))
|
|
|
|
|
|
|
|
(array2d-ref map-non-term (kernel-index st) (non-term-index gs)))))))
|
|
|
|
|
|
|
|
(add-tk-map
|
|
|
|
|
|
|
|
(lambda (map-term map-non-term)
|
|
|
|
|
|
|
|
(lambda (tk v)
|
|
|
|
|
|
|
|
(let ((st (trans-key-st tk))
|
|
|
|
|
|
|
|
(gs (trans-key-gs tk)))
|
|
|
|
|
|
|
|
(if (term? gs)
|
|
|
|
|
|
|
|
(array2d-set! map-term (kernel-index st) (term-index gs) v)
|
|
|
|
|
|
|
|
(array2d-set! map-non-term (kernel-index st) (non-term-index gs) v))))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(get-N (lookup-tk-map N-terms N-non-terms))
|
|
|
|
|
|
|
|
(set-N (add-tk-map N-terms N-non-terms))
|
|
|
|
|
|
|
|
(get-f (lookup-tk-map results-terms results-non-terms))
|
|
|
|
|
|
|
|
(set-f (add-tk-map results-terms results-non-terms))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(stack null)
|
|
|
|
|
|
|
|
(push (lambda (x)
|
|
|
|
|
|
|
|
(set! stack (cons x stack))))
|
|
|
|
|
|
|
|
(pop (lambda ()
|
|
|
|
|
|
|
|
(begin0
|
|
|
|
|
|
|
|
(car stack)
|
|
|
|
|
|
|
|
(set! stack (cdr stack)))))
|
|
|
|
|
|
|
|
(depth (lambda () (length stack)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
;; traverse: 'a ->
|
|
|
|
|
|
|
|
(traverse
|
|
|
|
|
|
|
|
(lambda (x)
|
|
|
|
|
|
|
|
(push x)
|
|
|
|
|
|
|
|
(let ((d (depth)))
|
|
|
|
|
|
|
|
(set-N x d)
|
|
|
|
|
|
|
|
(set-f x (f- x))
|
|
|
|
|
|
|
|
(for-each (lambda (y)
|
|
|
|
|
|
|
|
(if (= 0 (get-N y))
|
|
|
|
|
|
|
|
(traverse y))
|
|
|
|
|
|
|
|
(set-f x (bitwise-ior (get-f x) (get-f y)))
|
|
|
|
|
|
|
|
(set-N x (min (get-N x) (get-N y))))
|
|
|
|
|
|
|
|
(edges x))
|
|
|
|
|
|
|
|
(if (= d (get-N x))
|
|
|
|
|
|
|
|
(let loop ((p (pop)))
|
|
|
|
|
|
|
|
(set-N p +inf.0)
|
|
|
|
|
|
|
|
(set-f p (get-f x))
|
|
|
|
|
|
|
|
(if (not (equal? x p))
|
|
|
|
|
|
|
|
(loop (pop)))))))))
|
|
|
|
|
|
|
|
(for-each (lambda (x)
|
|
|
|
|
|
|
|
(if (= 0 (get-N x))
|
|
|
|
|
|
|
|
(traverse x)))
|
|
|
|
|
|
|
|
nodes)
|
|
|
|
|
|
|
|
get-f))
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|