zeni has asked for the wisdom of the Perl Monks concerning the following question:

Hi Folks, I have this piece of code which generates random expression that can contain arithmetic,logical and relational operators and various operands.
sub genRandomExpr { pickOperator(); pickRandomOperands(); formExpression(); return expr; } sub formExpression { createSubExprs(); merge(); return this; }
Say it generates @expr = "((2 + 4 * 6 / 3) <= 20)"; or @expr = "((10 * 3)+(2 / 5) == 1)"; The whole expr will be stored in d form of a string. I need to evaluate this expression and validate it. N i want the "compiler" to solve it and return me d answer. Can this be possible? Plz help me as this is very imp.. Thanks In Advance !

Replies are listed 'Best First'.
Re: Solving an expression
by moritz (Cardinal) on Jun 13, 2009 at 08:10 UTC
    If it's valid Perl code, you can use eval to evaluate its result. (But note that eval can execute arbitrary code, so you should make sure there are no system calls or other evil things in the string).

    There are also modules that execute arithmetic expressions. For example I wrote Math::Expression::Evaluator some time ago, which handles the arithmetic, but iirc not the comparisons. Other modules in the Math:: namespace might do that, though.

      It's probably a bit safer to use Safe instead of plain old eval"".

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

        If i know wat operator to use only then i can use eval rit. Everything is randomly generated. The expression will go as input to the module which inturn evaluates this expr and returns the result.
Re: Solving an expression
by planetscape (Chancellor) on Jun 13, 2009 at 12:08 UTC
Re: Solving an expression
by ikegami (Patriarch) on Jun 13, 2009 at 22:23 UTC
    A solution probably already exists on CPAN, but you could build your own based on the code in this node (go down to section 5).
Re: Solving an expression
by AnomalousMonk (Archbishop) on Jun 13, 2009 at 22:13 UTC
    One detail to mention is that the Perl statement
        @expr = "((2 + 4 * 6 / 3) <= 20)";
    probably does not do what you expect. It assigns the string  "((2 + 4 * 6 / 3) <= 20)" to the first element of the  @expr array (i.e., $expr[0]), and if any other elements had any values, they are destroyed. You may want something like:
        $expr    = "((2 + 4 * 6 / 3) <= 20)";  # scalar assignment
    or maybe:
        $expr[0] = "((2 + 4 * 6 / 3) <= 20)";  # array element assignment

    o, n gl with ur hw assignment also.

    Update: Added statement about effect of array assignment on other elements of array, array element assignment example.