Directives: commit
{my %variables}
start: statement /^\Z/ {$variables {'.'} = $item [1]}
statement: variable '=' <commit> statement
{$variables {$item [1]} = $item [4]}
| expression
expression: <leftop: term ('+' | '-') term>
{my $s = shift @{$item [1]};
while (@{$item [1]}) {
my ($op, $exp) = splice @{$item [1]}, 0, 2;
if ($op eq '+') {$s += $exp}
else {$s -= $exp}
}
$s
}
term: <leftop: factor m{([*/])} factor>
{my $p = shift @{$item [1]};
while (@{$item [1]}) {
my ($op, $term) = splice @{$item [1]}, 0, 2;
if ($op eq '*') {$p *= $term}
else {$p /= $term}
}
$p
}
factor: number
| variable {$variables {$item [1]} ||=
Math::BigInt -> new (0)}
| '+' <commit> factor {$item [3]}
| '-' <commit> factor {$item [3] * -1}
| '(' <commit> statement ')'
{$item [3]}
number: /\d+/ {Math::BigInt -> new ($item [1])}
variable: /[.a-z]+/i
- The <commit> directive tells the parser
that once this directive has been matched, none of the subsequent
productions need to be tried if the current production fails.
- <commit> always matches, and its
return value is 1.
- Benefit: less backtracking, hence more efficient.
- One can <uncommit> as well.
[Prev]
[Next]
[Index]