diff --git a/basis/regexp/dfa/dfa.factor b/basis/regexp/dfa/dfa.factor index cd6dab6a06..ef985258fd 100644 --- a/basis/regexp/dfa/dfa.factor +++ b/basis/regexp/dfa/dfa.factor @@ -25,7 +25,7 @@ IN: regexp.dfa : find-transitions ( seq1 regexp -- seq2 ) nfa-table>> transitions>> - [ at keys ] curry map concat + [ at keys ] curry gather eps swap remove ; : add-todo-state ( state regexp -- ) diff --git a/basis/regexp/regexp-tests.factor b/basis/regexp/regexp-tests.factor index 4d25a58c39..be19c065f5 100644 --- a/basis/regexp/regexp-tests.factor +++ b/basis/regexp/regexp-tests.factor @@ -299,3 +299,10 @@ IN: regexp-tests ! clear "a$" "a\n" over match ! clear "a$" "a\r" over match ! clear "a$" "a\r\n" over match + +! "(az)(?<=b)" "baz" over first-match +! "a(?<=b*)" "cbaz" over first-match +! "a(?<=b)" "baz" over first-match + +! "a(? "baz" over first-match +! "a(? "caz" over first-match diff --git a/basis/regexp/traversal/traversal.factor b/basis/regexp/traversal/traversal.factor index d4b43c37f0..d82e9941a2 100644 --- a/basis/regexp/traversal/traversal.factor +++ b/basis/regexp/traversal/traversal.factor @@ -38,7 +38,11 @@ TUPLE: dfa-traverser key? ; : text-finished? ( dfa-traverser -- ? ) - [ current-index>> ] [ text>> length ] bi >= ; + { + [ current-state>> empty? ] + [ [ current-index>> ] [ text>> length ] bi >= ] + ! [ current-index>> 0 < ] + } 1|| ; : save-final-state ( dfa-straverser -- ) [ current-index>> ] [ matches>> ] bi push ; @@ -62,24 +66,26 @@ M: lookahead-off flag-action ( dfa-traverser flag -- ) M: lookbehind-on flag-action ( dfa-traverser flag -- ) drop f >>traverse-forward + [ 2 - ] change-current-index lookbehind-counters>> 0 swap push ; M: lookbehind-off flag-action ( dfa-traverser flag -- ) drop t >>traverse-forward dup lookbehind-counters>> - [ drop ] [ pop '[ _ + ] change-current-index drop ] if-empty ; + [ drop ] [ pop '[ _ + 2 + ] change-current-index drop ] if-empty ; : process-flags ( dfa-traverser -- ) [ [ 1+ ] map ] change-lookahead-counters + [ [ 1+ ] map ] change-lookbehind-counters + ! dup current-state>> . dup [ current-state>> ] [ traversal-flags>> ] bi at [ dup . flag-action ] with each ; : increment-state ( dfa-traverser state -- dfa-traverser ) [ dup traverse-forward>> - [ [ 1+ ] change-current-index ] - [ [ 1- ] change-current-index ] if + [ 1+ ] [ 1- ] ? change-current-index dup current-state>> >>last-state ] dip first >>current-state ;