// #![feature(external_doc)]
// #![doc(include = "../README.md")]
//! For an introduction and context view, read...
//!
//! [README.md](https://github.com/jleahred/dynparser)
//!
//! A very basic example...
//! ```rust
//! extern crate dynparser;
//! use dynparser::{parse, rules_from_peg};
//!
//! fn main() {
//! let rules = rules_from_peg(
//! r#"
//!
//! main = letter letter_or_num+
//!
//! letter = [a-zA-Z]
//!
//! letter_or_num = letter
//! / number
//!
//! number = [0-9]
//!
//! "#,
//! ).unwrap();
//!
//! assert!(parse("a2AA456bzJ88", &rules).is_ok());
//! }
//!```
//!
//!
//! The classical calculator example
//!
//! ```rust
//! extern crate dynparser;
//! use dynparser::{parse, rules_from_peg};
//!
//!
//! fn main() {
//! let rules = rules_from_peg(
//! r#"
//!
//! main = _ expr _
//!
//! expr = add_t (_ add_op _ add_t)*
//! / portion_expr
//!
//! add_t = fact_t (_ fact_op _ fact_t)*
//!
//! fact_t = portion_expr
//!
//! portion_expr = '(' expr ')'
//! / item
//!
//! item = num
//!
//! num = [0-9]+ ('.' [0-9]+)?
//! add_op = '+' / '-'
//! fact_op = '*' / '/'
//!
//! _ = ' '*
//!
//! "#,
//! ).map_err(|e| {
//! println!("{}", e);
//! panic!("FAIL");
//! })
//! .unwrap();
//!
//! let result = parse(" 1 + 2* 3 +(5/5 - (8-7))", &rules);
//! match result {
//! Ok(ast) => println!(
//! "{:#?}",
//! ast.compact()
//! .prune(&vec!["_"])
//! .passthrow_except(&vec!["main", "add_t", "fact_t"])
//! ),
//! Err(e) => println!("Error: {:?}", e),
//! };
//! }
//! ```
//!
//! Please, read [README.md](https://github.com/jleahred/dynparser) for
//! more context information
//!
//! ```rust
//! extern crate dynparser;
//! use dynparser::{parse, rules_from_peg};
//! fn main() {
//! let rules = rules_from_peg(
//! r#"
//!
//! main = '(' main ( ')' / error("unbalanced parenthesis") )
//! / 'hello'
//!
//! "#,
//! ).unwrap();
//!
//! match parse("((hello)", &rules) {
//! Ok(_) => panic!("It should fail"),
//! Err(e) => assert!(e.descr == "unbalanced parenthesis"),
//! }
//! }
//! ```
extern crate idata;
// -------------------------------------------------------------------------------------
// M A C R O S
/// Create a map of rules
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => and!{
/// lit!("aa"),
/// ref_rule!("rule2")
/// },
/// "rule2" => and!{
/// lit!("b"),
/// lit!("c")
/// }
/// };
///
/// assert!(parse("aabc", &rules).is_ok())
/// }
/// ```
/// Create a literal
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => lit!("aa")
/// };
///
/// assert!(parse("aa", &rules).is_ok())
/// }
/// ```
/// Generate an error
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => error!("aa")
/// };
///
/// assert!(parse("aa", &rules).is_err())
/// }
/// ```
///
/// ```rust
/// extern crate dynparser;
/// use dynparser::{parse, rules_from_peg};
/// fn main() {
/// let rules = rules_from_peg(
/// r#"
///
/// main = '(' main ( ')' / error("unbalanced parenthesis") )
/// / 'hello'
///
/// "#,
/// ).unwrap();
///
/// match parse("((hello)", &rules) {
/// Ok(_) => panic!("It should fail"),
/// Err(e) => assert!(e.descr == "unbalanced parenthesis"),
/// }
/// }
/// ```
/// Atom::Dot (any character)
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => and!(dot!(), dot!())
/// };
///
/// assert!(parse("aa", &rules).is_ok())
/// }
/// ```
/// Generate a match expression with optional characters and a list
/// of bounds
///
/// "String", from 'a', to 'b', from 'c', to 'd'
/// The first string, is a set of chars.
/// Later you can write a list of tuples with ranges to validate
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => rep!(ematch!( chlist "cd",
/// from 'a', to 'b',
/// from 'j', to 'p'
/// ), 0)
/// };
///
/// assert!(parse("aabcdj", &rules).is_ok())
/// }
/// ```
///
///
/// You can also pass a list of chars and a vector of char bounds as next
/// example
///
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => rep!(ematch!( chlist "cd",
/// from2 vec![
/// ('a', 'b'),
/// ('j', 'p')
/// ]
/// ), 0)
/// };
///
/// assert!(parse("aabcdj", &rules).is_ok())
/// }
/// ```
/// Concat expressions (and)
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => and!(dot!(), dot!())
/// };
///
/// assert!(parse("aa", &rules).is_ok())
/// }
/// ```
/// Choose expressions (or)
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => or!(lit!("z"), lit!("a"))
/// };
///
/// assert!(parse("a", &rules).is_ok())
/// }
/// ```
/// negate expression
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => and!(not!(lit!("b")), dot!())
/// };
///
/// assert!(parse("a", &rules).is_ok())
/// }
/// ```
///
/// not! will not move the parsing position
/// repeat expression.
/// You have to define minimum repetitions and optionally
/// maximum repetitions (if missing, infinite)
///
/// example
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => rep!(lit!("a"), 0)
/// };
///
/// assert!(parse("aaaaaaaa", &rules).is_ok())
/// }
/// ```
/// repeating from 0 to infinite
///
/// ```
/// #[macro_use] extern crate dynparser;
/// use dynparser::parse;
///
/// fn main() {
/// let rules = rules!{
/// "main" => rep!(lit!("a"), 0, 3)
/// };
///
/// assert!(parse("aaa", &rules).is_ok())
/// }
/// ```
/// This will create a subexpression referring to a "rule name"
///
/// ```
/// #[macro_use] extern crate dynparser;
///
/// fn main() {
/// let rules = rules!{
/// "main" => ref_rule!("3a"),
/// "3a" => lit!("aaa")
/// };
///
/// assert!(dynparser::parse("aaa", &rules).is_ok())
/// }
/// ```
// M A C R O S
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// T Y P E S
// T Y P E S
// -------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------
// A P I
/// Parse a string with a set of rules
///
/// the `main` rule is the starting point to parse
///
/// # Examples
///
/// Parse a simple literal
///
/// ```
/// #[macro_use] extern crate dynparser;
///
/// fn main() {
/// let rules = rules!{
/// "main" => ref_rule!("3a"),
/// "3a" => lit!("aaa")
/// };
///
/// assert!(dynparser::parse("aaa", &rules).is_ok())
/// }
///
/// ```
/// More examples in macros
///
/// Same as parser, but with debug info
///
/// It will trace the rules called
///
/// It's expensive, use it just to develop and locate errors
///
pub use rules_from_peg;
// A P I
// -------------------------------------------------------------------------------------
//-----------------------------------------------------------------------
// I N T E R N A L