Login   Register  
PHP Classes
elePHPant
Icontem

File: test.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Gonzalo Chumillas  >  Ses Parser  >  test.php  >  Download  
File: test.php
Role: Example script
Content type: text/plain
Description: parsing a mathematical expression
Class: Ses Parser
Parse a string with an expression of any type
Author: By
Last change: Updating
Date: 11 months ago
Size: 6,403 bytes
 

Contents

Class file image Download
<?php
/**
 * This file contains a class to parse and calculate a mathematical expression.
 * Allowed functions are: sin, cos, tan, sqrt, abs and ln (natural logarithm)
 * Allowed constans are: PI and E
 */
 
dirname(__FILE__) . "/classes/parser/parser.php";

require_once 
"classes/parser/parser.php";

class 
MathParser extends Parser {
    private 
$constants;
    private 
$operators;
    private 
$functions;
    private 
$stack;
    
    public function 
__construct($string$flags 0) {
        
parent::__construct($string$flags);
        
        
$this->constants = array(
            
"pi" => M_PI,
            
"e" => M_E
        
);
        
        
$this->operators = array(
            
"+" => array("priority" => 0"func" => create_function('$x,$y''return $x + $y;')),
            
"-" => array("priority" => 0"func" => create_function('$x,$y''return $x - $y;')),
            
"*" => array("priority" => 1"func" => create_function('$x,$y''return $x * $y;')),
            
"/" => array("priority" => 1"func" => create_function('$x,$y''return $x / $y;')),
            
"^" => array("priority" => 2"func" => create_function('$x,$y''return pow($x, $y);'))
        );
        
        
$this->functions = array(
            
'sin' => create_function('$x''return sin($x);'),
            
'cos' => create_function('$x''return cos($x);'),
            
'tan' => create_function('$x''return tan($x);'),
            
'sqrt' => create_function('$x''return sqrt($x);'),
            
'abs' => create_function('$x''return abs($x);'),
            
"ln" => create_function('$x''return log($x);')
        );
        
        
$this->stack = array();
    }
    
    private function 
compute($number$operator "+") {
        
$level count($this->stack) - 1;
        
array_unshift($this->stack[$level], array("number" => $number"operator" => $operator));
        
        while (
count($this->stack[$level]) > 1) {
            
$op0 $this->stack[$level][0]["operator"];
            
$op1 $this->stack[$level][1]["operator"];
            
$priority0 $this->operators[$op0]["priority"];
            
$priority1 $this->operators[$op1]["priority"];
            
            if (
$priority0 <= $priority1) {
                
$func $this->operators[$op1]["func"];
                
$n0 $this->stack[$level][0]["number"];
                
$n1 $this->stack[$level][1]["number"];
                
$this->stack[$level][1]["number"] = $func($n1$n0);
                
$this->stack[$level][1]["operator"] = $op0;
                
array_shift($this->stack[$level]);
            } else {
                break;
            }
        }
        
        return 
$this->stack[$level][0]["number"];
    }
    
    protected function 
constant() {
        return 
$this->in(array_keys($this->constants));
    }
    
    protected function 
operator() {
        return 
$this->in(array_keys($this->operators));
    }
    
    protected function 
func() {
        
$functions array_keys($this->functions);
        
        if (list(
$func) = $this->in(array_keys($this->functions))) {
            
$f $this->functions[$func];
            
            if (!list(
$number) = $this->is("term")) {
                throw new 
ParserException($this"Unrecognized term");
            }
            
            return array(
$f($number));
        }
        
        return 
FALSE;
    }
    
    protected function 
term() {
        
$ret FALSE;
        
        if (
$this->eq("(")) {
            if (list(
$number) = $this->is("expression")) {
                
$ret = array($number);
            }
            if (!
$this->eq(")")) {
                throw new 
ParserException($this"Missing ')'");
            }
        } else
        if (
$this->eq("-")) {
            if (!list(
$number) = $this->is("term")) {
                throw new 
ParserException($this"Unrecognized term");
            }
            
            
$ret = array(-$number);
        } else
        if (list(
$const) = $this->is("constant")) {
            
$ret = array($this->constants[$const]);
        } else
        if ( (list(
$number) = $this->number()) || (list($number) = $this->is("func")) ) {
            
$ret = array($number);
        }
        
        return 
$ret;
    }
    
    protected function 
expression() {
        
array_push($this->stack, array());
        
$result 0;
        
$op "+";
        
        do {
            
$this->compute($result$op);
            if (!list(
$result) = $this->is("term")) {
                throw new 
ParserException($this"Unrecognized term");
            }
        } while (list(
$op) = $this->is("operator"));
        
        
$result $this->compute($result);
        
array_pop($this->stack);
        return array(
$result);
    }
    
    protected function 
_parse() {
        return 
$this->is("expression");
    }
}

$error "";
$result 0;
$expression = isset($_REQUEST["expression"])? $_REQUEST["expression"] : "-25 + 48 * (32^2 - ln E) + sin(PI/2) - 5^2";

// calculates the expression
$p = new MathParser($expression);

try {
    list(
$result) = $p->parse();
} catch (
ParserException $e) {
    
$error $e->getPrintableMessage();
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Math Parser</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
    <form action="<?php echo $_SERVER["PHP_SELF"?>" method="post">
        <div>
            <label for="expression">Enter a mathematical expression:</label><br />
            <input type="text" name="expression" id="expression" value="<?php echo htmlentities($expression?>" size="80" />
            <input type="submit" value="Calculate!" />
        </div>
        
        <?php if ($error): ?>
            <pre style="color: brown; "><strong><?php echo $error ?></strong></pre>
        <?php else: ?>
            <p><strong>Result is</strong>: <?php echo htmlentities($result?></p>
        <?php endif ?>
        
        <p style="color: gray; ">
            Allowed functions: sin, cos, tan, sqrt, abs, ln<br />
            Allowed constants: PI, E
        </p>
    </form>
</body>
</html>