Merge branch 'master' of git://factorcode.org/git/factor

db4
Slava Pestov 2009-03-11 16:54:26 -05:00
commit 44d36dab9c
8 changed files with 70 additions and 56 deletions

View File

@ -58,8 +58,8 @@ M: from-to <times>
: char-class ( ranges ? -- term )
[ <or-class> ] dip [ <not-class> ] when ;
TUPLE: lookahead term positive? ;
TUPLE: lookahead term ;
C: <lookahead> lookahead
TUPLE: lookbehind term positive? ;
TUPLE: lookbehind term ;
C: <lookbehind> lookbehind

View File

@ -12,7 +12,7 @@ ascii-class punctuation-class java-printable-class blank-class
control-character-class hex-digit-class java-blank-class c-identifier-class
unmatchable-class terminator-class word-boundary-class ;
SINGLETONS: beginning-of-input ^ end-of-input $ end-of-file ;
SINGLETONS: beginning-of-input ^ end-of-input $ end-of-file word-break ;
TUPLE: range from to ;
C: <range> range

View File

@ -3,7 +3,7 @@
USING: regexp.classes kernel sequences regexp.negation
quotations assocs fry math locals combinators
accessors words compiler.units kernel.private strings
sequences.private arrays call namespaces
sequences.private arrays call namespaces unicode.breaks
regexp.transition-tables combinators.short-circuit ;
IN: regexp.compiler
@ -15,6 +15,10 @@ SYMBOL: backwards?
<PRIVATE
M: t question>quot drop [ 2drop t ] ;
M: f question>quot drop [ 2drop f ] ;
M: not-class question>quot
class>> question>quot [ not ] compose ;
M: beginning-of-input question>quot
drop [ drop zero? ] ;
@ -36,6 +40,9 @@ M: $ question>quot
M: ^ question>quot
drop [ { [ drop zero? ] [ [ 1- ] dip ?nth "\r\n" member? ] } 2|| ] ;
M: word-break question>quot
drop [ word-break-at? ] ;
: (execution-quot) ( next-state -- quot )
! The conditions here are for lookaround and anchors, etc
dup condition? [

View File

@ -56,6 +56,8 @@ ERROR: bad-class name ;
{ CHAR: z [ end-of-input <tagged-epsilon> ] }
{ CHAR: Z [ end-of-file <tagged-epsilon> ] }
{ CHAR: A [ beginning-of-input <tagged-epsilon> ] }
{ CHAR: b [ word-break <tagged-epsilon> ] }
{ CHAR: B [ word-break <not-class> <tagged-epsilon> ] }
[ ]
} case ;
@ -138,10 +140,10 @@ Parenthized = "?:" Alternation:a => [[ a ]]
=> [[ a on off parse-options <with-options> ]]
| "?#" [^)]* => [[ f ]]
| "?~" Alternation:a => [[ a <negation> ]]
| "?=" Alternation:a => [[ a t <lookahead> <tagged-epsilon> ]]
| "?!" Alternation:a => [[ a f <lookahead> <tagged-epsilon> ]]
| "?<=" Alternation:a => [[ a t <lookbehind> <tagged-epsilon> ]]
| "?<!" Alternation:a => [[ a f <lookbehind> <tagged-epsilon> ]]
| "?=" Alternation:a => [[ a <lookahead> <tagged-epsilon> ]]
| "?!" Alternation:a => [[ a <lookahead> <not-class> <tagged-epsilon> ]]
| "?<=" Alternation:a => [[ a <lookbehind> <tagged-epsilon> ]]
| "?<!" Alternation:a => [[ a <lookbehind> <not-class> <tagged-epsilon> ]]
| Alternation
Element = "(" Parenthized:p ")" => [[ p ]]

View File

