/* #[macro_use] extern crate nom; extern crate bytes; use nom::{Compare,CompareResult,InputLength,InputIter,Slice,HexDisplay}; use std::str; use std::str::FromStr; use bytes::{Buf,MutBuf}; use bytes::buf::{BlockBuf,BlockBufCursor}; use std::ops::{Range,RangeTo,RangeFrom,RangeFull}; use std::iter::{Enumerate,Iterator}; use std::fmt; use std::cmp::{min,PartialEq}; #[derive(Clone,Copy)] #[repr(C)] pub struct BlockSlice<'a> { buf: &'a BlockBuf, start: usize, end: usize, } impl<'a> BlockSlice<'a> { fn cursor(&self) -> WrapCursor<'a> { let mut cur = self.buf.buf(); cur.advance(self.start); WrapCursor { cursor: cur, length: self.end - self.start, } } } impl<'a> fmt::Debug for BlockSlice<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "BlockSlice {{ start: {}, end: {}, data:\n{}\n}}", self.start, self.end, self.buf.bytes().unwrap_or(&b""[..]).to_hex(16)) } } impl<'a> PartialEq for BlockSlice<'a> { fn eq(&self, other: &BlockSlice<'a>) -> bool { let bufs = (self.buf as *const BlockBuf) == (other.buf as *const BlockBuf); self.start == other.start && self.end == other.end && bufs } } impl<'a> Slice> for BlockSlice<'a> { fn slice(&self, range:Range) -> Self { BlockSlice { buf: self.buf, start: self.start + range.start, //FIXME: check for valid end here end: self.start + range.end, } } } impl<'a> Slice> for BlockSlice<'a> { fn slice(&self, range:RangeTo) -> Self { self.slice(0..range.end) } } impl<'a> Slice> for BlockSlice<'a> { fn slice(&self, range:RangeFrom) -> Self { self.slice(range.start..self.end - self.start) } } impl<'a> Slice for BlockSlice<'a> { fn slice(&self, _:RangeFull) -> Self { BlockSlice { buf: self.buf, start: self.start, end: self.end, } } } impl<'a> InputIter for BlockSlice<'a> { type Item = u8; type RawItem = u8; type Iter = Enumerate>; type IterElem = WrapCursor<'a>; fn iter_indices(&self) -> Self::Iter { self.cursor().enumerate() } fn iter_elements(&self) -> Self::IterElem { self.cursor() } fn position

(&self, predicate: P) -> Option where P: Fn(Self::RawItem) -> bool { self.cursor().position(|b| predicate(b)) } fn slice_index(&self, count:usize) -> Option { if self.end - self.start >= count { Some(count) } else { None } } } impl<'a> InputLength for BlockSlice<'a> { fn input_len(&self) -> usize { self.end - self.start } } impl<'a,'b> Compare<&'b[u8]> for BlockSlice<'a> { fn compare(&self, t: &'b[u8]) -> CompareResult { let len = self.end - self.start; let blen = t.len(); let m = if len < blen { len } else { blen }; let reduced = self.slice(..m); let b = &t[..m]; for (a,b) in reduced.cursor().zip(b.iter()) { if a != *b { return CompareResult::Error; } } if m < blen { CompareResult::Incomplete } else { CompareResult::Ok } } #[inline(always)] fn compare_no_case(&self, t: &'b[u8]) -> CompareResult { let len = self.end - self.start; let blen = t.len(); let m = if len < blen { len } else { blen }; let reduced = self.slice(..m); let other = &t[..m]; if !reduced.cursor().zip(other).all(|(a, b)| { match (a,*b) { (0...64, 0...64) | (91...96, 91...96) | (123...255, 123...255) => a == *b, (65...90, 65...90) | (97...122, 97...122) | (65...90, 97...122 ) |(97...122, 65...90) => { a & 0b01000000 == *b & 0b01000000 } _ => false } }) { CompareResult::Error } else if m < blen { CompareResult::Incomplete } else { CompareResult::Ok } } } impl<'a,'b> Compare<&'b str> for BlockSlice<'a> { fn compare(&self, t: &'b str) -> CompareResult { self.compare(str::as_bytes(t)) } fn compare_no_case(&self, t: &'b str) -> CompareResult { self.compare_no_case(str::as_bytes(t)) } } //Wrapper to implement Iterator on BlockBufCursor pub struct WrapCursor<'a> { pub cursor: BlockBufCursor<'a>, pub length: usize, } impl<'a> Iterator for WrapCursor<'a> { type Item = u8; fn next(&mut self) -> Option { //println!("NEXT: length={}, remaining={}", self.length, self.cursor.remaining()); if min(self.length, self.cursor.remaining()) > 0 { self.length -=1; Some(self.cursor.read_u8()) } else { None } } } //Reimplement eat_separator instead of fixing iterators #[macro_export] macro_rules! block_eat_separator ( ($i:expr, $arr:expr) => ( { use nom::{InputLength,InputIter,Slice}; if ($i).input_len() == 0 { Ok(($i, ($i).slice(0..0))) } else { match ($i).iter_indices().position(|(_, item)| { for (_,c) in ($arr).iter_indices() { if *c == item { return false; } } true }) { Some(index) => { Ok((($i).slice(index..), ($i).slice(..index))) }, None => { Ok((($i).slice(($i).input_len()..), $i)) } } } } ) ); #[macro_export] macro_rules! block_named ( ($name:ident, $submac:ident!( $($args:tt)* )) => ( fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult, BlockSlice<'a>, u32> { $submac!(i, $($args)*) } ); ($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => ( fn $name<'a>( i: BlockSlice<'a> ) -> nom::IResult, $o, u32> { $submac!(i, $($args)*) } ); ); block_named!(sp, block_eat_separator!(&b" \t\r\n"[..])); macro_rules! block_ws ( ($i:expr, $($args:tt)*) => ( { sep!($i, sp, $($args)*) } ) ); block_named!(digit, is_a!("0123456789")); block_named!(parens, block_ws!(delimited!( tag!("("), expr, tag!(")") )) ); block_named!(factor, alt!( map_res!( block_ws!(digit), to_i64 ) | parens ) ); block_named!(term , do_parse!( init: factor >> res: fold_many0!( pair!(alt!(tag!("*") | tag!("/")), factor), init, |acc, (op, val): (BlockSlice, i64)| { if (op.cursor().next().unwrap() as char) == '*' { acc * val } else { acc / val } } ) >> (res) ) ); block_named!(expr , do_parse!( init: term >> res: fold_many0!( pair!(alt!(tag!("+") | tag!("-")), term), init, |acc, (op, val): (BlockSlice, i64)| { if (op.cursor().next().unwrap() as char) == '+' { acc + val } else { acc - val } } ) >> (res) ) ); fn blockbuf_from(input: &[u8]) -> BlockBuf { let mut b = BlockBuf::new(2, 100); b.copy_from(input); b } fn sl<'a>(input: &'a BlockBuf) -> BlockSlice<'a> { BlockSlice { buf: input, start: 0, end: input.len(), } } fn to_i64<'a>(input: BlockSlice<'a>) -> Result { let v: Vec = input.cursor().collect(); match str::from_utf8(&v) { Err(_) => Err(()), Ok(s) => match FromStr::from_str(s) { Err(_) => Err(()), Ok(i) => Ok(i) } } } #[test] fn factor_test() { let a = blockbuf_from(&b"3"[..]); println!("calculated: {:?}", factor(sl(&a))); } #[test] fn parens_test() { let input1 = blockbuf_from(&b" 2* ( 3 + 4 ) "[..]); println!("calculated 1: {:?}", expr(sl(&input1))); let input2 = blockbuf_from(&b" 2*2 / ( 5 - 1) + 3"[..]); println!("calculated 2: {:?}", expr(sl(&input2))); } */