Обходное решение ikegami выше с DEFINE прекрасно, но оно не отвечает на вопрос, как это сделать по-моему. Минимальное изменение моего кода, чтобы заставить его работать? Икегами прав, причина несоответствия - ^ in / ^ $ expr $ /. Когда синтаксический анализатор повторно вводит регулярное выражение рекурсивно, он снова проверяет начало строки, что завершается ошибкой. Так что я не могу иметь ^ и $ в регулярном выражении, кажется. Без них мои строки совпадают. Но тогда некоторые недопустимые строки также совпадают, например, A (1 + 2) * (3 + 4) B. В отсутствие ^ и $ это не обязательно соответствует всей строке. Проблема.
Икегами предложил решение этой проблемы в комментарии выше. Я просто напишу это. Я проверил это, и оно работает:
$number = '\d+';
$atom = "($number|\\((?1)\\))";
$product = "$atom(\\*$atom)*";
$sum = "$product(\\+$product)*";
$expr = $sum;
if ('(1+2)*(3+4)' =~ /^($expr)$/)
{
print "OK";
}
Обратите внимание, что теперь у меня есть (? 1) вместо (? R) и что я заключил $ expr в скобки. (? 1) относится к первой группе захвата, которая ($ expr). Таким образом, рекурсия возвращается в этот подэкс вместо всего регулярного выражения. ^ не встретил снова. Это решает это.