1vector >>new-states drop ;
: set-traversal-flags ( regexp -- )
- [ dfa-table>> transitions>> keys ]
+ dup
[ nfa-traversal-flags>> ]
- bi 2drop ;
+ [ dfa-table>> transitions>> keys ] bi
+ [ tuck [ swap at ] with map concat ] with H{ } map>assoc
+ >>dfa-traversal-flags drop ;
: construct-dfa ( regexp -- )
- [ set-initial-state ]
- [ new-transitions ]
- [ set-final-states ] tri ;
- ! [ set-traversal-flags ] quad ;
+ {
+ [ set-initial-state ]
+ [ new-transitions ]
+ [ set-final-states ]
+ [ set-traversal-flags ]
+ } cleave ;
! [ t ] [ "fxxbar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
! [ f ] [ "foobar" "(?!foo).{3}bar" <regexp> matches? ] unit-test
-! [ 3 ] [ "foobar" "foo(?=bar)" <regexp> match-head ] unit-test
-! [ f ] [ "foobxr" "foo(?=bar)" <regexp> match-head ] unit-test
+[ 3 ] [ "foobar" "foo(?=bar)" <regexp> match-head ] unit-test
+[ f ] [ "foobxr" "foo(?=bar)" <regexp> match-head ] unit-test
! [ f ] [ "foobxr" "foo\\z" <regexp> match-head ] unit-test
! [ 3 ] [ "foo" "foo\\z" <regexp> match-head ] unit-test
! Copyright (C) 2008 Doug Coleman.
! See http://factorcode.org/license.txt for BSD license.
USING: accessors assocs combinators kernel math math.ranges
-quotations sequences regexp.parser regexp.classes
-combinators.short-circuit regexp.utils ;
+quotations sequences regexp.parser regexp.classes fry
+combinators.short-circuit regexp.utils prettyprint regexp.nfa ;
IN: regexp.traversal
TUPLE: dfa-traverser
traversal-flags
capture-groups
{ capture-group-index integer }
- { lookahead-counter integer }
+ lookahead-counters
last-state current-state
text
start-index current-index
0 >>start-index
0 >>current-index
V{ } clone >>matches
- V{ } clone >>capture-groups ;
+ V{ } clone >>capture-groups
+ V{ } clone >>lookahead-counters ;
: final-state? ( dfa-traverser -- ? )
[ current-state>> ] [ dfa-table>> final-states>> ] bi
dup save-final-state
] when text-finished? ;
-: print-flags ( dfa-traverser -- dfa-traverser )
+GENERIC: flag-action ( dfa-traverser flag -- )
+
+M: lookahead-on flag-action ( dfa-traverser flag -- )
+ drop
+ lookahead-counters>> 0 swap push ;
+
+M: lookahead-off flag-action ( dfa-traverser flag -- )
+ drop
+ dup lookahead-counters>> pop
+ '[ _ - ] change-current-index drop ;
+
+: process-flags ( dfa-traverser -- )
+ [ [ 1+ ] map ] change-lookahead-counters
dup [ current-state>> ] [ traversal-flags>> ] bi
- ;
+ at [ dup . flag-action ] with each ;
: increment-state ( dfa-traverser state -- dfa-traverser )
[
[ nth ] 2dip ;
: do-match ( dfa-traverser -- dfa-traverser )
+ dup process-flags
dup match-done? [
dup setup-match match-transition
[ increment-state do-match ] when*