<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#!/usr/bin/perl -sw

# RPN ARITHMETIC EXPRESSIONS

use Parse::RecDescent;

sub Parse::RecDescent::rpn
{
	my @list = @_;
	for (my $i=1; $i&lt;@list; $i+=2)
	{
		@list[$i,$i+1] = @list[$i+1,$i];
	}
	join " ", @list;
}

# $RD_TRACE=1;

$grammar =
q{
	expr	:	&lt;leftop: conj /(\|\|)/ conj&gt;
				{ rpn(@{$item[1]}) }

	conj	:	&lt;leftop: addn /(&amp;&amp;)/ addn&gt;
				{ rpn(@{$item[1]}) }

	addn	:	&lt;leftop: mult /([+-])/ mult &gt;
				{ rpn(@{$item[1]}) }

	mult	:	&lt;leftop: expo /([*\/\%])/ expo &gt;
				{ rpn(@{$item[1]}) }

	expo	:	&lt;leftop: unary /(\^|\*\*)/ unary &gt;
				{ rpn(@{$item[1]}) }

	unary	:	'(' expr ')'	{ $item[2] }
		|	value

	value	:	/\d+(\.\d+)?/
};

$parse = new Parse::RecDescent ($grammar) or die "bad grammar";

while (&lt;&gt;)
{
	print $parse-&gt;expr($_), "\n" if $_;
}
</pre></body></html>