arithmetic-parser 0.2.0-beta.1

Parser for arithmetic expressions with flexible literals and type annotations.
Documentation
# Flexible Arithmetic Parser

[![Build Status](https://github.com/slowli/arithmetic-parser/workflows/Rust/badge.svg?branch=master)](https://github.com/slowli/arithmetic-parser/actions)
[![License: Apache-2.0](https://img.shields.io/github/license/slowli/arithmetic-parser.svg)](https://github.com/slowli/arithmetic-parser/blob/master/LICENSE)
![rust 1.41.0+ required](https://img.shields.io/badge/rust-1.41.0+-blue.svg) 

**Links:** [![Docs.rs](https://docs.rs/arithmetic-parser/badge.svg)](https://docs.rs/arithmetic-parser/)
[![crate docs (master)](https://img.shields.io/badge/master-yellow.svg?label=docs)](https://slowli.github.io/arithmetic-parser/arithmetic_parser/) 
[![changelog](https://img.shields.io/badge/-changelog-orange)](CHANGELOG.md)

A versatile parser for arithmetic expressions which allows customizing literal definitions,
type annotations and several other aspects of parsing.

## Supported Features

- **Variables.** A variable name is defined similar to Rust and other programming languages,
  as a sequence of alphanumeric chars and underscores that does not start with a digit.
- **Literals.** The parser for literals is user-provided, thus allowing to apply the library
  to different domains (e.g., finite group arithmetic).
- Python-like **comments** staring with `#`.
- Basic **arithmetic operations**: `+`, `-` (binary and unary), `*`, `/`, `^` (power).
  The parser outputs AST with nodes organized according to the operation priority.
- **Boolean operations**: `==`, `!=`, `&&`, `||`, `!`.
- **Function calls**: `foo(1.0, x)`.
- **Parentheses** which predictably influence operation priority.

The parser supports both complete and streaming (incomplete) modes; the latter is useful
for REPLs and similar applications.

### Optional Features

These features can be switched on or off when defining a grammar.

- **Tuples.** A tuple is two or more elements separated by commas, such as `(x, y)`
  or `(1, 2 * x)`. Tuples are parsed both as lvalues and rvalues.
- **Function definitions.** A definition looks like a closure definition in Rust, e.g.,
  `|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).
- **Blocks.** A block is several `;`-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)`.
- **Methods.** Method call is a function call separated from the receiver with a `.` char;
  for example, `foo.bar(2, x)`. 
- **Type annotations.** A type annotation in the form `var: Type` can be present
  in the lvalues or in the function argument definitions. The parser for type annotations
  is user-defined.
- **Order comparisons,** that is, `>`, `<`, `>=`, and `<=` boolean ops.
  (The reason is that these ops do not make sense for some grammars, 
  such as for modular arithmetic.)

### Code Sample

Here is an example of code parsed with the grammar with real-valued literals
and the only supported type `Num`:

```text
# This is a comment.
x = 1 + 2.5 * 3 + sin(a^3 / b^2);
# Function declarations have syntax similar to Rust closures.
some_function = |a, b: Num| (a + b, a - b);
other_function = |x| {
    r = min(rand(), 0.5);
    r * x
};
# Tuples and blocks are supported and have a similar syntax to Rust.
(y, z: Num) = some_function({ x = x - 0.5; x }, x);
other_function(y - z)
```

## Implementation Details 

The parser is based on the [`nom`](https://docs.rs/nom/) crate. The core trait of the library,
`Grammar`, is designed in such a way that switching [optional features](#optional-features)
should not induce run-time overhead; the unused parsing code paths should be removed during
compilation.

## License

Licensed under the [Apache-2.0 license](LICENSE).