parsing.md (7332B)
1 # Expression parsing and evaluation 2 3 Expressions can be parsed and evaluated in various ways: 4 5 - Using the function [`math.evaluate(expr [,scope])`](#evaluate). 6 - Using the function [`math.compile(expr)`](#compile). 7 - Using the function [`math.parse(expr)`](#parse). 8 - By creating a [parser](#parser), `math.parser()`, which contains a method 9 `evaluate` and keeps a scope with assigned variables in memory. 10 11 12 ## Evaluate 13 14 Math.js comes with a function `math.evaluate` to evaluate expressions. Syntax: 15 16 ```js 17 math.evaluate(expr) 18 math.evaluate(expr, scope) 19 math.evaluate([expr1, expr2, expr3, ...]) 20 math.evaluate([expr1, expr2, expr3, ...], scope) 21 ``` 22 23 Function `evaluate` accepts a single expression or an array with 24 expressions as the first argument and has an optional second argument 25 containing a scope with variables and functions. The scope can be a regular 26 JavaScript Object, or Map. The scope will be used to resolve symbols, and to write 27 assigned variables or function. 28 29 The following code demonstrates how to evaluate expressions. 30 31 ```js 32 // evaluate expressions 33 math.evaluate('sqrt(3^2 + 4^2)') // 5 34 math.evaluate('sqrt(-4)') // 2i 35 math.evaluate('2 inch to cm') // 5.08 cm 36 math.evaluate('cos(45 deg)') // 0.7071067811865476 37 38 // provide a scope 39 let scope = { 40 a: 3, 41 b: 4 42 } 43 math.evaluate('a * b', scope) // 12 44 math.evaluate('c = 2.3 + 4.5', scope) // 6.8 45 scope.c // 6.8 46 ``` 47 48 49 ## Compile 50 51 Math.js contains a function `math.compile` which compiles expressions 52 into JavaScript code. This is a shortcut for first [parsing](#parse) and then 53 compiling an expression. The syntax is: 54 55 ```js 56 math.compile(expr) 57 math.compile([expr1, expr2, expr3, ...]) 58 ``` 59 60 Function `compile` accepts a single expression or an array with 61 expressions as the argument. Function `compile` returns an object with a function 62 `evaluate([scope])`, which can be executed to evaluate the expression against an 63 (optional) scope: 64 65 ```js 66 const code = math.compile(expr) // compile an expression 67 const result = code.evaluate([scope]) // evaluate the code with an optional scope 68 ``` 69 70 An expression needs to be compiled only once, after which the 71 expression can be evaluated repeatedly and against different scopes. 72 The optional scope is used to resolve symbols and to write assigned 73 variables or functions. Parameter [`scope`](#scope) can be a regular Object, or Map. 74 75 Example usage: 76 77 ```js 78 // parse an expression into a node, and evaluate the node 79 const code1 = math.compile('sqrt(3^2 + 4^2)') 80 code1.evaluate() // 5 81 ``` 82 83 84 ## Parse 85 86 Math.js contains a function `math.parse` to parse expressions into an 87 [expression tree](expression_trees.md). The syntax is: 88 89 ```js 90 math.parse(expr) 91 math.parse([expr1, expr2, expr3, ...]) 92 ``` 93 94 Function `parse` accepts a single expression or an array with 95 expressions as the argument. Function `parse` returns a the root node of the tree, 96 which can be successively compiled and evaluated: 97 98 ```js 99 const node = math.parse(expr) // parse expression into a node tree 100 const code = node.compile() // compile the node tree 101 const result = code.evaluate([scope]) // evaluate the code with an optional scope 102 ``` 103 104 The API of nodes is described in detail on the page 105 [Expression trees](expression_trees.md). 106 107 An expression needs to be parsed and compiled only once, after which the 108 expression can be evaluated repeatedly. On evaluation, an optional scope 109 can be provided, which is used to resolve symbols and to write assigned 110 variables or functions. Parameter [`scope`](#scope) is a regular Object or Map. 111 112 Example usage: 113 114 ```js 115 // parse an expression into a node, and evaluate the node 116 const node1 = math.parse('sqrt(3^2 + 4^2)') 117 const code1 = node1.compile() 118 code1.evaluate() // 5 119 120 // provide a scope 121 const node2 = math.parse('x^a') 122 const code2 = node2.compile() 123 let scope = { 124 x: 3, 125 a: 2 126 } 127 code2.evaluate(scope) // 9 128 129 // change a value in the scope and re-evaluate the node 130 scope.a = 3 131 code2.evaluate(scope) // 27 132 ``` 133 134 Parsed expressions can be exported to text using `node.toString()`, and can 135 be exported to LaTeX using `node.toTex()`. The LaTeX export can be used to 136 pretty print an expression in the browser with a library like 137 [MathJax](https://www.mathjax.org/). Example usage: 138 139 ```js 140 // parse an expression 141 const node = math.parse('sqrt(x/x+1)') 142 node.toString() // returns 'sqrt((x / x) + 1)' 143 node.toTex() // returns '\sqrt{ {\frac{x}{x} }+{1} }' 144 ``` 145 146 147 ## Parser 148 149 In addition to the static functions [`math.evaluate`](#evaluate) and 150 [`math.parse`](#parse), math.js contains a parser with functions `evaluate` and 151 `parse`, which automatically keeps a scope with assigned variables in memory. 152 The parser also contains some convenience functions to get, set, and remove 153 variables from memory. 154 155 A parser can be created by: 156 157 ```js 158 const parser = math.parser() 159 ``` 160 161 The parser contains the following functions: 162 163 - `clear()` 164 Completely clear the parser's scope. 165 - `evaluate(expr)` 166 Evaluate an expression. Returns the result of the expression. 167 - `get(name)` 168 Retrieve a variable or function from the parser's scope. 169 - `getAll()` 170 Retrieve a map with all defined a variables from the parser's scope. 171 - `remove(name)` 172 Remove a variable or function from the parser's scope. 173 - `set(name, value)` 174 Set a variable or function in the parser's scope. 175 176 The following code shows how to create and use a parser. 177 178 ```js 179 // create a parser 180 const parser = math.parser() 181 182 // evaluate expressions 183 parser.evaluate('sqrt(3^2 + 4^2)') // 5 184 parser.evaluate('sqrt(-4)') // 2i 185 parser.evaluate('2 inch to cm') // 5.08 cm 186 parser.evaluate('cos(45 deg)') // 0.7071067811865476 187 188 // define variables and functions 189 parser.evaluate('x = 7 / 2') // 3.5 190 parser.evaluate('x + 3') // 6.5 191 parser.evaluate('f(x, y) = x^y') // f(x, y) 192 parser.evaluate('f(2, 3)') // 8 193 194 // get and set variables and functions 195 const x = parser.get('x') // x = 7 196 const f = parser.get('f') // function 197 const g = f(3, 3) // g = 27 198 parser.set('h', 500) 199 parser.evaluate('h / 2') // 250 200 parser.set('hello', function (name) { 201 return 'hello, ' + name + '!' 202 }) 203 parser.evaluate('hello("user")') // "hello, user!" 204 205 // clear defined functions and variables 206 parser.clear() 207 ``` 208 209 ## Scope 210 211 The scope is a data-structure used to store and lookup variables and functions defined and used by expressions. 212 213 It is passed to mathjs via calls to [`math.evaluate`](#evaluate) or `simplify`. 214 215 For ease of use, it can be a Plain Javascript Object; for safety it can be a plain `Map` and for flexibility, any object that has 216 the methods `get`/`set`/`has`/`keys`, seen on `Map`. 217 218 Some care is taken to mutate the same object that is passed into mathjs, so they can collect the definitions from mathjs scripts and expressions. 219 220 `evaluate` will fail if the expression uses a blacklisted symbol, preventing mathjs expressions to escape into Javascript. This is enforced by access to the scope. 221 222 For less reliance on this blacklist, scope can also be a `Map`, which allows mathjs expressions to define variables and functions of any name. 223 224 For more, see [examples of custom scopes](../../examples/advanced/custom_scope_objects.js).