Author: pmichaud
Date: Wed Apr 4 20:50:38 2007
New Revision: 17990
Added:
trunk/t/compilers/pge/perl6regex/rx_metachars
- copied, changed from r17969, /trunk/t/compilers/pge/p6regex/rx_metachars
Modified:
trunk/MANIFEST
trunk/compilers/pge/PGE/Perl6Regex.pir
trunk/t/compilers/pge/perl6regex/01-regex.t
trunk/t/compilers/pge/perl6regex/rx_charclass
Log:
[PGE]:
* More updates to metacharacter handling, tests.
Modified: trunk/MANIFEST
==============================================================================
--- trunk/MANIFEST (original)
+++ trunk/MANIFEST Wed Apr 4 20:50:38 2007
@@ -2748,6 +2748,7 @@
t/compilers/pge/perl6regex/01-regex.t []
t/compilers/pge/perl6regex/rx_backtrack []
t/compilers/pge/perl6regex/rx_charclass []
+t/compilers/pge/perl6regex/rx_metachars []
t/compilers/pge/pge-hs.t []
t/compilers/pge/pge.t []
t/compilers/pge/pge_examples.t []
Modified: trunk/compilers/pge/PGE/Perl6Regex.pir
==============================================================================
--- trunk/compilers/pge/PGE/Perl6Regex.pir (original)
+++ trunk/compilers/pge/PGE/Perl6Regex.pir Wed Apr 4 20:50:38 2007
@@ -165,6 +165,12 @@
$P0 = get_global 'parse_term'
optable.newtok('term:', 'precedence'=>'=', 'nows'=>1, 'parsed'=>$P0)
+ $P0 = get_global 'parse_term_ws'
+ optable.newtok('term:#', 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
+
+ $P0 = get_global 'parse_term_backslash'
+ optable.newtok("term:\\", 'equiv'=>'term:', 'nows'=>1, 'parsed'=>$P0)
+
optable.newtok('term:^', 'equiv'=>'term:', 'nows'=>1,
'match'=>'PGE::Exp::Anchor')
optable.newtok('term:^^', 'equiv'=>'term:', 'nows'=>1,
'match'=>'PGE::Exp::Anchor')
optable.newtok('term:$$', 'equiv'=>'term:', 'nows'=>1,
'match'=>'PGE::Exp::Anchor')
@@ -287,7 +293,6 @@
$P0 = get_hll_global ['PGE::Perl6Regex'], '@!stopstack'
stop = $P0[-1]
- .local string initchar
$I0 = is_cclass .CCLASS_WHITESPACE, target, pos
if $I0 goto term_ws
$I0 = length stop
@@ -295,104 +300,24 @@
$S0 = substr target, pos, $I0
if $S0 == stop goto end_noterm
not_stop:
- initchar = substr target, pos, 1
- $I0 = index '<>[](){}:*?+|&^$.', initchar
- if $I0 >= 0 goto end_noterm
- inc pos
- if initchar == '#' goto term_ws
- if initchar != "\\" goto term_literal
-
- term_backslash:
- $I0 = is_cclass .CCLASS_NUMERIC, target, pos
- if $I0 goto err_backslash_digit
- initchar = substr target, pos, 1
- .local int isnegated
- isnegated = is_cclass .CCLASS_UPPERCASE, target, pos
- inc pos
- $S0 = initchar
- $I0 = index "ABCDEFGHIJKLMNOPQRSTUVWXYZ", $S0
- if $I0 < 0 goto term_backslash_1
- $S0 = substr "abcdefghijklmnopqrstuvwxyz", $I0, 1
- term_backslash_1:
- if $S0 == 'x' goto term_backslash_x # \x.. \X..
- if $S0 == 'o' goto term_backslash_o # \o.. \O..
- $P0 = get_global '%esclist'
- $I0 = exists $P0[$S0]
- if $I0 == 0 goto term_literal
- initchar = $P0[$S0]
- if isnegated goto term_charlist
- $I0 = length initchar
- if $I0 < 2 goto term_literal
- term_charlist:
- (mob, $P99, $P99, $P0) = mob.newfrom(0, 'PGE::Exp::EnumCharList')
- mob.'result_object'(initchar)
- mob['isnegated'] = isnegated
- $P0 = pos
- .return (mob)
+ ## find length of word character sequence
+ .local int litlen
+ $I0 = find_not_cclass .CCLASS_WORD, target, pos, lastpos
+ litlen = $I0 - pos
- term_backslash_o:
- .local int base
- base = 8
- goto term_bx0
- term_backslash_x:
- base = 16
- term_bx0:
- $I0 = 0
- $S0 = substr target, pos, 1
- $I2 = index "[{(<", $S0
- if $I2 < 0 goto term_bx1
- $S2 = substr "]})>", $I0
- inc pos
- term_bx1:
- $S0 = substr target, pos, 1
- $I1 = index "0123456789abcdef0123456789ABCDEF", $S0
- if $I1 < 0 goto term_bx2
- $I1 = $I1 % 16
- if $I1 >= base goto term_bx2
- $I0 *= base
- $I0 += $I1
- inc pos
- goto term_bx1
- term_bx2:
- initchar = chr $I0
- if $I2 < 0 goto term_bx3
- $S0 = substr target, pos, 1
- if $S0 != $S2 goto err_backslash_close
- inc pos
- term_bx3:
- if isnegated goto term_charlist # \X[...], \000
- # goto term_literal # \x[...], \000
+ ## if we didn't find any, return no term
+ if litlen == 0 goto end_noterm
- term_literal:
- .local int litstart, litlen
- .local string delim
- litstart = pos
- litlen = 0
- delim = "<>[](){}:*?+\\|&#^$"
- $S0 = substr stop, 0, 1
- delim .= $S0
- term_literal_loop:
- if pos >= lastpos goto term_literal_end
- $I0 = is_cclass .CCLASS_WHITESPACE, target, pos
- if $I0 goto term_literal_end
- $S0 = substr target, pos, 1
- $I0 = index delim, $S0
- if $I0 >= 0 goto term_literal_end
- inc pos
- inc litlen
- goto term_literal_loop
- term_literal_end:
- ## for a multi-char literal, we don't eat the last chararacter
+ ## for multi-char unquoted literals, leave the last character
## in case it's quantified (it gets processed as a subsequent term)
- if litlen < 1 goto term_literal_one
- dec pos
- term_literal_one:
- $I0 = pos - litstart
- $S0 = substr target, litstart, $I0
- $S0 = concat initchar, $S0
- (mob, $S99, $P99, $P0) = mob.newfrom(0, 'PGE::Exp::Literal')
+ if litlen < 2 goto term_literal
+ dec litlen
+ term_literal:
+ $S0 = substr target, pos, litlen
+ pos += litlen
+ (mob, $S99, $P99, $P0) = mob.'newfrom'(0, 'PGE::Exp::Literal')
mob.'result_object'($S0)
- $P0 = pos
+ mob.'to'(pos)
.return (mob)
term_ws:
@@ -401,15 +326,108 @@
end_noterm:
(mob) = mob.newfrom(0, 'PGE::Exp::Literal')
.return (mob)
+.end
+
+
+=item C<parse_term_backslash(mob [, adverbs :slurpy :named])>
+
+Parses terms beginning with backslash.
+
+=cut
+
+.sub 'parse_term_backslash'
+ .param pmc mob
+ .param pmc adverbs :slurpy :named
+
+ .local string target
+ .local int pos, lastpos
+ $P0 = getattribute mob, '$.target'
+ target = $P0
+ $P0 = getattribute mob, '$.pos'
+ pos = $P0
+ lastpos = length target
+
+ .local string initchar
+ initchar = substr target, pos, 1
+ $I0 = is_cclass .CCLASS_WORD, initchar, 0
+ if $I0 goto term_metachar
+ quoted_metachar:
+ inc pos
+ (mob, $S99, $P99, $P0) = mob.'newfrom'(0, 'PGE::Exp::Literal')
+ mob.'result_object'(initchar)
+ mob.'to'(pos)
+ .return (mob)
+
+ term_metachar:
+ .local int isnegated
+ isnegated = is_cclass .CCLASS_UPPERCASE, initchar, 0
+ $S0 = downcase initchar
+ if $S0 == 'x' goto scan_xdo
+ if $S0 == 'o' goto scan_xdo
+ $P0 = get_global '%esclist'
+ $I0 = exists $P0[$S0]
+ if $I0 == 0 goto err_reserved_metachar
+ inc pos
+ .local string charlist
+ charlist = $P0[$S0]
+ if isnegated goto term_charlist
+ $I0 = length charlist
+ if $I0 > 1 goto term_charlist
+
+ term_literal:
+ (mob, $S99, $P99, $P0) = mob.'newfrom'(0, 'PGE::Exp::Literal')
+ mob.'result_object'(charlist)
+ mob.'to'(pos)
+ .return (mob)
- err_backslash_digit:
- parse_error(mob, pos, "\\1 and \\012 illegal, use $1, \\o012, or \\x0a")
+ term_charlist:
+ (mob, $S99, $P99, $P0) = mob.'newfrom'(0, 'PGE::Exp::EnumCharList')
+ mob.'result_object'(charlist)
+ mob['isnegated'] = isnegated
+ mob.'to'(pos)
.return (mob)
- err_backslash_close:
- parse_error(mob, pos, "Missing close bracket for \\x..")
-.end
+ scan_xdo:
+ inc pos
+ .local int base, decnum, isbracketed
+ charlist = ''
+ base = index ' o d x', $S0
+ decnum = 0
+ $S0 = substr target, pos, 1
+ isbracketed = iseq $S0, '['
+ pos += isbracketed
+ scan_xdo_char_loop:
+ $S0 = substr target, pos, 1
+ $I0 = index '0123456789abcdef', $S0
+ if $I0 < 0 goto scan_xdo_char_end
+ if $I0 >= base goto scan_xdo_char_end
+ decnum *= base
+ decnum += $I0
+ inc pos
+ goto scan_xdo_char_loop
+ scan_xdo_char_end:
+ $S1 = chr decnum
+ concat charlist, $S1
+ unless isbracketed goto scan_xdo_end
+ if $S0 == ']' goto scan_xdo_end
+ if $S0 != ',' goto err_bracketed
+ if isnegated goto err_negated_brackets
+ inc pos
+ decnum = 0
+ goto scan_xdo_char_loop
+ scan_xdo_end:
+ pos += isbracketed
+ if isnegated goto term_charlist
+ goto term_literal
+ err_reserved_metachar:
+ parse_error(mob, pos, 'Alphanumeric metacharacters are reserved')
+ err_bracketed:
+ parse_error(mob, pos, 'Invalid digit in \\x[...] or \\o[...]')
+ err_negated_brackets:
+ parse_error(mob, pos, 'Cannot use comma in \\X[...] or \\O[...]')
+.end
+
=item C<parse_term_ws(PMC mob)>
Modified: trunk/t/compilers/pge/perl6regex/01-regex.t
==============================================================================
--- trunk/t/compilers/pge/perl6regex/01-regex.t (original)
+++ trunk/t/compilers/pge/perl6regex/01-regex.t Wed Apr 4 20:50:38 2007
@@ -58,6 +58,7 @@
load_bytecode 'Test/Builder.pir'
load_bytecode 'PGE.pbc'
load_bytecode 'PGE/Dumper.pbc'
+ load_bytecode 'String/Utils.pbc'
.include "iglobals.pasm"
# Variable declarations, initializations
@@ -71,7 +72,7 @@
test_files = new 'ResizablePMCArray'
# populate the list of test files
- # push test_files, 'rx_metachars'
+ push test_files, 'rx_metachars'
push test_files, 'rx_backtrack'
push test_files, 'rx_charclass'
# push test_files, 'rx_subrules'
@@ -455,15 +456,12 @@
$I0 = index target, '\x', x_pos
if $I0 == -1 goto target7
- $I1 = length target
- $I2 = $I0 + 2
-
- if $I2 > $I1 goto target7
- $S0 = substr target, $I2, 2
- $S1 = hex_chr($S0)
- substr target, $I0, 4, $S1
-
- inc x_pos
+ $I1 = $I0 + 2
+ $P0 = get_hll_global ['String';'Utils'], 'convert_digits_to_string'
+ ($S0, $I2) = $P0(target, 'x', $I1)
+ $S3 = substr target, $I1, $I2
+ $I2 += 2
+ substr target, $I0, $I2, $S0
goto target6
target7:
.return (target)
Modified: trunk/t/compilers/pge/perl6regex/rx_charclass
==============================================================================
--- trunk/t/compilers/pge/perl6regex/rx_charclass (original)
+++ trunk/t/compilers/pge/perl6regex/rx_charclass Wed Apr 4 20:50:38 2007
@@ -54,12 +54,13 @@
'... --- ...' ...---... n literal match (\')
# todo :pugs<feature>
'ab\'>cd' ab'>cd y literal match with quote
-'ab\\cd' ab\x5ccd y literal match with backslash
+'ab\\yz' ab\x5cyz y literal match with backslash
'ab"cd' ab"cd y literal match with quote
# todo :pugs<feature>
-'ab\\cd' ab\x5ccd y literal match with backslash
+'ab\\yz' ab\x5cyz y literal match with backslash
# todo :pugs<feature> :pge<feature>
"... --- ..." ... --- ... y literal match (\")
+# todo :pugs<feature> :pge<feature>
"... --- ..." ...---... n literal match (\")
# todo :pugs<feature> :pge<feature>
"ab<\">cd" ab<">cd y literal match with quote
Copied: trunk/t/compilers/pge/perl6regex/rx_metachars (from r17969,
/trunk/t/compilers/pge/p6regex/rx_metachars)
==============================================================================
--- /trunk/t/compilers/pge/p6regex/rx_metachars (original)
+++ trunk/t/compilers/pge/perl6regex/rx_metachars Wed Apr 4 20:50:38 2007
@@ -1,3 +1,4 @@
+## Metacharacter tests
. a y dot (.)
. \n y dot (.)
. '' n dot (.)
@@ -27,31 +28,32 @@
>>abc abc-def n right word boundary, BOS
def>> abc-def y right word boundary, EOS
>> ------- n right word boundary, no word
>> chars
+
c \n d abc\ndef y logical newline (\n)
-c \n d abc\x0adef y logical newline (\n)
-c \n d abc\x0ddef y logical newline (\n)
-c \n+ d abc\n\ndef y logical newline (\n)
+# todo :pugs<feature>
+c \n d abc\rdef y logical newline matches \r
+c \n+ d abc\n\ndef y logical newline
quantified
a\n+f abcdef n logical newline (\n)
-c \n d abc\x0a\x0ddef n logical newline (\n)
-c \n d abc\x0d\x0adef y logical newline (\n)
+c \n d abc\n\rdef n logical newline matches \n\r
+# todo :pugs<feature>
+c \n d abc\r\ndef y logical newline matches \r\n
b \n c abc\ndef n logical newline (\n)
\N a y not logical newline (\N)
a \N c abc y not logical newline (\N)
\N '' n not logical newline (\N)
c \N d abc\ndef n not logical newline (\N)
-c \N d abc\x0adef n not logical newline (\N)
-c \N d abc\x0ddef n not logical newline (\N)
+c \N d abc\rdef n not logical newline (\N)
c \N+ d abc\n\ndef n not logical newline (\N)
a\N+f abcdef y not logical newline (\N)
-c \N d abc\x0a\x0ddef n not logical newline (\N)
-c \N d abc\x0d\x0adef n not logical newline (\N)
+c \N d abc\n\rdef n not logical newline (\N)
+c \N d abc\r\ndef n not logical newline (\N)
b \N \n abc\ndef y not logical newline (\N)
-\Aabc Aabc y retired metachars (\A)
-\Aabc abc\ndef n retired metachars (\A)
-abc\Z abcZ y retired metachars (\Z)
-abc\Z abc\ndef n retired metachars (\Z)
-abc\z abcz y retired metachars (\z)
-def\z abc\ndef n retired metachars (\z)
+\Aabc Aabc /reserved/ retired metachars (\A)
+\Aabc abc\ndef /reserved/ retired metachars (\A)
+abc\Z abcZ /reserved/ retired metachars (\Z)
+abc\Z abc\ndef /reserved/ retired metachars (\Z)
+abc\z abcz /reserved/ retired metachars (\z)
+def\z abc\ndef /reserved/ retired metachars (\z)
abc # def abc#def y comments (#)
abc # xyz abc#def y comments (#)
abc # def \n \$ abc#def y comments (#)
@@ -59,70 +61,85 @@
abc \# xyz abc#def n comments (#)
^ abc \# def $ abc#def y comments (#)
^^ abc \n ^^ def abc\ndef y line beginnings and endings (^^)
+# todo :pugs<feature>
^^ abc \n ^^ def \n ^^ abc\ndef\n n line beginnings and endings (^^)
^^ \n \n y line beginnings and endings (^^)
+# todo :pugs<feature>
\n ^^ \n n line beginnings and endings (^^)
abc $$ \n def $$ abc\ndef y line beginnings and endings ($$)
+# todo :pugs<feature>
abc $$ \n def $$ \n $$ abc\ndef\n n line beginnings and endings ($$)
$$ \n \n y line beginnings and endings ($$)
+# todo :pugs<feature>
\n $$ \n n line beginnings and endings ($$)
<[a..d]> | <[b..e]> c y alternation (|)
<[a..d]> | <[d..e]> c y alternation (|)
<[a..b]> | <[b..e]> c y alternation (|)
<[a..b]> | <[d..e]> c n alternation (|)
<[a..d]>+ | <[b..e]>+ bcd y alternation (|)
-^<[a..d]>+ | <[b..e]>+$ bcd y alternation (|)
-<[a..c]>+ | <[b..e]>+ bcd y alternation (|)
-<[a..d]>+ | <[c..e]>+ bcd y alternation (|)
+^ [ <[a..d]>+ | <[b..e]>+ ] $ bcd y alternation (|)
+^ [ <[a..c]>+ | <[b..e]>+ ] $ bcd y alternation (|)
+^ [ <[a..d]>+ | <[c..e]>+ ] $ bcd y alternation (|)
b| bcd /rule error/ alternation (|) - null
right arg illegal
-|b bcd /Missing term/ alternation (|) - null
left arg illegal
-| bcd /Missing term/ alternation (|) - null
both args illegal
+|b bcd y alternation (|) - null left arg
ignored
+| bcd /rule error/ alternation (|) - null
both args illegal
\| | y alternation (|) - literal must
be escaped
-| | n alternation (|) - literal must
be escaped
+| | /rule error/ alternation (|) -
literal must be escaped
+# todo :pugs<feature>
<[a..d]> & <[b..e]> c y conjunction (&)
<[a..d]> & <[d..e]> c n conjunction (&)
<[a..b]> & <[b..e]> c n conjunction (&)
<[a..b]> & <[d..e]> c n conjunction (&)
+# todo :pugs<feature>
<[a..d]>+ & <[b..e]>+ bcd y conjunction (&)
-^<[a..d]>+ & <[b..e]>+$ bcd y conjunction (&)
+# todo :pugs<feature>
+^ [ <[a..d]>+ & <[b..e]>+ ] $ bcd y conjunction (&)
+# todo :pugs<feature>
<[a..c]>+ & <[b..e]>+ bcd y conjunction (&)
+# todo :pugs<feature>
<[a..d]>+ & <[c..e]>+ bcd y conjunction (&)
b& bcd /rule error/ conjunction (&) - null
right arg illegal
-&b bcd /Missing term/ conjunction (&) - null
left arg illegal
-& bcd /Missing term/ conjunction (&) - null
both args illegal
+&b bcd /rule error/ conjunction (&) - null
left arg illegal
+& bcd /rule error/ conjunction (&) - null
both args illegal
\& & y conjunction (&) - literal must
be escaped
-& & n conjunction (&) - literal must
be escaped
-a&|b a&|b /Missing term/ alternation and
conjunction (&|) - parse error
-a|&b a|&b /Missing term/ alternation and
conjunction (|&) - parse error
+& & /rule error/ conjunction (&) -
literal must be escaped
+# todo :pge<leading |>
+a&|b a&|b /rule error/ alternation and
conjunction (&|) - parse error
+a|&b a|&b /rule error/ alternation and
conjunction (|&) - parse error
|d|b abc y leading alternation ignored
|d|b abc y leading alternation ignored
|d |b abc y leading alternation ignored
| d | b abc y leading alternation ignored
+# todo :pugs<feature> :pge<feature>
b | | d abc n null pattern invalid
-\pabc pabc y retired metachars (\p)
-\p{InConsonant} a n retired metachars (\p)
-\Pabc Pabc y retired metachars (\P)
-\P{InConsonant} a n retired metachars (\P)
-\Labc\E LabcE y retired metachars
(\L...\E)
-\LABC\E abc n retired metachars
(\L...\E)
-\Uabc\E UabcE y retired metachars
(\U...\E)
-\Uabc\E ABC n retired metachars
(\U...\E)
-\Qabc\E QabcE y retired metachars
(\Q...\E)
-\Qabc d?\E abc d n retired metachars (\Q...\E)
-\Gabc Gabc y retired metachars (\G)
-\1abc 1abc y retired metachars (\1)
-^ \s+ $
\u0009\u0020\u00a0\u000a\u000b\u000c\u000d\u0085 y 0-255
whitespace (\s)
-^ \h+ $ \u0009\u0020\u00a0 y 0-255
horizontal whitespace (\h)
-^ \v+ $ \u000a\u000b\u000c\u000d\u0085 y 0-255
vertical whitespace (\v)
-^ \h+ $ \u000a\u000b\u000c\u000d\u0085 n 0-255
horizontal whitespace (\h)
-^ \v+ $ \u0009\u0020\u00a0 n 0-255 vertical
whitespace (\v)
-^ \s+ $
\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2008\u2009\u200a\u202f\u205f\u3000\u000a\u000b\u000c\u000d\u0085
y unicode whitespace (\s)
-^ \h+ $
\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2008\u2009\u200a\u202f\u205f\u3000
y unicode whitespace (\h)
-^ \v+ $ \u000a\u000b\u000c\u000d\u0085 y unicode
whitespace (\v)
-^ \h+ $ \u000a\u000b\u000c\u000d\u0085 n unicode
whitespace (\h)
-^ \v+ $
\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2008\u2009\u200a\u202f\u205f\u3000
n unicode whitespace (\v)
+\pabc pabc /reserved/ retired metachars (\p)
+\p{InConsonant} a /reserved/ retired
metachars (\p)
+\Pabc Pabc /reserved/ retired metachars (\P)
+\P{InConsonant} a /reserved/ retired
metachars (\P)
+\Labc\E LabcE /reserved/ retired
metachars (\L...\E)
+\LABC\E abc /reserved/ retired
metachars (\L...\E)
+\Uabc\E UabcE /reserved/ retired
metachars (\U...\E)
+\Uabc\E ABC /reserved/ retired
metachars (\U...\E)
+\Qabc\E QabcE /reserved/ retired
metachars (\Q...\E)
+\Qabc d?\E abc d /reserved/ retired metachars
(\Q...\E)
+\Gabc Gabc /reserved/ retired metachars (\G)
+\1abc 1abc /reserved/ retired metachars (\1)
+# todo :pugs<feature>
+^ \s+ $
\x0009\x0020\x00a0\x000a\x000b\x000c\x000d\x0085 y 0-255
whitespace (\s)
+# todo :pugs<feature>
+^ \h+ $ \x0009\x0020\x00a0 y 0-255
horizontal whitespace (\h)
+^ \V+ $ \x0009\x0020\x00a0 y 0-255
horizontal whitespace (\V)
+# todo :pugs<feature>
+^ \v+ $ \x000a\x000b\x000c\x000d\x0085 y 0-255
vertical whitespace (\v)
+^ \h+ $ \x000a\x000b\x000c\x000d\x0085 n 0-255
horizontal whitespace (\h)
+^ \v+ $ \x0009\x0020\x00a0 n 0-255 vertical
whitespace (\v)
+# todo :pugs<feature>
+^ \s+ $
\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2008\x2009\x200a\x202f\x205f\x3000
y unicode whitespace (\s)
+# todo :pugs<feature>
+^ \h+ $
\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2008\x2009\x200a\x202f\x205f\x3000
y unicode whitespace (\h)
+^ \V+ $
\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2008\x2009\x200a\x202f\x205f\x3000
y unicode whitespace (\V)
+^ \v+ $
\x1680\x180e\x2000\x2001\x2002\x2003\x2004\x2005\x2006\x2007\x2008\x2008\x2009\x200a\x202f\x205f\x3000
n unicode whitespace (\v)
c \t d abc\tdef y horizontal tab (\t)
-c \t d abc\x09def y horizontal tab (\t)
c \t+ d abc\t\tdef y horizontal tab (\t)
a \t+ f abcdef n horizontal tab (\t)
b \t c abc\tdef n horizontal tab (\t)
@@ -130,11 +147,9 @@
a \T c abc y not horizontal tab (\T)
\T '' n not horizontal tab (\T)
c \T d abc\tdef n not horizontal tab (\T)
-c \T d abc\x09def n not horizontal tab (\T)
c \T+ d abc\t\tdef n not horizontal tab (\T)
a \T+ f abcdef y not horizontal tab (\T)
c \r d abc\rdef y return (\r)
-c \r d abc\x0ddef y return (\r)
c \r+ d abc\r\rdef y return (\r)
a \r+ f abcdef n return (\r)
b \r c abc\rdef n return (\r)
@@ -142,11 +157,9 @@
a \R c abc y not return (\R)
\R '' n not return (\R)
c \R d abc\rdef n not return (\R)
-c \R d abc\x0ddef n not return (\R)
c \R+ d abc\r\rdef n not return (\R)
a \R+ f abcdef y not return (\R)
c \f d abc\fdef y formfeed (\f)
-c \f d abc\x0cdef y formfeed (\f)
c \f+ d abc\f\fdef y formfeed (\f)
a \f+ f abcdef n formfeed (\f)
b \f c abc\fdef n formfeed (\f)
@@ -154,45 +167,65 @@
a \F c abc y not formfeed (\F)
\F '' n not formfeed (\F)
c \F d abc\fdef n not formfeed (\F)
-c \F d abc\x0cdef n not formfeed (\F)
c \F+ d abc\f\fdef n not formfeed (\F)
a \F+ f abcdef y not formfeed (\F)
+# todo :pugs<feature>
c \e d abc\edef y escape (\e)
-c \e d abc\x1bdef y escape (\e)
+# todo :pugs<feature>
c \e+ d abc\e\edef y escape (\e)
a \e+ f abcdef n escape (\e)
b \e c abc\edef n escape (\e)
\E a y not escape (\E)
a \E c abc y not escape (\E)
\E '' n not escape (\E)
+# todo :pugs<feature>
c \E d abc\edef n not escape (\E)
-c \E d abc\x1bdef n not escape (\E)
+# todo :pugs<feature>
c \E+ d abc\e\edef n not escape (\E)
a \E+ f abcdef y not escape (\E)
c \x0021 d abc!def y hex (\x)
-c \x0021 d abc\x21def y hex (\x)
c \x0021+ d abc!!def y hex (\x)
a \x0021+ f abcdef n hex (\x)
b \x0021 c abc!def n hex (\x)
+c \x[0021] d abc!def y hex (\x[])
+c \x[0021]+ d abc!!def y hex (\x[])
+c \x[21,21] d abc!!def y hex (\x[])
+a \x[0021]+ f abcdef n hex (\x[])
+b \x[0021] c abc!def n hex (\x[])
\X0021 a y not hex (\X)
a \X0021 c abc y not hex (\X)
\X0021 '' n not hex (\X)
c \X0021 d abc!def n not hex (\X)
-c \X0021 d abc\x21def n not hex (\X)
c \X0021+ d abc!!def n not hex (\X)
a \X0021+ f abcdef y not hex (\X)
+\X[0021] a y not hex (\X[])
+a \X[0021] c abc y not hex (\X[])
+\X[0021] '' n not hex (\X[])
+c \X[0021] d abc!def n not hex (\X[])
+c \X[0021]+ d abc!!def n not hex (\X[])
+a \X[0021]+ f abcdef y not hex (\X[])
c \o041 d abc!def y octal (\o)
-c \o41 d abc\x21def y octal (\o)
c \o41+ d abc!!def y octal (\o)
a \o41+ f abcdef n octal (\o)
b \o41 c abc!def n octal (\o)
+c \o[41] d abc!def y octal (\o[])
+c \o[41]+ d abc!!def y octal (\o[])
+# todo :pugs<feature>
+c \o[41,41] d abc!!def y octal (\o[])
+a \o[41]+ f abcdef n octal (\o[])
+b \o[41] c abc!def n octal (\o[])
\O41 a y not octal (\O)
a \O41 c abc y not octal (\O)
\O41 '' n not octal (\O)
c \O41 d abc!def n not octal (\O)
-c \O41 d abc\x21def n not octal (\O)
c \O41+ d abc!!def n not octal (\O)
a \O41+ f abcdef y not octal (\O)
+\O[41] a y not octal (\O[])
+a \O[41] c abc y not octal (\O[])
+\O[41] '' n not octal (\O[])
+c \O[41] d abc!def n not octal (\O[])
+c \O[41]+ d abc!!def n not octal (\O[])
+a \O[41]+ f abcdef y not octal (\O[])
a\w+f a=[ *f n word character
a\w+f abcdef y word character
a\W+f a&%- f y not word character