factor/basis/regexp/dfa/dfa.factor

88 lines
2.7 KiB
Factor
Raw Normal View History

2009-02-19 01:11:45 -05:00
! Copyright (C) 2008, 2009 Doug Coleman, Daniel Ehrenberg.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors arrays assocs combinators fry kernel locals
math math.order regexp.nfa regexp.transition-tables sequences
2009-03-04 01:36:03 -05:00
sets sorting vectors regexp.ast regexp.classes ;
IN: regexp.dfa
2009-02-18 13:27:07 -05:00
: find-delta ( states transition nfa -- new-states )
transitions>> '[ _ swap _ at at ] gather sift ;
2009-03-04 01:36:03 -05:00
:: epsilon-loop ( state table nfa question -- )
state table at :> old-value
old-value question 2array <or-class> :> new-question
new-question old-value = [
new-question state table set-at
state nfa transitions>> at
[ drop tagged-epsilon? ] assoc-filter
[| trans to |
to [
table nfa
trans tag>> new-question 2array <and-class>
epsilon-loop
] each
] assoc-each
] unless ;
: epsilon-table ( states nfa -- table )
[ [ H{ } clone ] dip over ] dip
2009-03-04 01:36:03 -05:00
'[ _ _ t epsilon-loop ] each ;
2009-03-04 01:36:03 -05:00
: find-epsilon-closure ( states nfa -- dfa-state )
epsilon-table table>condition ;
2009-02-18 13:27:07 -05:00
: find-closure ( states transition nfa -- new-states )
[ find-delta ] keep find-epsilon-closure ;
2009-02-18 13:27:07 -05:00
: find-start-state ( nfa -- state )
2009-03-04 01:36:03 -05:00
[ start-state>> 1array ] keep find-epsilon-closure ;
2009-02-18 13:27:07 -05:00
: find-transitions ( dfa-state nfa -- next-dfa-state )
transitions>>
'[ _ at keys [ condition-states ] map concat ] gather
[ tagged-epsilon? not ] filter ;
2009-02-18 13:27:07 -05:00
: add-todo-state ( state visited-states new-states -- )
3dup drop key? [ 3drop ] [
[ conjoin ] [ push ] bi-curry* bi
] if ;
: add-todo-states ( state/condition visited-states new-states -- )
[ condition-states ] 2dip
'[ _ _ add-todo-state ] each ;
2009-04-06 20:43:50 -04:00
: ensure-state ( key table -- )
2dup key? [ 2drop ] [ [ H{ } clone ] 2dip set-at ] if ; inline
2009-02-18 13:27:07 -05:00
:: new-transitions ( nfa dfa new-states visited-states -- nfa dfa )
new-states [ nfa dfa ] [
2009-02-18 15:52:10 -05:00
pop :> state
2009-04-06 20:43:50 -04:00
state dfa transitions>> ensure-state
2009-02-18 15:52:10 -05:00
state nfa find-transitions
2009-02-18 13:27:07 -05:00
[| trans |
state trans nfa find-closure :> new-state
new-state visited-states new-states add-todo-states
2009-03-04 01:36:03 -05:00
state new-state trans dfa set-transition
2009-02-18 13:27:07 -05:00
] each
nfa dfa new-states visited-states new-transitions
] if-empty ;
2009-02-18 13:27:07 -05:00
: set-final-states ( nfa dfa -- )
[
[ final-states>> members ]
[ transitions>> keys ] bi*
2009-02-18 13:27:07 -05:00
[ intersects? ] with filter
fast-set
] keep final-states<< ;
2009-02-18 13:27:07 -05:00
: initialize-dfa ( nfa -- dfa )
<transition-table>
swap find-start-state >>start-state ;
2008-08-28 23:08:54 -04:00
2009-02-18 13:27:07 -05:00
: construct-dfa ( nfa -- dfa )
dup initialize-dfa
dup start-state>> condition-states >vector
2009-02-18 13:27:07 -05:00
H{ } clone
new-transitions
[ set-final-states ] keep ;