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.>
, <
, >=
, and <=
boolean ops.
(The reason is that these ops do not make sense for some grammars,
such as for modular arithmetic.)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.