@ -433,49 +433,40 @@ IN: regexp-tests
[ { "foo" "fxx" "fab" } ] [ "fab fxx foo" R/ f../r all-matching-subseqs ] unit-test
! [ t ] [ "foo" "\\bfoo\\b" <regexp> matches? ] unit-test
! [ t ] [ "afoob" "\\Bfoo\\B" <regexp> matches? ] unit-test
! [ t ] [ "afoob" "\\bfoo\\b" <regexp> matches? ] unit-test
! [ f ] [ "foo" "\\Bfoo\\B" <regexp> matches? ] unit-test
[ t ] [ "foo" "\\bfoo\\b" <regexp> re-contains? ] unit-test
[ t ] [ "afoob" "\\Bfoo\\B" <regexp> re-contains? ] unit-test
[ f ] [ "afoob" "\\bfoo\\b" <regexp> re-contains? ] unit-test
[ f ] [ "foo" "\\Bfoo\\B" <regexp> re-contains? ] unit-test
! [ 3 ] [ "foo bar" "foo\\b" <regexp> match-index-head ] unit-test
! [ f ] [ "fooxbar" "foo\\b" <regexp> matches? ] unit-test
! [ t ] [ "foo" "foo\\b" <regexp> matches? ] unit-test
! [ t ] [ "foo bar" "foo\\b bar" <regexp> matches? ] unit-test
! [ f ] [ "fooxbar" "foo\\bxbar" <regexp> matches? ] unit-test
! [ f ] [ "foo" "foo\\bbar" <regexp> matches? ] unit-test
[ 3 ] [ "foo bar" "foo\\b" <regexp> first-match length ] unit-test
[ f ] [ "fooxbar" "foo\\b" <regexp> re-contains? ] unit-test
[ t ] [ "foo" "foo\\b" <regexp> re-contains? ] unit-test
[ t ] [ "foo bar" "foo\\b bar" <regexp> matches? ] unit-test
[ f ] [ "fooxbar" "foo\\bxbar" <regexp> matches? ] unit-test
[ f ] [ "foo" "foo\\bbar" <regexp> matches? ] unit-test
! [ f ] [ "foo bar" "foo\\B" <regexp> matches? ] unit-test
! [ 3 ] [ "fooxbar" "foo\\B" <regexp> match-index-head ] unit-test
! [ t ] [ "foo" "foo\\B" <regexp> matches? ] unit-test
! [ f ] [ "foo bar" "foo\\B bar" <regexp> matches? ] unit-test
! [ t ] [ "fooxbar" "foo\\Bxbar" <regexp> matches? ] unit-test
! [ f ] [ "foo" "foo\\Bbar" <regexp> matches? ] unit-test
[ f ] [ "foo bar" "foo\\B" <regexp> re-contains? ] unit-test
[ 3 ] [ "fooxbar" "foo\\B" <regexp> first-match length ] unit-test
[ f ] [ "foo" "foo\\B" <regexp> re-contains? ] unit-test
[ f ] [ "foo bar" "foo\\B bar" <regexp> matches? ] unit-test
[ t ] [ "fooxbar" "foo\\Bxbar" <regexp> matches? ] unit-test
[ f ] [ "foo" "foo\\Bbar" <regexp> matches? ] unit-test
! [ 1 ] [ "aaacb" "a+?" <regexp> match-index-head ] unit-test
! [ 1 ] [ "aaacb" "aa??" <regexp> match-index-head ] unit-test
! [ f ] [ "aaaab" "a++ab" <regexp> matches? ] unit-test
! [ t ] [ "aaacb" "a++cb" <regexp> matches? ] unit-test
! [ 3 ] [ "aacb" "aa?c" <regexp> match-index-head ] unit-test
! [ 3 ] [ "aacb" "aa??c" <regexp> match-index-head ] unit-test
[ t ] [ "ab" "a(?=b*)" <regexp> re-contains? ] unit-test
[ t ] [ "abbbbbc" "a(?=b*c)" <regexp> re-contains? ] unit-test
[ f ] [ "abbbbb" "a(?=b*c)" <regexp> re-contains? ] unit-test
[ t ] [ "ab" "a(?=b*)" <regexp> re-contains? ] unit-test
! "ab" "a(?=b*)" <regexp> match
! "abbbbbc" "a(?=b*c)" <regexp> match
! "ab" "a(?=b*)" <regexp> match
[ "az" ] [ "baz" "(?<=b)(az)" <regexp> first-match >string ] unit-test
[ f ] [ "chaz" "(?<=b)(az)" <regexp> re-contains? ] unit-test
[ "a" ] [ "cbaz" "(?<=b*)a" <regexp> first-match >string ] unit-test
[ f ] [ "baz" "a(?<=b)" <regexp> re-contains? ] unit-test
! "baz" "(az)(?<=b)" <regexp> first-match
! "cbaz" "a(?<=b*)" <regexp> first-match
! "baz" "a(?<=b)" <regexp> first-match
[ f ] [ "baz" "(?<!b)a" <regexp> re-contains? ] unit-test
[ t ] [ "caz" "(?<!b)a" <regexp> re-contains? ] unit-test
! "baz" "a(?<!b)" <regexp> first-match
! "caz" "a(?<!b)" <regexp> first-match
[ "abcd" ] [ "abcdefg" "a(?=bcdefg)bcd" <regexp> first-match >string ] unit-test
[ t ] [ "abcdefg" "a(?#bcdefg)bcd" <regexp> re-contains? ] unit-test
[ t ] [ "abcdefg" "a(?:bcdefg)" <regexp> matches? ] unit-test
! "abcdefg" "a(?=bcdefg)bcd" <regexp> first-match
! "abcdefg" "a(?#bcdefg)bcd" <regexp> first-match
! "abcdefg" "a(?:bcdefg)" <regexp> first-match
! "caba" "a(?<=b)" <regexp> first-match
! capture group 1: "aaaa" 2: ""
! "aaaa" "(a*)(a*)" <regexp> match*
! "aaaa" "(a*)(a+)" <regexp> match*
[ 3 ] [ "caba" "(?<=b)a" <regexp> first-match from>> ] unit-test

