Returning '.currentChar' method because this makes parsers cleaner (presumably without any performance loss); removed char returns from other methods and simplified some duplicated code
This commit is contained in:
parent
cb10fc8f83
commit
1c6f829c9f
@ -41,22 +41,18 @@ impl<
|
||||
type P = W::WP;
|
||||
type CS = W::WCS;
|
||||
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> bool {
|
||||
return self
|
||||
._src
|
||||
.skipNext(&mut PredicateConverter::wrap(predicate, &self._converter))
|
||||
.map(|c| self._converter.convertChar(c));
|
||||
.skipNext(&mut PredicateConverter::wrap(predicate, &self._converter));
|
||||
}
|
||||
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
|
||||
let (cs, wrongChar) = self
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||
let cs = self
|
||||
._src
|
||||
.collect(&mut PredicateConverter::wrap(predicate, &self._converter));
|
||||
|
||||
return (
|
||||
self._converter.convertSubstring(cs),
|
||||
wrongChar.map(|c| self._converter.convertChar(c)),
|
||||
);
|
||||
return self._converter.convertSubstring(cs);
|
||||
}
|
||||
|
||||
fn pos(&self) -> W::WP {
|
||||
@ -66,4 +62,8 @@ impl<
|
||||
fn nextChar(&mut self) -> Option<W::WC> {
|
||||
return self._src.nextChar().map(|c| self._converter.convertChar(c));
|
||||
}
|
||||
|
||||
fn currentChar(&self) -> Option<Self::C> {
|
||||
return self._src.currentChar().map(|c| self._converter.convertChar(c));
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,47 +30,35 @@ impl<'source, C: Copy> CollectedSubstring for ArrayCollectedSubstring<'source, C
|
||||
pub struct ArraySourceStream<'source, C: Copy, PC: PosCounter<C>> {
|
||||
_source: &'source [C],
|
||||
__iter: Iter<'source, C>,
|
||||
_current: C,
|
||||
_current: Option<C>,
|
||||
_posRaw: usize,
|
||||
_posHighlevel: PC,
|
||||
_isEnded: bool,
|
||||
}
|
||||
|
||||
impl<'source, C: Copy, PC: PosCounter<C>> ArraySourceStream<'source, C, PC> {
|
||||
pub fn start(arr: &'source [C], pos: PC) -> Option<(Self, C)> {
|
||||
pub fn start(arr: &'source [C], pos: PC) -> Self {
|
||||
let mut iter = arr.iter();
|
||||
let first = iter.next().copied();
|
||||
match first {
|
||||
None => None,
|
||||
Some(c) => {
|
||||
let stream = ArraySourceStream {
|
||||
_source: arr,
|
||||
__iter: iter,
|
||||
_current: c,
|
||||
_posRaw: 0,
|
||||
_posHighlevel: pos,
|
||||
_isEnded: false,
|
||||
};
|
||||
return Some((stream, c));
|
||||
}
|
||||
}
|
||||
let stream = ArraySourceStream {
|
||||
_source: arr,
|
||||
__iter: iter,
|
||||
_current: first,
|
||||
_posRaw: 0,
|
||||
_posHighlevel: pos,
|
||||
};
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source, 'pos, C: Copy, PC: PosCounter<C>> ArraySourceStream<'source, C, PC> {
|
||||
fn _next(&mut self) -> Option<C> {
|
||||
if !self._isEnded {
|
||||
self._posHighlevel.update(self._current);
|
||||
if let Some(c) = self._current {
|
||||
self._posHighlevel.update(c);
|
||||
self._posRaw += 1;
|
||||
}
|
||||
match self.__iter.next() {
|
||||
None => return None,
|
||||
Some(c) => {
|
||||
self._isEnded = true;
|
||||
self._current = *c;
|
||||
return Some(self._current);
|
||||
}
|
||||
}
|
||||
|
||||
self._current = self.__iter.next().copied();
|
||||
return self._current;
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,40 +67,13 @@ impl<'source, C: Copy, PC: PosCounter<C>> SourceStream for ArraySourceStream<'so
|
||||
type P = PC::P;
|
||||
type CS = ArrayCollectedSubstring<'source, C>;
|
||||
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
||||
loop {
|
||||
match self._next() {
|
||||
None => return None,
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => return Some(c),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||
let startPosRaw = self._posRaw;
|
||||
|
||||
let wrongChar: Option<C>;
|
||||
loop {
|
||||
match self._next() {
|
||||
None => {
|
||||
wrongChar = None;
|
||||
break;
|
||||
}
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => {
|
||||
wrongChar = Some(c);
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
self.skipNext(predicate);
|
||||
|
||||
let slice = &self._source[startPosRaw..self._posRaw];
|
||||
return (ArrayCollectedSubstring { slice: slice }, wrongChar);
|
||||
return ArrayCollectedSubstring { slice: slice };
|
||||
}
|
||||
|
||||
fn pos(&self) -> Self::P {
|
||||
@ -122,4 +83,8 @@ impl<'source, C: Copy, PC: PosCounter<C>> SourceStream for ArraySourceStream<'so
|
||||
fn nextChar(&mut self) -> Option<Self::C> {
|
||||
return self._next();
|
||||
}
|
||||
|
||||
fn currentChar(&self) -> Option<Self::C> {
|
||||
return self._current;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,18 @@
|
||||
use std::marker::PhantomData;
|
||||
use crate::pos::{PosCounter};
|
||||
use crate::pos::PosCounter;
|
||||
use crate::{CollectedSubstring, Predicate, SourceStream};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
pub struct EmptySourceStream<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> {
|
||||
_pos: PC,
|
||||
__phantom: PhantomData<(C, CS)>
|
||||
__phantom: PhantomData<(C, CS)>,
|
||||
}
|
||||
|
||||
impl<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> EmptySourceStream<C, CS, PC> {
|
||||
pub fn start(pos: PC) -> (Self, Option<C>) {
|
||||
let stream = EmptySourceStream { _pos: pos, __phantom: PhantomData::default() };
|
||||
return (stream, None);
|
||||
pub fn start(pos: PC) -> Self {
|
||||
return EmptySourceStream {
|
||||
_pos: pos,
|
||||
__phantom: PhantomData::default(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,11 +23,15 @@ impl<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> SourceStream
|
||||
type P = PC::P;
|
||||
type CS = CS;
|
||||
|
||||
fn skipNext(&mut self, _: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
||||
return None;
|
||||
fn skipCurrent(&mut self, _: &mut impl Predicate<Self::C>) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn collect(&mut self, _: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
|
||||
fn skipNext(&mut self, _: &mut impl Predicate<Self::C>) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
fn collect(&mut self, _: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||
panic!("How about to check first char of substring being collected first");
|
||||
}
|
||||
|
||||
@ -36,4 +42,8 @@ impl<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> SourceStream
|
||||
fn nextChar(&mut self) -> Option<Self::C> {
|
||||
return None;
|
||||
}
|
||||
|
||||
fn currentChar(&self) -> Option<Self::C> {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,50 +31,55 @@ impl<'source> CollectedSubstring for StrCollectedSubstring<'source> {
|
||||
pub struct StrSourceStream<'source, PC: PosCounter<char>> {
|
||||
_source: &'source str,
|
||||
__iter: CharIndices<'source>,
|
||||
_current: char,
|
||||
_current: Option<char>,
|
||||
_posRaw: usize,
|
||||
_posCodePoints: usize,
|
||||
_posHighlevel: PC,
|
||||
_isEnded: bool,
|
||||
}
|
||||
|
||||
impl<'source, PC: PosCounter<char>> StrSourceStream<'source, PC> {
|
||||
pub fn start(s: &'source str, pos: PC) -> Option<(Self, char)> {
|
||||
pub fn start(s: &'source str, pos: PC) -> Self {
|
||||
let mut it = s.char_indices();
|
||||
let first = it.next();
|
||||
|
||||
let mut stream = StrSourceStream {
|
||||
_source: s,
|
||||
__iter: it,
|
||||
_current: None,
|
||||
_posRaw: s.len(),
|
||||
_posCodePoints: 0,
|
||||
_posHighlevel: pos,
|
||||
};
|
||||
|
||||
match first {
|
||||
None => return None,
|
||||
None => {}
|
||||
Some((p, c)) => {
|
||||
let stream = StrSourceStream {
|
||||
_source: s,
|
||||
__iter: it,
|
||||
_current: c,
|
||||
_posRaw: p,
|
||||
_posCodePoints: 0,
|
||||
_posHighlevel: pos,
|
||||
_isEnded: false,
|
||||
};
|
||||
return Some((stream, c));
|
||||
stream._current = Some(c);
|
||||
stream._posRaw = p
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
|
||||
impl<'source, PC: PosCounter<char>> StrSourceStream<'source, PC> {
|
||||
fn _next(&mut self) -> Option<char> {
|
||||
if !self._isEnded {
|
||||
self._posHighlevel.update(self._current);
|
||||
if let Some(c) = self._current {
|
||||
self._posHighlevel.update(c);
|
||||
self._posCodePoints += 1;
|
||||
}
|
||||
|
||||
match self.__iter.next() {
|
||||
None => return None,
|
||||
None => {
|
||||
self._posRaw = self._source.len();
|
||||
self._current = None;
|
||||
}
|
||||
Some((p, c)) => {
|
||||
self._isEnded = true;
|
||||
self._posRaw = p;
|
||||
self._current = c;
|
||||
return Some(self._current);
|
||||
self._current = Some(c);
|
||||
}
|
||||
}
|
||||
return self._current;
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,47 +88,17 @@ impl<'source, PC: PosCounter<char>> SourceStream for StrSourceStream<'source, PC
|
||||
type P = PC::P;
|
||||
type CS = StrCollectedSubstring<'source>;
|
||||
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
||||
loop {
|
||||
match self._next() {
|
||||
None => return None,
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => return Some(c),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>) {
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||
let startPosRaw = self._posRaw;
|
||||
let startPosCP = self._posCodePoints;
|
||||
|
||||
let wrongChar: Option<char>;
|
||||
loop {
|
||||
match self._next() {
|
||||
None => {
|
||||
wrongChar = None;
|
||||
break;
|
||||
}
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => {
|
||||
wrongChar = Some(c);
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
self.skipNext(predicate);
|
||||
|
||||
let slice = &self._source[startPosRaw..self._posRaw];
|
||||
return (
|
||||
StrCollectedSubstring {
|
||||
slice: slice,
|
||||
size: self._posCodePoints - startPosCP,
|
||||
},
|
||||
wrongChar,
|
||||
);
|
||||
return StrCollectedSubstring {
|
||||
slice: slice,
|
||||
size: self._posCodePoints - startPosCP,
|
||||
};
|
||||
}
|
||||
|
||||
fn pos(&self) -> Self::P {
|
||||
@ -133,4 +108,8 @@ impl<'source, PC: PosCounter<char>> SourceStream for StrSourceStream<'source, PC
|
||||
fn nextChar(&mut self) -> Option<Self::C> {
|
||||
return self._next();
|
||||
}
|
||||
|
||||
fn currentChar(&self) -> Option<Self::C> {
|
||||
return self._current;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,18 +10,32 @@ pub trait SourceStream {
|
||||
type P: Pos;
|
||||
type CS: CollectedSubstring<C = Self::C>;
|
||||
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C>;
|
||||
|
||||
fn skipCurrent(
|
||||
&mut self,
|
||||
current: Self::C,
|
||||
predicate: &mut impl Predicate<Self::C>,
|
||||
) -> Option<Self::C> {
|
||||
if !predicate.check(current) {
|
||||
return Some(current);
|
||||
}
|
||||
) -> bool {
|
||||
match self.currentChar() {
|
||||
None => return true,
|
||||
Some(c) => {
|
||||
if !predicate.check(c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return self.skipNext(predicate);
|
||||
return self.skipNext(predicate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> bool {
|
||||
loop {
|
||||
match self.nextChar() {
|
||||
None => return true,
|
||||
Some(c) => match predicate.check(c) {
|
||||
true => continue,
|
||||
false => return false,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,9 +50,11 @@ pub trait SourceStream {
|
||||
* Calling this method on ended stream (previous `nextChar` returned `None`)
|
||||
* is undefined behavior.
|
||||
*/
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> (Self::CS, Option<Self::C>);
|
||||
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS;
|
||||
|
||||
fn pos(&self) -> Self::P;
|
||||
|
||||
fn nextChar(&mut self) -> Option<Self::C>;
|
||||
|
||||
fn currentChar(&self) -> Option<Self::C>;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user