http://www.perlmonks.org?node_id=423871


in reply to Re^2: Generic RPN Translator available?
in thread Generic RPN Translator available?

Update: Looks like I spoke too soon:
"sin(ab)"
yields
sin, a, b
instead of the correct
sin, ab
Hmmm ...

Actually, I was looking for exactly the solution browserUK provided. Outstanding job, browserUK! It even works for nested function calls like

"max(min(a,b-c), c, min(d-f,e) ) * atan( pi*4, -1 )"
which gets transformed to
a, b, c, -, min, c, d, f, -, e, min, max, pi, 4, *, -1, atan, *
Now, anyone up for a Parse::Descent grammar, just for kicks :) ?

Replies are listed 'Best First'.
Re^4: Generic RPN Translator available?
by BrowserUk (Patriarch) on Jan 21, 2005 at 06:15 UTC

    Fixed. Update: But it still has another bug!..

    P:\test>423305 -XLATE 1+2+3 1, 2, ADD, 3, ADD a+b+c a, b, ADD, c, ADD abc+def+Efg_hij abc, def, ADD, Efg_hij, ADD 2.0+1e-2/0.01E-21 2.0, 1e-2, ADD, 0.01E-21, DIV max( a, b, c, d ) * atan( pi*4, -1 ) a, b, c, d, 4, max, pi, 4, MULT, -1, 2, atan, MULT sin( cos( x ) - tan( y ) ) + f( g( z ) ) x, cos, y, tan, SUBT, sin, z, g, f, ADD 2*(somevar+other) + max(this, that) 2, somevar, other, ADD, MULT, this, that, 2, max, ADD A+(B*C-D)/E A, B, C, MULT, D, SUBT, ADD, E, DIV (a*(b)-c^(3.4e-2)) a, b, MULT, c, SUBT, 3.4e-2, POW 5^((-2e-3+x)*sin(p+4.0)/fred) 5, -2e-3, x, ADD, p, 4.0, ADD, sin, MULT, fred, DIV, POW sin(a) + sin(ab) + sin( a, b ) a, sin, ab, sin, ADD, a, b, 2, sin, ADD Func_1( 1, Func_2( Func3( 1* 2 * 3) * aFunc( 3 ) )+FuNc(4,5,6), -2,e, +-10, -2e-10 ) +1 1, 1, 2, MULT, 3, MULT, Func3, 3, aFunc, MULT, Func_2, 4, 5, +6, 3, FuNc, ADD, -2, e, -10, -2e-10, 6, Func_1, 1, ADD

    Anyone have a ready source of expressions plus their RPN forms? Or a clever way of verifying them?


    Examine what is said, not who speaks.
    Silence betokens consent.
    Love the truth but pardon error.

      An updated version of the above with all the bugs I am aware of fixed.

      It attempts to verify the results by reversing them. The caveat being that as far as I can see, there is no easy way to put back parenthesis around subexpressions? Hence it will flag expressions that contain parenthesised subexpression as not being correctly.

      In every case I have tested, the expression has been reversed correctly except for the replacement of the parens.

      It's not a perfect test method, but the best I have come up with. Anyone have a better one?

      Results

      Code:


      Examine what is said, not who speaks.
      Silence betokens consent.
      Love the truth but pardon error.
        Hmm, looks like precedence of * and / over + and - isn't handled correctly:
        a+b*c/2
        should yield
        a,b,c,*,2,/,+
        but results in
        a,b,+,c,*,2,/
        instead. I guess we really need grammar, especially if you into consideration that an operator like '**' or '^' needs even higher precedence.