while(){ my ($re, $term, @vars, %vars, $loops); s/\*/ && /g; s/\+/ || /g; s/(\w+)\s*'/!$1/g; $re = qr{\((?:(?>[^()]+)|(??{$re}))*\)}; # :-) s/($re)\s*'/!$1/g; $term = $_; @vars = $_ =~ m/(\w+)/g; $vars{$_}++ for @vars; @vars = sort keys %vars; s/(\w+)/\$$1/g; printf "\n@vars = $term"; @vars = map {"\$$_"}@vars; $loops .= "for $_ (0..1) {\n" for @vars; $loops .= qq{printf "@vars = %d\n", eval;\n}; $loops .= "}" for @vars; 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