Parses a plaintext string of unicode math to an AST.
npm install -S equation-parser
or
yarn add equation-parser
Numbers are supported in decimal-notation only, using .
as decimal separator (note that adding an exponent can easily be achieved using * 10^n
).
Variables can contain the following characters:
- Latin-1 supplement letters (
U+00C0-U+00D6
) - Latin-1 supplement letters (
U+00D8-U+00F6
) - Latin-1 supplement letters (
U+00F8-U+00FF
) - Latin extended-A (
U+0100-U+017F
) - Latin extended-B letters (
U+0180-U+01BF
) - Greek letters (
U+0391-U+03c9
) '
,"
,%
,‰
,°
,∞
_
used for variable indexing/subscripting
A _
not surrounded by variable-characters is considered a placeholder. A placeholder can be used instead of an operand (variable/number/function-name) to create a valid, parseable equation when a value is still unknown.
Whitespace is ignored, except when separating two variables (a b
, interpreted as implicit multiplication), a variable and a number (a 2
, interpreted as implicit multiplication), two numbers (1 2
, a numberWhitespace
-error).
Variables must start with a non-number, non-underscore. Leading numbers will instead be interpreted as implicit multiplication (2x
is 2 * x
). Leading underscores will be interpreted as implicit multiplication with a placeholder (_a
is _ * a
).
The following operators are supported:
- Plus:
+
- Minus:
-
,−
(Minus Sign U+2212) - Plus-minus:
±
- Implicit multiplication (error on vectors):
- Dot multiplication (scalar product on vectors):
*
,∗
(Asterisk Operator U+2217),⋅
(Dot Operator U+22C5) - Cross multiplication (vector product on vectors):
×
(Multiplication Sign U+00D7),✕
(Multiplication X U+2715) - Fraction:
/
,∕
(Division Slash U+2215) - Inline division (differentiated for rendering purposes):
÷
(Division Sign U+00F7) - Power:
^
- Placeholder operator:
?
- Like the operand-placeholder, the operator placeholder kan be used to create a parseable equation when parts of it is still missing.
The following comparisons are supported:
- Equals:
=
- Less than:
<
- Greater than:
>
- Less than or equals:
≤
- Greater than or equals:
≥
- Approximately equals:
≈
Regular parenthesis can be used to group parts of an expression or to denote a function, in usual math fashion.
Square brackets []
can be used to create vectors or matrices. Matrices are defined with nested brackets as rows: [[row1col1,row1col2][row2col1,row2col2]]
. Vectors are defined as if a standalone row [a, b]
. In the parsed result, a vector parses identically to a matrix with one column, so [a, b]
is completely equivalent to [[a][b]]
.
Parse the string into an EquationNode
, or an EquationParserError
if the string is invalid.
parse
should never throw, any error should be considered a library error.
Example:
parse('1+2*3+a(b)')
// returns {
// type: 'plus',
// a: {
// type: 'plus',
// a: { type: 'number', value: '1' },
// b: {
// type: 'multiply-dot',
// a: { type: 'number', value: '2' },
// b: { type: 'number', value: '3' }
// }
// },
// b: {
// type: 'function',
// name: 'a',
// args: [{ type: 'variable', name: 'b' }]
// }
// }
Render the AST as a tree of nodes. Mostly useful for debugging and understanding the AST structure. This function should preferably be removed by a treeshaking build.
Example:
renderTree(parse('1+2*3+a(b)'))
// returns
// '+
// ├─ +
// │ ├─ 1
// │ └─ *
// │ ├─ 2
// │ └─ 3
// └─ a()
// └─ "b"'
Reconstructs the original equation from the AST. Whitespace is not preserved, and operators with multiple symbols always output the same. This function should preferably be removed by a treeshaking build.
Example:
stringify(parse('1+2*3+a(b)'))
// returns '1 + 2 * 3 + a(b)'
The CLI is included mainly for testing. The first argument should be either json
or tree
and the second an equation string.
Example:
$ equation-parser json "1+2*3+a(b)"
{
"type": "plus",
"a": {
"type": "plus",
"a": {
"type": "number",
"value": "1"
},
"b": {
"type": "multiply-dot",
"a": {
"type": "number",
"value": "2"
},
"b": {
"type": "number",
"value": "3"
}
}
},
"b": {
"type": "function",
"name": "a",
"args": [
{
"type": "variable",
"name": "b"
}
]
}
}
$ equation-parser tree "1+2*3+a(b)"
+
├─ +
│ ├─ 1
│ └─ *
│ ├─ 2
│ └─ 3
└─ a()
└─ "b"
EquationNode
s are plain objects, identified by their type
property. To avoid stressing the type system, operator precedence is not enforced through the type system.
Represents a named variable. Subscripts should be separated with underscores.
Additional values:
name: string
Example:
a
, %
, a_2
Represents a number. Note that the value is not parsed as a number, but is guaranteed to be a number.
Additional values:
value: string
Example:
1
, 2.3
, .4
Represents a function. Always has at least one argument.
Additional values:
name: string
args: EquationNode[]
Example:
f(1)
, g(a, b)
Represents a statement wrapped in parenthesis.
Additional values:
child: EquationNode
Example:
(1)
, (1+2)
Represents a matrix. n
is the amount of columns, m
is the amount of rows, values
is a list of rows.
Vectors can be represented by a single row. The data-structure is the same, it will simply be a 1-column matrix.
Additional values:
n: number
m: number
values: EquationNode[][]
Example:
[1,2,3]
, [[1,2,3][4,5,6][7,8,9]]
Multiple operators targeting a single value.
Types:
positive
: Plus-sign unary. Symbols:+
negative
: Minus-sign unary. Symbols:-
,−
(Minus Sign (U+2212))positive-negative
: Plus/minus-sign unary. Symbols:±
(Plus minus symbol (U+00B1))
Additional values:
value: EquationNode
Example:
-2
, 5*(±2)
Multiple operators and comparisons targetting two values.
Types:
plus
: Addition. Symbols:+
minus
: Subtraction. Symbols:-
,−
(U+2212 Minus Sign)plus-minus
: Addition/subtraction. Symbols:±
(U+00B1 Plus minus symbol)multiply-implicit
: Implicit multiplication. Symbols:multiply-dot
: Multiply with dot. Symbols:*
,∗
(U+2217 Asterisk Operator),⋅
(U+22C5 Dot Operator)multiply-cross
: Multiplication with cross. Symbols:×
(U+00D7 Multiplication Sign),✕
(U+2715 Multiplication X)divide-fraction
: Division as fraction. Symbols:/
,∕
(U+2215 Division Slash)divide-inline
: Division as inline operator. Symbols:÷
(U+00F7 Division Sign)power
: Raise to power. Symbols:^
equals
: Comparison. Symbols:=
less-than
: Comparison. Symbols:<
greater-than
: Comparison. Symbols:>
less-than-equals
: Comparison. Symbols:≤
(U+2264 Less-Than or Equal To)greater-than-equals
: Comparison. Symbols:≥
(U+2265 Greater-Than or Equal To)approximates
: Comparison. Symbols:≈
(U+2248 Almost Equal To)
Additional values:
a: EquationNode
b: EquationNode
Example:
1+2
, 2/5
, 1+2=3
Represents a missing operand (number, variable, function, block).
Example:
_
, _+2
, f(_)
Represents a function without a name.
Additional values:
args: EquationNode[]
Example:
_(2)
, _(a, b)
Represents a missing binary operator, such as plus
or equals
.
Additional values:
a: EquationNode
b: EquationNode
Example:
2 ? 3
Represents a missing unary operator, such as negative
or positive-negative
.
Additional values:
value: EquationNode
Example:
?2
, 2+(?3)
Represents an error in parsing. Not technically an EquationNode
, since it cannot be a subvalue of any other nodes, but it can be returned by the parse
function.
The type of error is represented by the errorType
-value, taking one of the following:
numberWhitespace
: Unexpected space in a numberinvalidNumber
: Invalid numberadjecentOperator
: Two operators next to each otherinvalidChar
: Unrecognized characterinvalidUnary
: This operator cannot be used as a unary operatormultipleExpressions
: There are a few cases where the expression doesn't proberly terminate. This is generally the result of a library limitation.matrixMixedDimension
: The rows of a matrix are different dimensionsmatrixEmpty
: A matrix has no elementsvectorEmpty
: A vector has no elementsexpectedEnd
: Expected end of equation, not a close parenthesis or similarexpectedSquareBracket
: Expected a closing square-bracket, not a different type of parenthesis or the end of the equationexpectedCloseParens
: Expected a closing parenthesis, not a diffent type of parenthesis or the end of the equationoperatorLast
: The equation ends on an operatoremptyBlock
: Parenthesis without content