use Data::Dumper; use YAPE::Regex::Explain; print "regex explanation:\n"; print "\t",YAPE::Regex::Explain->new(qr{s/\*/ && /})->explain; print "\t",YAPE::Regex::Explain->new(qr{s/\+/ || /})->explain; print "\t",YAPE::Regex::Explain->new(qr{s/(\w+)\s*'/!$1/g})->explain; print "\t",YAPE::Regex::Explain->new(qr{\((?:(?>[^()]+)|(??{$re}))*\)})->explain; print "processing DATA:\n"; while(){ chomp; # added by me print "\n\t-->received [$_]\n"; my ($re, $term, @vars, %vars, $loops); s/\*/ && /g; print "\t-->after first regex [$_]\n"; s/\+/ || /g; print "\t-->after second regex [$_]\n"; s/(\w+)\s*'/!$1/g; print "\t-->after third regex [$_]\n"; $re = qr{\((?:(?>[^()]+)|(??{$re}))*\)}; # :-) s/($re)\s*'/!$1/g; print "\t-->after fourth regex [$_]\n"; $term = $_; print "\t-->\$term is [$term]\n"; @vars = $_ =~ m/(\w+)/g; print "\t\@vars is [@vars]\n"; $vars{$_}++ for @vars; print "\t-->\%vars is :\n"; print "\t\t", Dumper \%vars; @vars = sort keys %vars; print "\t-->\@vars is [@vars]\n"; s/(\w+)/\$$1/g; print "\t-->\$_ is [$_]\n"; printf "\n@vars = $term"; @vars = map {"\$$_"}@vars; print "\n\t-->\@vars is [@vars]\n"; $loops .= "for $_ (0..1) {\n" for @vars; print "\t-->\$loops is [$loops]\n"; $loops .= qq{printf "@vars = %d\n", eval;\n}; print "\t-->\$loops is [$loops]\n"; $loops .= "}" for @vars; print "\t-->\$loops is [$loops]\n\n\n"; do{ no strict 'vars'; eval $loops }; die "Can't process $term$_\n$@\n" if $@; } __DATA__ a*b*!(c) a'+b'+c' !(a*b) b^a (a^b)' (a+(a+b))'*c #### regex explanation: The regular expression: (?-imsx:s/\*/ && /) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- s/ 's/' ---------------------------------------------------------------------- \* '*' ---------------------------------------------------------------------- / && / '/ && /' ---------------------------------------------------------------------- ) end of grouping ---------------------------------------------------------------------- The regular expression: (?-imsx:s/\+/ || /) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- s/ 's/' ---------------------------------------------------------------------- \+ '+' ---------------------------------------------------------------------- / '/ ' ---------------------------------------------------------------------- | OR ---------------------------------------------------------------------- | OR ---------------------------------------------------------------------- / ' /' ---------------------------------------------------------------------- ) end of grouping ---------------------------------------------------------------------- The regular expression: (?-imsx:s/(\w+)\s*'/!/g) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- s/ 's/' ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- \w+ word characters (a-z, A-Z, 0-9, _) (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- \s* whitespace (\n, \r, \t, \f, and " ") (0 or more times (matching the most amount possible)) ---------------------------------------------------------------------- '/!/g '\'/!/g' ---------------------------------------------------------------------- ) end of grouping ---------------------------------------------------------------------- The regular expression: (?-imsx:\((?:(?>[^()]+)|(??{$re}))*\)) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- \( '(' ---------------------------------------------------------------------- (?: group, but do not capture (0 or more times (matching the most amount possible)): ---------------------------------------------------------------------- (?> match (and do not backtrack afterwards): ---------------------------------------------------------------------- [^()]+ any character except: '(', ')' (1 or more times (matching the most amount possible)) ---------------------------------------------------------------------- ) end of look-ahead ---------------------------------------------------------------------- | OR ---------------------------------------------------------------------- (??{$re}) run this block of Perl code (that isn't interpolated until RIGHT NOW) ---------------------------------------------------------------------- )* end of grouping ---------------------------------------------------------------------- \) ')' ---------------------------------------------------------------------- ) end of grouping ---------------------------------------------------------------------- processing DATA: -->received [a*b*!(c)] -->after first regex [a && b && !(c)] -->after second regex [a && b && !(c)] -->after third regex [a && b && !(c)] -->after fourth regex [a && b && !(c)] -->$term is [a && b && !(c)] @vars is [a b c] -->%vars is : $VAR1 = { 'c' => 1, 'a' => 1, 'b' => 1 }; -->@vars is [a b c] -->$_ is [$a && $b && !($c)] a b c = a && b && !(c) -->@vars is [$a $b $c] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; }}}] 0 0 0 = 0 0 0 1 = 0 0 1 0 = 0 0 1 1 = 0 1 0 0 = 0 1 0 1 = 0 1 1 0 = 1 1 1 1 = 0 -->received [a'+b'+c'] -->after first regex [a'+b'+c'] -->after second regex [a' || b' || c'] -->after third regex [!a || !b || !c] -->after fourth regex [!a || !b || !c] -->$term is [!a || !b || !c] @vars is [a b c] -->%vars is : $VAR1 = { 'c' => 1, 'a' => 1, 'b' => 1 }; -->@vars is [a b c] -->$_ is [!$a || !$b || !$c] a b c = !a || !b || !c -->@vars is [$a $b $c] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; }}}] 0 0 0 = 1 0 0 1 = 1 0 1 0 = 1 0 1 1 = 1 1 0 0 = 1 1 0 1 = 1 1 1 0 = 1 1 1 1 = 0 -->received [!(a*b)] -->after first regex [!(a && b)] -->after second regex [!(a && b)] -->after third regex [!(a && b)] -->after fourth regex [!(a && b)] -->$term is [!(a && b)] @vars is [a b] -->%vars is : $VAR1 = { 'a' => 1, 'b' => 1 }; -->@vars is [a b] -->$_ is [!($a && $b)] a b = !(a && b) -->@vars is [$a $b] -->$loops is [for $a (0..1) { for $b (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; }}] 0 0 = 1 0 1 = 1 1 0 = 1 1 1 = 0 -->received [b^a] -->after first regex [b^a] -->after second regex [b^a] -->after third regex [b^a] -->after fourth regex [b^a] -->$term is [b^a] @vars is [b a] -->%vars is : $VAR1 = { 'a' => 1, 'b' => 1 }; -->@vars is [a b] -->$_ is [$b^$a] a b = b^a -->@vars is [$a $b] -->$loops is [for $a (0..1) { for $b (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; }}] 0 0 = 0 0 1 = 1 1 0 = 1 1 1 = 0 -->received [(a^b)'] -->after first regex [(a^b)'] -->after second regex [(a^b)'] -->after third regex [(a^b)'] -->after fourth regex [!(a^b)] -->$term is [!(a^b)] @vars is [a b] -->%vars is : $VAR1 = { 'a' => 1, 'b' => 1 }; -->@vars is [a b] -->$_ is [!($a^$b)] a b = !(a^b) -->@vars is [$a $b] -->$loops is [for $a (0..1) { for $b (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { printf "$a $b = %d ", eval; }}] 0 0 = 1 0 1 = 0 1 0 = 0 1 1 = 1 -->received [(a+(a+b))'*c] -->after first regex [(a+(a+b))' && c] -->after second regex [(a || (a || b))' && c] -->after third regex [(a || (a || b))' && c] -->after fourth regex [!(a || (a || b)) && c] -->$term is [!(a || (a || b)) && c] @vars is [a a b c] -->%vars is : $VAR1 = { 'c' => 1, 'a' => 2, 'b' => 1 }; -->@vars is [a b c] -->$_ is [!($a || ($a || $b)) && $c] a b c = !(a || (a || b)) && c -->@vars is [$a $b $c] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; ] -->$loops is [for $a (0..1) { for $b (0..1) { for $c (0..1) { printf "$a $b $c = %d ", eval; }}}] 0 0 0 = 0 0 0 1 = 1 0 1 0 = 0 0 1 1 = 0 1 0 0 = 0 1 0 1 = 0 1 1 0 = 0 1 1 1 = 0