Documentation

use crate::*;
use Re::*;
grammar(g: &mut usize);

pub Re: Re = {
  Alt
}

#[inline]
Digits: Bset = {
  r"\\d"  => Bset::range('0','9'),
  r"\\D"  => !Bset::range('0','9'),
}

#[inline]
Letters: Bset = {
  r"\\w"  =>   Bset::range('a','z') | Bset::range('A','Z') |  Bset::range('0','9') | Bset::fromchar('_'),
  r"\\W"  => !(Bset::range('a','z') | Bset::range('A','Z') |  Bset::range('0','9') | Bset::fromchar('_')),
}

#[inline]
Space: Bset = {
  r"\\s"  =>  Bset::str(" \t\n"),
  r"\\S"  => !Bset::str(" \t\n"),
}

#[inline]
Class: Bset = {
  Letters,
  Digits,
  Space,
}

#[inline]
Charsetchar: Bset = {
  Char0  => Bset::fromchar(<>),
  <l:Char0> r"\-" <r:Char0> => Bset::range(l,r),
  Class,
}

#[inline]
Charsetchar2: Bset = {
  Charsetchar,
  r"!"  => Bset::fromchar('!'),
  r"\(" => Bset::fromchar('('),
  r"\)" => Bset::fromchar(')'),
  r"\+" => Bset::fromchar('+'),
  r"\." => Bset::fromchar('.'),
  r"\?" => Bset::fromchar('?'),
  r"\{" => Bset::fromchar('{'),
  r"\}" => Bset::fromchar('}'),
}

#[inline]
ChsersetArray: Bset = {
  <mut v: Charsetchar2+> => {
    //let mut u = r.map(|c| Bset::fromchar(c)).unwrap_or_default();
    v.into_iter().fold(Bset(0,0), |u,v| u|v)
  }
}

#[inline]
Charset: Re = {
  r"\["   <ChsersetArray> r"\]"  => Set(<>),
  r"\["   <ChsersetArray> r"-\]" => Set(<> | Bset::fromchar('-')),
  r"\[\^" <ChsersetArray> r"\]"  => Set(!<>),
  r"\[\^" <ChsersetArray> r"-\]" => Set(!(<>| Bset::fromchar('-'))),
}

#[inline]
Char0: char = {
  r"[^\^\$\[\]\(\)\{\}!\-\*\+&?|.\\]" => <>.as_bytes()[0] as char,
  r"\\n" =>  '\n',
  r"\\[^ndDwWsS]" => <>.as_bytes()[1] as char,
}

#[inline]
Char: char = {
  Char0,
  r"\-"   => '-',
}

// /*
//   ^ => (.*\n)?
//   $ => (\n.*)?
// */

#[inline]
Atom: Re = {
  r"\^" => binop(ALT, Kle(box NON), binop(CAT, Kle(box ALP), Set(Bset::fromchar('\n')))),
  r"\$"  => binop(ALT, Kle(box NON), binop(CAT, Set(Bset::fromchar('\n')), Kle(box ALP))),
  //r"[$]"  => binop(ALT, Kle(box NON), binop(CAT, Set(Bset::fromchar('\n')), Kle(box ALP))),
  Class   => Set(<>),
  Char    => Set(Bset::fromchar(<>)),
  Charset,
  r"\."   => Set(Bset::brange(0,255)),
  r"\(" r"\?:" <Alt> r"\)",
  r"\(" <Alt> r"\)" => {
    *g+=1; 
    Cap(box <>, CG(*g))
  }
}

Post: Re = {
  Atom,
  <Post> r"!"  => unop(NOT, <>),
  <Post> r"\*" => unop(KLE, <>),
  <Post> r"\+" => unop(PLS, <>),
  //<Post> r"\+" => binop(CAT, unop(KLE, <>.clone()), <>.clone()),
  <Post> r"\?" => binop(ALT, Kle(box NON), <>),
}

Cat: Re = {
  Post,
  <l:Cat> <r:Post> => binop(CAT,l,r),
}

And: Re = {
  Cat,
  <l:And> r"\&" <r:Cat> => unop(NOT, binop(ALT,unop(NOT, l),unop(NOT, r))),
}

Alt: Re = {
  And,
  <l:Alt> r"\|" <r:And> => binop(ALT,l,r),
}

match {
  "" => {},
  _
}