How to add implicit multiplication to PHP PEG basic calculator grammar?

48 views Asked by At

I have a problem with my PEG grammar in PHP that use php-peg (the project have more recent fork that is publish to packagist). My project is a fork of an expression parser that I want to replace with a generated parser that is way easier to modify.

Everything works well so far, but I have a problem adding implicit multiplication which is part of the original project features.

It looks like this:

8(5/2)

it should implicitly multiply 8 by the fraction.

My grammar so far has a lot of features, but I only want to know how to add implicit multiplication to a basic calculator example that looks like this:

Number: /[0-9]+/
Value: Number > | '(' > Expr > ')' >
    function Number( &$result, $sub ) {
        $result['val'] = $sub['text'] ;
    }
    function Expr( &$result, $sub ) {
        $result['val'] = $sub['val'] ;
    }

Times: '*' > operand:Value >
Div: '/' > operand:Value >
Product: Value > ( Times | Div ) *
    function Value( &$result, $sub ) {
        $result['val'] = $sub['val'] ;
    }
    function Times( &$result, $sub ) {
        $result['val'] *= $sub['operand']['val'] ;
    }
    function Div( &$result, $sub ) {
        $result['val'] /= $sub['operand']['val'] ;
    }

Plus: '+' > operand:Product >
Minus: '-' > operand:Product >
Sum: Product > ( Plus | Minus ) *
    function Product( &$result, $sub ) {
        $result['val'] = $sub['val'] ;
    }
    function Plus( &$result, $sub ) {
        $result['val'] += $sub['operand']['val'] ;
    }
    function Minus( &$result, $sub ) {
        $result['val'] -= $sub['operand']['val'] ;
    }

Expr: Sum
    function Sum( &$result, $sub ) {
        $result['val'] = $sub['val'] ;
    }

Located in project examples directory.

I've created basic calculator example project on GitHub.

1

There are 1 answers

0
Olivier On BEST ANSWER

I would try changing the Product rule to this:

Times: '*' > operand:Value >
ImplicitTimes: operand:Value >
Div: '/' > operand:Value >
Product: Value > ( Times | ImplicitTimes | Div ) *
    function Value( &$result, $sub ) {
        $result['val'] = $sub['val'] ;
    }
    function Times( &$result, $sub ) {
        $result['val'] *= $sub['operand']['val'] ;
    }
    function ImplicitTimes( &$result, $sub ) {
        $result['val'] *= $sub['operand']['val'] ;
    }
    function Div( &$result, $sub ) {
        $result['val'] /= $sub['operand']['val'] ;
    }