diff --git a/src/QRegex/P5Regex/Actions.nqp b/src/QRegex/P5Regex/Actions.nqp index cc97d3b339..29c1b59e56 100644 --- a/src/QRegex/P5Regex/Actions.nqp +++ b/src/QRegex/P5Regex/Actions.nqp @@ -84,6 +84,64 @@ class QRegex::P5Regex::Actions is HLL::Actions { ); } + method p5metachar:sym<[ ]>($/) { + make $.ast; + } + + method cclass($/) { + my $str := ''; + my $qast; + my @alts; + for $ { + if $_[1] { + my $node; + my $lhs; + my $rhs; + if $_[0] { + $node := $_[0].ast; + $/.CURSOR.panic("Illegal range endpoint in regex: " ~ ~$_) + if $node.rxtype ne 'literal' && $node.rxtype ne 'enumcharlist' + || $node.negate || nqp::chars($node[0]) != 1; + $lhs := $node[0]; + } + else { + $lhs := ~$_[0][0]; + } + if $_[1][0] { + $node := $_[1][0].ast; + $/.CURSOR.panic("Illegal range endpoint in regex: " ~ ~$_) + if $node.rxtype ne 'literal' && $node.rxtype ne 'enumcharlist' + || $node.negate || nqp::chars($node[0]) != 1; + $rhs := $node[0]; + } + else { + $rhs := ~$_[1][0][0]; + } + my $ord0 := nqp::ord($lhs); + my $ord1 := nqp::ord($rhs); + $/.CURSOR.panic("Illegal reversed character range in regex: " ~ ~$_) + if $ord0 > $ord1; + $str := nqp::concat($str, nqp::chr($ord0++)) while $ord0 <= $ord1; + } + elsif $_[0] { + my $bs := $_[0].ast; + $bs.negate(!$bs.negate) if $ eq '^'; + @alts.push($bs); + } + else { $str := $str ~ ~$_[0]; } + } + @alts.push(QAST::Regex.new( $str, :rxtype, :node($/), :negate( $ eq '^' ) )) + if nqp::chars($str); + $qast := +@alts == 1 ?? @alts[0] !! + $ eq '^' ?? + QAST::Regex.new( :rxtype, :node($/), + QAST::Regex.new( :rxtype, :subtype, |@alts ), + QAST::Regex.new( :rxtype, :subtype<.> ) ) !! + QAST::Regex.new( :rxtype, |@alts ); + make $qast; + } + + method p5quantifier:sym<*>($/) { my $qast := QAST::Regex.new( :rxtype, :min(0), :max(-1), :node($/) ); make quantmod($qast, $); @@ -354,31 +412,6 @@ class QRegex::P5Regex::Actions is HLL::Actions { } make $qast; } - - method assertion:sym<[>($/) { - my $clist := $; - my $qast := $clist[0].ast; - if $qast.negate && $qast.rxtype eq 'subrule' { - $qast.subtype('zerowidth'); - $qast := QAST::Regex.new(:rxtype, :node($/), - $qast, - QAST::Regex.new( :rxtype, :subtype<.> )); - } - my $i := 1; - my $n := +$clist; - while $i < $n { - my $ast := $clist[$i].ast; - if $ast.negate { - $ast.subtype('zerowidth'); - $qast := QAST::Regex.new( $ast, $qast, :rxtype, :node($/)); - } - else { - $qast := QAST::Regex.new( $qast, $ast, :rxtype, :node($/)); - } - $i++; - } - make $qast; - } method arg($/) { make $ ?? $.ast !! +$; @@ -390,73 +423,6 @@ class QRegex::P5Regex::Actions is HLL::Actions { make $past; } - method cclass_elem($/) { - my $str := ''; - my $qast; - if $ { - my $name := ~$; - $qast := QAST::Regex.new( PAST::Node.new($name), :rxtype, :subtype, - :negate( $ eq '-' ), :node($/) ); - } - elsif $ { - my $uniprop := ~$; - $qast := QAST::Regex.new( $uniprop, :rxtype, - :negate( $ eq '-' && $ ne '!' # $ ^^ $ - || $ ne '-' && $ eq '!' ), :node($/) ); - } - else { - my @alts; - for $ { - if $_[1] { - my $node; - my $lhs; - my $rhs; - if $_[0] { - $node := $_[0].ast; - $/.CURSOR.panic("Illegal range endpoint in regex: " ~ ~$_) - if $node.rxtype ne 'literal' && $node.rxtype ne 'enumcharlist' - || $node.negate || nqp::chars($node[0]) != 1; - $lhs := $node[0]; - } - else { - $lhs := ~$_[0][0]; - } - if $_[1][0] { - $node := $_[1][0].ast; - $/.CURSOR.panic("Illegal range endpoint in regex: " ~ ~$_) - if $node.rxtype ne 'literal' && $node.rxtype ne 'enumcharlist' - || $node.negate || nqp::chars($node[0]) != 1; - $rhs := $node[0]; - } - else { - $rhs := ~$_[1][0][0]; - } - my $ord0 := nqp::ord($lhs); - my $ord1 := nqp::ord($rhs); - $/.CURSOR.panic("Illegal reversed character range in regex: " ~ ~$_) - if $ord0 > $ord1; - $str := nqp::concat($str, nqp::chr($ord0++)) while $ord0 <= $ord1; - } - elsif $_[0] { - my $bs := $_[0].ast; - $bs.negate(!$bs.negate) if $ eq '-'; - @alts.push($bs); - } - else { $str := $str ~ ~$_[0]; } - } - @alts.push(QAST::Regex.new( $str, :rxtype, :node($/), :negate( $ eq '-' ) )) - if nqp::chars($str); - $qast := +@alts == 1 ?? @alts[0] !! - $ eq '-' ?? - QAST::Regex.new( :rxtype, :node($/), - QAST::Regex.new( :rxtype, :subtype, |@alts ), - QAST::Regex.new( :rxtype, :subtype<.> ) ) !! - QAST::Regex.new( :rxtype, |@alts ); - } - #$qast.negate( $ eq '-' ); - make $qast; - } - method mod_internal($/) { my $n := $[0] gt '' ?? +$[0] !! 1; %*RX{ ~$ } := $n; diff --git a/src/QRegex/P5Regex/Grammar.nqp b/src/QRegex/P5Regex/Grammar.nqp index 6337ae645a..1105b93600 100644 --- a/src/QRegex/P5Regex/Grammar.nqp +++ b/src/QRegex/P5Regex/Grammar.nqp @@ -56,6 +56,20 @@ grammar QRegex::P5Regex::Grammar is HLL::Grammar { token p5metachar:sym<$> { '$' } + token p5metachar:sym<[ ]> { } + + token cclass { + '[' + $=['^'|] + $=( + \s* ( '\\' || (<-[\]\\]>) ) + [ + \s* '-' \s* + ( '\\' || (<-[\]\\]>) ) + ]? + )* + \s* ']' + } proto token p5backslash { <...> } @@ -161,27 +175,6 @@ grammar QRegex::P5Regex::Grammar is HLL::Grammar { ]? } - token assertion:sym<[> { + } - - token cclass_elem { - $=['+'|'-'|] - <.normspace>? - [ - | '[' $=( - || \s* '-' <.obs: '- as character range','.. for range, for explicit - in character class, escape it or place as last thing'> - || \s* ( '\\' || (<-[\]\\]>) ) - [ - \s* '..' \s* - ( '\\' || (<-[\]\\]>) ) - ]? - )* - \s* ']' - | $=[\w+] - | ':' $=['!'|] $=[\w+] - ] - <.normspace>? - } - token mod_internal { [ | ':' $=('!' | \d+)**1 ยป