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 is a regular
|
26 | JavaScript Object. 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` is a regular Object.
|
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` is a regular Object.
|
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 | ```
|