diff --git a/README.md b/README.md index 4461bc7..abba5a3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # math-parser -[![Latest Stable Version](https://poser.pugx.org/mossadal/math-parser/v/stable)](https://packagist.org/packages/mossadal/math-parser) [![Total Downloads](https://poser.pugx.org/mossadal/math-parser/downloads)](https://packagist.org/packages/mossadal/math-parser) [![License](https://poser.pugx.org/mossadal/math-parser/license)](https://packagist.org/packages/mossadal/math-parser) +[![Latest Stable Version](https://poser.pugx.org/mossadal/math-parser/v/stable)](https://packagist.org/packages/mossadal/math-parser) [![Total Downloads](https://poser.pugx.org/mossadal/math-parser/downloads)](https://packagist.org/packages/mossadal/math-parser) [![License](https://poser.pugx.org/mossadal/math-parser/license)](https://packagist.org/packages/mossadal/math-parser) [![Code Climate](https://codeclimate.com/github/mossadal/math-parser/badges/gpa.svg)](https://codeclimate.com/github/mossadal/math-parser) ## DESCRIPTION @@ -11,43 +11,62 @@ Intended use: safe and reasonably efficient evaluation of user submitted formula The lexer and parser produces an abstract syntax tree (AST) that can be traversed using a tree interpreter. The math-parser library ships with three interpreters: -* an evaluator computing the value of the given expression. -* a differentiator transforming the AST into a (somewhat) simplied AST representing the derivative of the supplied expression. -* a rudimentary LaTeX output generator, useful for pretty printing expressions using MathJax - +- an evaluator computing the value of the given expression. +- a differentiator transforming the AST into a (somewhat) simplied AST representing the derivative of the supplied expression. +- a rudimentary LaTeX output generator, useful for pretty printing expressions using MathJax ## EXAMPLES It is possible to fine-tune the lexer and parser, but the library ships with a StdMathParser class, capable of tokenizing and parsing standard mathematical expressions, including arithmetical operations as well as elementary functions. -~~~{.php} +By default all single letters are interpreted as variables. Sequences of letters are interpreted as products of variables. Default constants are `e, pi, NAN, INF`. This default can be used as follows. + +```{.php} use MathParser\StdMathParser; -use MathParser\Interpreting\Evaluator; $parser = new StdMathParser(); +``` + +This default can be changed by calling a parser for a new language with newly defined variables and constants: + +```{.php} +use MathParser\Lexing\Language; +use MathParser\StdMathParser; + +$lang = new Language; +$lang->setVariables(['phi','x','t']); +$lang->setConstants(['h']); + +$parser = new StdMathParser($lang); +``` + + +```{.php} // Generate an abstract syntax tree $AST = $parser->parse('1+2'); // Do something with the AST, e.g. evaluate the expression: +use MathParser\Interpreting\Evaluator; + $evaluator = new Evaluator(); $value = $AST->accept($evaluator); echo $value; -~~~ +``` More interesting example, containing variables: -~~~{.php} -$AST = $parser->parse('x+sqrt(y)'); +```{.php} +$AST = $parser->parse('t+sqrt(phi)'); -$evaluator->setVariables([ 'x' => 2, 'y' => 3 ]); +$evaluator->setVariables([ 't' => 2, 'phi' => 3 ]); $value = $AST->accept($evaluator); -~~~ +``` We can do other things with the AST. The library ships with a differentiator, computing the (symbolic) derivative with respect to a given variable. -~~~{.php} +```{.php} use MathParser\Interpreting\Differentiator; $differentiator = new Differentiator('x'); @@ -55,9 +74,29 @@ $f = $parser->parse('exp(2*x)-x*y'); $df = $f->accept($differentiator); // $df now contains the AST of '2*exp(x)-y' and can be evaluated further -$evaluator->setVariables([ 'x' => 1, 'y' => 2 ]); +$evaluator->setVariables([ 't' => 1, 'phi' => 2 ]); $df->accept($evaluator); -~~~ +``` + +We can test whether a term, given as AST, is an instance of another term. + +```{.php} +$lang->addVariables(['c','d','u','v']); +$parser = new StdMathParser($lang); +$AST = $parser->parse('x*phi*x'); +$AST1 = $parser->parse('(c+d)*(u+v)*(c+d)'); +$AST->hasInstance($AST1)['result']; // true +$AST->hasInstance($AST1)['instantiation']['phi']; // AST of u+v + +$AST = $parser->parse('x*h*x'); +$AST->hasInstance($AST1)['result']; // false as 'h' is a constant and cannot be instantiated +$AST2 = $parser->parse('(c+d)*h*(c+d)'); +$AST->hasInstance($AST2)['result']; // true +$AST3 = $parser->parse('h*h*h'); +$AST->hasInstance($AST3)['result']; // true +$AST4 = $parser->parse('h*(h*h)'); +$AST->hasInstance($AST4)['result']; // false as h*(h*h) is not an instance of x*phi*x=(x*phi)*x +``` ### Implicit multiplication @@ -65,14 +104,10 @@ Another helpful feature is that the parser understands implicit multiplication. Note that implicit multiplication has the same precedence as explicit multiplication. In particular, `xy^2z` is parsed as `x*y^2*z` and **not** as `x*y^(2*z)`. -To make full use of implicit multiplication, the standard lexer only allows one-letter variables. (Otherwise, we wouldn't know if `xy` should be parsed as `x*y` or as the single variable `xy`). - -## DOCUMENTATION - -For complete documentation, see the [github.io project page](http://mossadal.github.io/math-parser/index.html) - ## THANKS +This software is an adaptation of the [math-parser by Frank Wikström](https://github.com/mossadal/math-parser). + The Lexer is based on the lexer described by Marc-Oliver Fiset in his [blog](http://marcofiset.com/programming-language-implementation-part-1-lexer/). The parser is a version of the "Shunting yard" algorithm, described for example by [Theodore Norvell](http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#shunting_yard). diff --git a/src/MathParser/Interpreting/ASCIIPrinter.php b/src/MathParser/Interpreting/ASCIIPrinter.php index 8d19a13..1d59a42 100644 --- a/src/MathParser/Interpreting/ASCIIPrinter.php +++ b/src/MathParser/Interpreting/ASCIIPrinter.php @@ -1,12 +1,13 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2016 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL */ namespace MathParser\Interpreting; +use MathParser\Lexing\Language; use MathParser\Exceptions\UnknownConstantException; use MathParser\Interpreting\Visitors\Visitor; use MathParser\Lexing\StdMathLexer; @@ -51,9 +52,12 @@ class ASCIIPrinter implements Visitor /** * Constructor. Create an ASCIIPrinter. */ - public function __construct() + public function __construct($lang = null) { - $this->lexer = new StdMathLexer(); + if ($lang === null) { + $lang = new Language; + } + $this->lexer = new StdMathLexer($lang); } /** @@ -189,8 +193,9 @@ public function visitConstantNode(ConstantNode $node) return 'NAN'; case 'INF': return 'INF'; + default: return $node->getName(); - default:throw new UnknownConstantException($node->getName()); + //default:throw new UnknownConstantException($node->getName()); } } diff --git a/src/MathParser/Interpreting/Evaluator.php b/src/MathParser/Interpreting/Evaluator.php index 1a08f76..aec734d 100644 --- a/src/MathParser/Interpreting/Evaluator.php +++ b/src/MathParser/Interpreting/Evaluator.php @@ -247,7 +247,6 @@ public function visitFunctionNode(FunctionNode $node) // Exponentials and logarithms case 'exp': return exp($inner); - case 'log': case 'ln': return log($inner); diff --git a/src/MathParser/Lexing/Language.php b/src/MathParser/Lexing/Language.php new file mode 100644 index 0000000..ecee2d8 --- /dev/null +++ b/src/MathParser/Lexing/Language.php @@ -0,0 +1,97 @@ + + * @copyright 2019 Ingo Dahn + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * + */ + +/** + * @namespace MathParser::Lexing + * Lexer and Token related classes. + * + * [Lexical analysis](https://en.wikipedia.org/wiki/Lexical_analysis) + * or *lexing* is the process of converting an input string into a sequence + * of tokens, representing discrete parts of the input each carrying certain meaning. + * + */ +namespace MathParser\Lexing; +/** + * Class Language keeps definitions of variables and constants + * Maybe extended later by function and relation symbols + */ +class Language +{ + private $constants=[]; + private $variables=['[a-zA-Z]']; + /** + * setting the list of constnts + * @retval void + * @param Array $carray Array of constants + */ + public function setConstants(Array $carray) { + $this->constants=$carray; + } + /** + * Adding a list of constants + * @retval void + * @param Array $carray Array of constants + */ + public function addConstants(Array $carray) { + $oldconsts=$this->constants; + $this->constants=array_merge($oldconsts,$carray); + } + /** + * Removing a list of constants + * @retval void + * @param Array $carray Array of constnts + */ + public function removeConstants(Array $carray) { + $oldconsts=$this->constants; + $this->constants=array_values(array_diff($oldconsts,$carray)); + } + /** + * getting the list of constnts + * @retval Array of constants + */ + public function getConstants() { + return $this->constants; + } + + /** + * setting the list of variables + * As default, all letters are variables + * @retval void + * @param Array $carray Array of variables + */ + public function setVariables(Array $carray) { + $this->variables=$carray; + } + /** + * Adding a list of variables + * @retval void + * @param Array $carray Array of variables + */ + public function addVariables(Array $carray) { + $oldvars=$this->variables; + $this->variables=array_merge($oldvars,$carray); + } + /** + * Removing a list of variables + * Use removeVariables(['[a-zA-Z]']) to remove the default single letter variable declaration + * @retval void + * @param Array $carray Array of variables + */ + public function removeVariables(Array $carray) { + $oldvars=$this->variables; + $this->variables=array_values(array_diff($oldvars,$carray)); + } + /** + * getting the list of variables + * @retval Array of variables + */ + public function getVariables() { + return $this->variables; + } +} \ No newline at end of file diff --git a/src/MathParser/Lexing/StdMathLexer.php b/src/MathParser/Lexing/StdMathLexer.php index afef4be..48d99e8 100644 --- a/src/MathParser/Lexing/StdMathLexer.php +++ b/src/MathParser/Lexing/StdMathLexer.php @@ -5,13 +5,14 @@ * Long description * * @package Lexical analysis - * @author Frank Wikström + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * */ namespace MathParser\Lexing; +use MathParser\Lexing\Language; /** * Lexer capable of recognizing all standard mathematical expressions. @@ -67,8 +68,11 @@ */ class StdMathLexer extends Lexer { - public function __construct() + public function __construct(Language $lang=null) { + if ($lang === null ) { + $lang=new Language; + } $this->add(new TokenDefinition('/\d+[,\.]\d+(e[+-]?\d+)?/', TokenType::RealNumber)); $this->add(new TokenDefinition('/\d+/', TokenType::PosInt)); @@ -129,8 +133,15 @@ public function __construct() $this->add(new TokenDefinition('/e/', TokenType::Constant)); $this->add(new TokenDefinition('/NAN/', TokenType::Constant)); $this->add(new TokenDefinition('/INF/', TokenType::Constant)); - - $this->add(new TokenDefinition('/[a-zA-Z]/', TokenType::Identifier)); + $consts=$lang->getConstants(); + foreach ($consts as $c) { + $this->add(new TokenDefinition('/'.$c.'/', TokenType::Constant)); + } + $vars=$lang->getVariables(); + foreach ($vars as $v) { + $this->add(new TokenDefinition('/'.$v.'/', TokenType::Identifier)); + } + //$this->add(new TokenDefinition('/[a-zA-Z]/', TokenType::Identifier)); $this->add(new TokenDefinition('/\n/', TokenType::Terminator)); $this->add(new TokenDefinition('/\s+/', TokenType::Whitespace)); diff --git a/src/MathParser/Parsing/Nodes/ConstantNode.php b/src/MathParser/Parsing/Nodes/ConstantNode.php index e652259..25be910 100644 --- a/src/MathParser/Parsing/Nodes/ConstantNode.php +++ b/src/MathParser/Parsing/Nodes/ConstantNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -9,6 +9,7 @@ namespace MathParser\Parsing\Nodes; +use MathParser\Lexing\Language; use MathParser\Interpreting\Visitors\Visitor; /** @@ -33,8 +34,12 @@ class ConstantNode extends Node * ~~~ * */ - function __construct($value) + function __construct($value, $lang = null) { + if ($lang === null) { + $lang = new Language; + } + $this->language = $lang; $this->value = $value; } @@ -70,4 +75,21 @@ public function compareTo($other) return $this->getName() == $other->getName(); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof ConstantNode)) { + return ['result' => false]; + } + $result=($this->getName() == $other->getName()); + if ($result) { + return ['result' => true, 'instantiation'=> $inst]; + } + + return ['result' => false]; + } + } diff --git a/src/MathParser/Parsing/Nodes/ExpressionNode.php b/src/MathParser/Parsing/Nodes/ExpressionNode.php index e6d7992..cc0db71 100644 --- a/src/MathParser/Parsing/Nodes/ExpressionNode.php +++ b/src/MathParser/Parsing/Nodes/ExpressionNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -251,5 +251,50 @@ public function compareTo($other) return $thisLeft->compareTo($otherLeft) && $thisRight->compareTo($otherRight); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof ExpressionNode)) { + return ['result' => false]; + } + + if ($this->getOperator() != $other->getOperator()) return ['result' => false]; + + $thisLeft = $this->getLeft(); + $otherLeft = $other->getLeft(); + $thisRight = $this->getRight(); + $otherRight = $other->getRight(); + + if ($thisLeft === null) { + if ($otherLeft === null) { + return $thisRight->hasInstance($otherRight,$inst); + } else { + return ['result' => false]; + } + } + + if ($thisRight === null) { + if ($otherRight === null) { + return $thisLeft-> hasInstance($otherLeft,$inst); + } else { + return ['result' => false]; + } + } + $instLeft=$thisLeft->hasInstance($otherLeft,$inst); + if (! $instLeft['result']) { + return ['result' => false]; + } else { + $instRight = $thisRight->hasInstance($otherRight,$instLeft['instantiation']); + if (! $instRight['result']) { + return ['result' => false]; + } else { + return ['result'=> true, 'instantiation' => $instRight['instantiation']]; + } + } + } + } diff --git a/src/MathParser/Parsing/Nodes/FunctionNode.php b/src/MathParser/Parsing/Nodes/FunctionNode.php index 7df4db5..d28d409 100644 --- a/src/MathParser/Parsing/Nodes/FunctionNode.php +++ b/src/MathParser/Parsing/Nodes/FunctionNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -85,4 +85,27 @@ public function compareTo($other) return $this->getName() == $other->getName() && $thisOperand->compareTo($otherOperand); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof FunctionNode)) { + return ['result' => false]; + } + + $thisOperand = $this->getOperand(); + $otherOperand = $other->getOperand(); + + if (! $this->getName() == $other->getName()) { + return ['result' => false]; + } + $instOperand=$thisOperand->hasInstance($otherOperand,$inst); + if (! $instOperand) { + return ['result' => false]; + } + return ['result' => true, 'instantiation' => $instOperand['instantiation']]; + } + } diff --git a/src/MathParser/Parsing/Nodes/IntegerNode.php b/src/MathParser/Parsing/Nodes/IntegerNode.php index e2d9e68..b9f2cf8 100644 --- a/src/MathParser/Parsing/Nodes/IntegerNode.php +++ b/src/MathParser/Parsing/Nodes/IntegerNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -69,5 +69,13 @@ public function compareTo($other) return $this->getValue() == $other->getValue(); } - + + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) { + if ($this->compareTo($other)) { + return ['result'=>true, 'instantiation'=>$inst]; + } + return ['result'=> false]; + } + } diff --git a/src/MathParser/Parsing/Nodes/Node.php b/src/MathParser/Parsing/Nodes/Node.php index 5a14930..61590f7 100644 --- a/src/MathParser/Parsing/Nodes/Node.php +++ b/src/MathParser/Parsing/Nodes/Node.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -17,6 +17,7 @@ use MathParser\Interpreting\ASCIIPrinter; use MathParser\Interpreting\Evaluator; use MathParser\Interpreting\Visitors\Visitable; +use MathParser\Lexing\Language; use MathParser\Lexing\Token; use MathParser\Lexing\TokenType; @@ -136,6 +137,15 @@ public static function factory(Token $token) */ abstract public function compareTo($other); + /**ID + * Helper function, testing whether an argument AST is an instance of the given AST + * + * @retval Array ['result' => true|false|, 'instantiation' => Variable instantiation] in case of true] + * @param Node|null $other Compare to this tree, + * @param Array $inst of instantiations of proper variables + */ + abstract public function hasInstance($other,$inst=[]); + /** * Convenience function for evaluating a tree, using * the Evaluator class. @@ -244,7 +254,6 @@ public function getOperator() public function __toString() { $printer = new ASCIIPrinter(); - return $this->accept($printer); } } diff --git a/src/MathParser/Parsing/Nodes/NumberNode.php b/src/MathParser/Parsing/Nodes/NumberNode.php index cf7fc7b..3316924 100644 --- a/src/MathParser/Parsing/Nodes/NumberNode.php +++ b/src/MathParser/Parsing/Nodes/NumberNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -55,4 +55,20 @@ public function compareTo($other) return $this->getValue() == $other->getValue(); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof NumberNode)) { + return ['result' => false]; + } + + if (! ($this->getValue() == $other->getValue())) { + return ['result' => false]; + } + return ['result' => true, 'instantiation' => $inst]; + } + } diff --git a/src/MathParser/Parsing/Nodes/PostfixOperatorNode.php b/src/MathParser/Parsing/Nodes/PostfixOperatorNode.php index f97387f..e247167 100644 --- a/src/MathParser/Parsing/Nodes/PostfixOperatorNode.php +++ b/src/MathParser/Parsing/Nodes/PostfixOperatorNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -55,4 +55,19 @@ public function compareTo($other) return $this->getOperator() == $other->getOperator(); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof PostfixOperatorNode)) { + return ['result' => false]; + } + if (! $this->getOperator() == $other->getOperator()) { + return ['result' => false]; + } + return ['result' => true, 'instantiation' => $inst]; + } + } diff --git a/src/MathParser/Parsing/Nodes/RationalNode.php b/src/MathParser/Parsing/Nodes/RationalNode.php index 6c61938..29d3edd 100644 --- a/src/MathParser/Parsing/Nodes/RationalNode.php +++ b/src/MathParser/Parsing/Nodes/RationalNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -92,6 +92,29 @@ public function compareTo($other) return $this->getNumerator() == $other->getNumerator() && $this->getDenominator() == $other->getDenominator(); } + /** + * Implementing the hasInstance abstract method. + */ + public function hasInstance($other,$inst) + { + if ($other === null) { + return ['result' => false]; + } + if ($other instanceof IntegerNode) { + if ($this->getDenominator() == 1 && $this->getNumerator() == $other->getValue()) { + return ['result' => true, 'instantiation' => $inst]; + } + } + if (!($other instanceof RationalNode)) { + return ['result' => false]; + } + + if ($this->getNumerator() == $other->getNumerator() && $this->getDenominator() == $other->getDenominator()) { + return ['result' => true, 'instantiation' => $inst]; + } + return ['result' => false]; + } + private function normalize() { $a = $this->p; diff --git a/src/MathParser/Parsing/Nodes/SubExpressionNode.php b/src/MathParser/Parsing/Nodes/SubExpressionNode.php index 64e823d..9cc114e 100644 --- a/src/MathParser/Parsing/Nodes/SubExpressionNode.php +++ b/src/MathParser/Parsing/Nodes/SubExpressionNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -62,4 +62,19 @@ public function compareTo($other) return $this->getValue() == $other->getValue(); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' => false]; + } + if (!($other instanceof SubExpressionNode)) { + return ['result' => false]; + } + if (! $this->getValue() == $other->getValue()) { + return ['result' => false]; + } + return ['result' => true, 'instantiation' => $inst]; + } + } diff --git a/src/MathParser/Parsing/Nodes/VariableNode.php b/src/MathParser/Parsing/Nodes/VariableNode.php index ee4f37e..8f4fbed 100644 --- a/src/MathParser/Parsing/Nodes/VariableNode.php +++ b/src/MathParser/Parsing/Nodes/VariableNode.php @@ -1,7 +1,7 @@ + * @author Frank Wikström , modified by Ingo Dahn * @copyright 2015 Frank Wikström * @license http://www.opensource.org/licenses/lgpl-license.php LGPL * @@ -55,4 +55,34 @@ public function compareTo($other) return $this->getName() == $other->getName(); } + /** Implementing the hasInstance abstract method. */ + public function hasInstance($other,$inst=[]) + { + if ($other === null) { + return ['result' =>false]; + } + $name=$this->getName(); + /* + if (in_array($name,$consts)) { + if (! ($other instanceof VariableNode)){ + return ['result' => false]; + } elseif ($other->getName() == $name) { + return ['result' => true, 'instantiation' => $vars]; + } else { + return ['result' => false]; + } + } + */ + if (array_key_exists($name,$inst)) { + if ($other->compareTo($inst[$name])) { + return ['result' => true, 'instantiation' =>$inst]; + } else { + return ['result' => false]; + } + } + $inst[$name]=$other; + + return ['result' => true, 'instantiation' => $inst]; + } + } diff --git a/src/MathParser/StdMathParser.php b/src/MathParser/StdMathParser.php index d727203..f23b7a0 100644 --- a/src/MathParser/StdMathParser.php +++ b/src/MathParser/StdMathParser.php @@ -1,9 +1,10 @@ -parse('2x + 2y^2/sin(x)'); * * // Do whatever you want with the parsed expression, @@ -37,12 +38,15 @@ class StdMathParser extends AbstractMathParser { - public function __construct() + public function __construct($lang=null) { - $this->lexer = new StdMathLexer(); + if ($lang === null) { + $lang=new Language; + } + $this->lexer = new StdMathLexer($lang); $this->parser = new Parser(); } - + /** * Parse the given mathematical expression into an abstract syntax tree. * @@ -56,5 +60,5 @@ public function parse($text) return $this->tree; } - + }