A versatile parser for arithmetic expressions which allows customizing literal definitions, type annotations and several other aspects of parsing.
#
.+
, -
(binary and unary), *
, /
, ^
(power).
The parser outputs AST with nodes organized according to the operation priority.==
, !=
, &&
, ||
, !
.foo(1.0, x)
.The parser supports both complete and streaming (incomplete) modes; the latter is useful for REPLs and similar applications.
These features can be switched on or off when defining a grammar.
(x, y)
or (1, 2 * x)
. Tuples are parsed both as lvalues and rvalues.|x| x - 10
or |x, y| { z = max(x, y); (z - x, z - y) }
. A definition may be
assigned to a variable (which is the way to define named functions).;
-delimited statements enclosed in {}
braces,
e.g, { z = max(x, y); (z - x, z - y) }
. The blocks can be used in all contexts
instead of a simple expression; for example, min({ z = 5; z - 1 }, 3)
..
char;
for example, foo.bar(2, x)
. var: Type
can be present
in the lvalues or in the function argument definitions. The parser for type annotations
is user-defined.Here is an example of code parsed with the grammar with real-valued literals
and the only supported type Num
:
```text
x = 1 + 2.5 * 3 + sin(a^3 / b^2);
somefunction = |a, b: Num| (a + b, a - b); otherfunction = |x| { r = min(rand(), 0.5); r * x };
(y, z: Num) = somefunction({ x = x - 0.5; x }, x); otherfunction(y - z) ```
The parser is based on the nom
crate. The core trait of the library,
Grammar
, is designed in such a way that switching optional features
should not induce run-time overhead; the unused parsing code paths should be removed during
compilation.
Licensed under the Apache-2.0 license.