As part of my plan to create a macro system for Prolog (think "Prolog source filter"), I've finally managed to create a regex that will match complicated Prolog math functions. Don't print out the final regex. Your eyes will hurt.
#!/usr/bin/perl
use warnings; use strict; use Regexp::Common;
my $var = qr/[[:upper:]][[:alnum:]_]*/; my $num = $RE{num}{real}; my $anon = '_'; my $simple_math_term = qr/(?:$num|$var|$anon)/; my $op = qr{[-+*/%]}; my $compare = qr/(?:=|is|[<>]=?)/; my $lp = qr/\(/; my $rp = qr/\)/;
my $simple_rhs = qr/ $simple_math_term \s* (?: $op \s* $simple_math_term \s* )* /x; my $simple_group_term = qr/$lp\s*$simple_rhs\s*$rp/;
my $math_term = qr/(?:$simple_math_term|$simple_group_term)/; my $complex_rhs = qr/ $math_term \s* (?: $op \s* $math_term \s* )* /x; my $complex_group_term = qr/$lp\s*$complex_rhs\s*$rp/; my $final_math_term = qr/(?:$math_term|$complex_group_term)/; my $rhs = qr/ $final_math_term \s* (?: $op \s* $final_math_term \s* )* /x;
my $expression = qr/ ($simple_math_term) \s+ ($compare) \s+ ($rhs) (?=[,.]) /x; print $expression;
# FrobNitz is 9 / (3 + (4+7) % ModValue) + 2 / (3+7).