lemon-mint 0.1.4

Famous Lemon Parser Generator implemented in rust as library with API.
Documentation
# lemon-mint
Famous Lemon Parser Generator implemented in rust as library with API.

## Example

```rust
extern crate lemon_mint;

use std::fs::File;
use std::sync::Arc;
use lemon_mint::LemonMintBuilder;

fn main()
{	let builder = LemonMintBuilder::new().load_y
	(	&Arc::new("source.y".to_string()), // fake source name, that will appear in error messages
		"	%trace {>> }
			%extra_argument {()}
			%left PLUS MINUS.
			%left TIMES DIVIDE.
			%token_type {f64}
			%type Expr {super::Expr}
			%type Exprs {Vec<super::Expr>}
			%type Program {Vec<super::Expr>}

			Program ::= Exprs(exprs). exprs
			Program ::= Exprs(exprs) NEW_LINE. exprs

			Exprs ::= Expr(item).                       vec![item]
			Exprs ::= Exprs(items) NEW_LINE Expr(item). let mut items = items; items.push(item); items

			Expr ::= NUM(value). super::Expr {value}
			Expr ::= PAR_OPEN Expr(a) PAR_CLOSE. a
			Expr ::= PLUS Expr(a). a
			Expr ::= MINUS Expr(a). let mut a = a; a.value = -a.value; a
			Expr ::= Expr(a) PLUS Expr(b). super::Expr{value: a.value + b.value}
			Expr ::= Expr(a) MINUS Expr(b). super::Expr{value: a.value - b.value}
			Expr ::= Expr(a) TIMES Expr(b). super::Expr{value: a.value * b.value}
			Expr ::= Expr(a) DIVIDE Expr(b). super::Expr{value: a.value / b.value}

			%code {
				use code::{Parser, Token};

                #[derive(Debug, PartialEq)]
				pub struct Expr {value: f64}

				fn main()
				{	let mut parser = Parser::new(()); // () is our extra argument, that will be accessible in actions, and also through parser.extra

					parser.add_token(Token::NUM, 15.0).unwrap();
					parser.add_token(Token::DIVIDE, 0.0).unwrap();
					parser.add_token(Token::NUM, 5.0).unwrap();
					parser.add_token(Token::NEW_LINE, 0.0).unwrap();

					let result = parser.end().unwrap(); // if Program
                    assert_eq!(result, vec![Expr {value: 3.0}]);
                    println!(\"Result: {:?}\", result);
				}
			}
		".as_bytes()
	).unwrap();

	let lemon = builder.try_into_lemon().unwrap();
	let mut out_rust = File::create("/tmp/main.rs").unwrap();
	let mut out_y = File::create("/tmp/main.y").unwrap();
	lemon.gen_rust(&mut out_rust).unwrap();
	lemon.gen_log(&mut out_y, false, false).unwrap();
}
```

The first step is to create `LemonMintBuilder` object, and use it's methods to describe the desired parser. It's possible to load "y"-grammar from a file with `load_y_file()`, or from a string with `load_y()`, as shown in the example above, or you can set each parser rule with individual methods, like `set_start_symbol()`, `set_token_type()`, `add_type()`, `add_rule()`, and others.

Then the builder object can be converted to `LemonMint` object that represents the parser transition tables. This step is done with the `try_into_lemon()` method, as shown above.

And the last step is to generate a rust file with parser tables and it's driver code. This is done with `gen_rust()` method. Optionally you can generate log file with `gen_log()`, as classic Lemon program does.

## Y-Grammar

Lemon-mint uses y-grammar similar to what [classic Lemon parser](https://www.hwaci.com/sw/lemon/) uses. There are a few distinctions:

* If a symbol name contains at least one lowercase letter, it's considered nonterminal. In classic Lemon only the first letter matters.
* To enable trace, use `%trace` directive. In Lemon need to call ParseTrace() function.
* No need for `%name` directive, because in rust each file is separate module.
* No need for destructors.

The generated parser will be separated to 2 submodules: `code` and `rules`. There are only 2 interesting things in `code` module: `Parser` and `Token`. See in above example how they're used. The `rules` module wraps actions, and you don't need to use it directly. If your actions use types, constants or functions global space, they can be accessed like `super::Expr`, or `crate::Expr`, or so.

The following directives are supported:

* %token_type
* %type
* %default_type
* %start_symbol
* %trace
* %extra_argument - only it's type. The name is always `extra`. Default type is `()`.
* %left
* %right
* %nonassoc
* %fallback
* %code or %include - are the same

The syntax is free and permissive:

```
%start_symbol {Unit}
/* or */
%start_symbol Unit.
/* or */
%start_symbol Unit
```

Braces allow to specify multiline value, till matching closing brace. Supported line and multiline C-style comments.