View File

@ -17,21 +17,16 @@ TUPLE: reverse-regexp < regexp ;
<PRIVATE
: maybe-negated ( lookaround quot -- regexp-quot )
'[ term>> @ ] [ positive?>> [ ] [ not ] ? ] bi compose ; inline
M: lookahead question>quot ! Returns ( index string -- ? )
[ ast>dfa dfa>shortest-word '[ f _ execute ] ] maybe-negated ;
term>> ast>dfa dfa>shortest-word '[ f _ execute ] ;
: <reversed-option> ( ast -- reversed )
"r" string>options <with-options> ;
M: lookbehind question>quot ! Returns ( index string -- ? )
[
<reversed-option>
ast>dfa dfa>reverse-shortest-word
'[ [ 1- ] dip f _ execute ]
] maybe-negated ;
term>> <reversed-option>
ast>dfa dfa>reverse-shortest-word
'[ [ 1- ] dip f _ execute ] ;
: check-string ( string -- string )
! Make this configurable

View File

@ -37,3 +37,5 @@ IN: unicode.breaks.tests
grapheme-break-test parse-test-file [ >graphemes ] test
word-break-test parse-test-file [ >words ] test
[ { t f t t f t } ] [ 6 [ "as df" word-break-at? ] map ] unit-test

View File

@ -228,3 +228,20 @@ PRIVATE>
: >words ( str -- words )
[ first-word ] >pieces ;
<PRIVATE
: nth-next ( i str -- str[i-1] str[i] )
[ [ 1- ] keep ] dip '[ _ nth ] bi@ ;
PRIVATE>
: word-break-at? ( i str -- ? )
{
[ drop zero? ]
[ length = ]
[
[ nth-next [ word-break-prop ] dip ] 2keep
word-break-next nip
]
} 2|| ;