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 P = W::WP;
|
||||||
type CS = W::WCS;
|
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
|
return self
|
||||||
._src
|
._src
|
||||||
.skipNext(&mut PredicateConverter::wrap(predicate, &self._converter))
|
.skipNext(&mut PredicateConverter::wrap(predicate, &self._converter));
|
||||||
.map(|c| self._converter.convertChar(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 (cs, wrongChar) = self
|
let cs = self
|
||||||
._src
|
._src
|
||||||
.collect(&mut PredicateConverter::wrap(predicate, &self._converter));
|
.collect(&mut PredicateConverter::wrap(predicate, &self._converter));
|
||||||
|
|
||||||
return (
|
return self._converter.convertSubstring(cs);
|
||||||
self._converter.convertSubstring(cs),
|
|
||||||
wrongChar.map(|c| self._converter.convertChar(c)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self) -> W::WP {
|
fn pos(&self) -> W::WP {
|
||||||
@ -66,4 +62,8 @@ impl<
|
|||||||
fn nextChar(&mut self) -> Option<W::WC> {
|
fn nextChar(&mut self) -> Option<W::WC> {
|
||||||
return self._src.nextChar().map(|c| self._converter.convertChar(c));
|
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>> {
|
pub struct ArraySourceStream<'source, C: Copy, PC: PosCounter<C>> {
|
||||||
_source: &'source [C],
|
_source: &'source [C],
|
||||||
__iter: Iter<'source, C>,
|
__iter: Iter<'source, C>,
|
||||||
_current: C,
|
_current: Option<C>,
|
||||||
_posRaw: usize,
|
_posRaw: usize,
|
||||||
_posHighlevel: PC,
|
_posHighlevel: PC,
|
||||||
_isEnded: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source, C: Copy, PC: PosCounter<C>> ArraySourceStream<'source, C, PC> {
|
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 mut iter = arr.iter();
|
||||||
let first = iter.next().copied();
|
let first = iter.next().copied();
|
||||||
match first {
|
let stream = ArraySourceStream {
|
||||||
None => None,
|
_source: arr,
|
||||||
Some(c) => {
|
__iter: iter,
|
||||||
let stream = ArraySourceStream {
|
_current: first,
|
||||||
_source: arr,
|
_posRaw: 0,
|
||||||
__iter: iter,
|
_posHighlevel: pos,
|
||||||
_current: c,
|
};
|
||||||
_posRaw: 0,
|
return stream;
|
||||||
_posHighlevel: pos,
|
|
||||||
_isEnded: false,
|
|
||||||
};
|
|
||||||
return Some((stream, c));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source, 'pos, C: Copy, PC: PosCounter<C>> ArraySourceStream<'source, C, PC> {
|
impl<'source, 'pos, C: Copy, PC: PosCounter<C>> ArraySourceStream<'source, C, PC> {
|
||||||
fn _next(&mut self) -> Option<C> {
|
fn _next(&mut self) -> Option<C> {
|
||||||
if !self._isEnded {
|
if let Some(c) = self._current {
|
||||||
self._posHighlevel.update(self._current);
|
self._posHighlevel.update(c);
|
||||||
self._posRaw += 1;
|
self._posRaw += 1;
|
||||||
}
|
}
|
||||||
match self.__iter.next() {
|
|
||||||
None => return None,
|
self._current = self.__iter.next().copied();
|
||||||
Some(c) => {
|
return self._current;
|
||||||
self._isEnded = true;
|
|
||||||
self._current = *c;
|
|
||||||
return Some(self._current);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,40 +67,13 @@ impl<'source, C: Copy, PC: PosCounter<C>> SourceStream for ArraySourceStream<'so
|
|||||||
type P = PC::P;
|
type P = PC::P;
|
||||||
type CS = ArrayCollectedSubstring<'source, C>;
|
type CS = ArrayCollectedSubstring<'source, C>;
|
||||||
|
|
||||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||||
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>) {
|
|
||||||
let startPosRaw = self._posRaw;
|
let startPosRaw = self._posRaw;
|
||||||
|
|
||||||
let wrongChar: Option<C>;
|
self.skipNext(predicate);
|
||||||
loop {
|
|
||||||
match self._next() {
|
|
||||||
None => {
|
|
||||||
wrongChar = None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Some(c) => match predicate.check(c) {
|
|
||||||
true => continue,
|
|
||||||
false => {
|
|
||||||
wrongChar = Some(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let slice = &self._source[startPosRaw..self._posRaw];
|
let slice = &self._source[startPosRaw..self._posRaw];
|
||||||
return (ArrayCollectedSubstring { slice: slice }, wrongChar);
|
return ArrayCollectedSubstring { slice: slice };
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self) -> Self::P {
|
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> {
|
fn nextChar(&mut self) -> Option<Self::C> {
|
||||||
return self._next();
|
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 crate::{CollectedSubstring, Predicate, SourceStream};
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub struct EmptySourceStream<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> {
|
pub struct EmptySourceStream<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> {
|
||||||
_pos: PC,
|
_pos: PC,
|
||||||
__phantom: PhantomData<(C, CS)>
|
__phantom: PhantomData<(C, CS)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> EmptySourceStream<C, CS, PC> {
|
impl<C: Copy, CS: CollectedSubstring<C = C>, PC: PosCounter<C>> EmptySourceStream<C, CS, PC> {
|
||||||
pub fn start(pos: PC) -> (Self, Option<C>) {
|
pub fn start(pos: PC) -> Self {
|
||||||
let stream = EmptySourceStream { _pos: pos, __phantom: PhantomData::default() };
|
return EmptySourceStream {
|
||||||
return (stream, None);
|
_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 P = PC::P;
|
||||||
type CS = CS;
|
type CS = CS;
|
||||||
|
|
||||||
fn skipNext(&mut self, _: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
fn skipCurrent(&mut self, _: &mut impl Predicate<Self::C>) -> bool {
|
||||||
return None;
|
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");
|
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> {
|
fn nextChar(&mut self) -> Option<Self::C> {
|
||||||
return None;
|
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>> {
|
pub struct StrSourceStream<'source, PC: PosCounter<char>> {
|
||||||
_source: &'source str,
|
_source: &'source str,
|
||||||
__iter: CharIndices<'source>,
|
__iter: CharIndices<'source>,
|
||||||
_current: char,
|
_current: Option<char>,
|
||||||
_posRaw: usize,
|
_posRaw: usize,
|
||||||
_posCodePoints: usize,
|
_posCodePoints: usize,
|
||||||
_posHighlevel: PC,
|
_posHighlevel: PC,
|
||||||
_isEnded: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source, PC: PosCounter<char>> StrSourceStream<'source, PC> {
|
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 mut it = s.char_indices();
|
||||||
let first = it.next();
|
let first = it.next();
|
||||||
|
|
||||||
|
let mut stream = StrSourceStream {
|
||||||
|
_source: s,
|
||||||
|
__iter: it,
|
||||||
|
_current: None,
|
||||||
|
_posRaw: s.len(),
|
||||||
|
_posCodePoints: 0,
|
||||||
|
_posHighlevel: pos,
|
||||||
|
};
|
||||||
|
|
||||||
match first {
|
match first {
|
||||||
None => return None,
|
None => {}
|
||||||
Some((p, c)) => {
|
Some((p, c)) => {
|
||||||
let stream = StrSourceStream {
|
stream._current = Some(c);
|
||||||
_source: s,
|
stream._posRaw = p
|
||||||
__iter: it,
|
|
||||||
_current: c,
|
|
||||||
_posRaw: p,
|
|
||||||
_posCodePoints: 0,
|
|
||||||
_posHighlevel: pos,
|
|
||||||
_isEnded: false,
|
|
||||||
};
|
|
||||||
return Some((stream, c));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return stream;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'source, PC: PosCounter<char>> StrSourceStream<'source, PC> {
|
impl<'source, PC: PosCounter<char>> StrSourceStream<'source, PC> {
|
||||||
fn _next(&mut self) -> Option<char> {
|
fn _next(&mut self) -> Option<char> {
|
||||||
if !self._isEnded {
|
if let Some(c) = self._current {
|
||||||
self._posHighlevel.update(self._current);
|
self._posHighlevel.update(c);
|
||||||
self._posCodePoints += 1;
|
self._posCodePoints += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.__iter.next() {
|
match self.__iter.next() {
|
||||||
None => return None,
|
None => {
|
||||||
|
self._posRaw = self._source.len();
|
||||||
|
self._current = None;
|
||||||
|
}
|
||||||
Some((p, c)) => {
|
Some((p, c)) => {
|
||||||
self._isEnded = true;
|
|
||||||
self._posRaw = p;
|
self._posRaw = p;
|
||||||
self._current = c;
|
self._current = Some(c);
|
||||||
return Some(self._current);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return self._current;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,47 +88,17 @@ impl<'source, PC: PosCounter<char>> SourceStream for StrSourceStream<'source, PC
|
|||||||
type P = PC::P;
|
type P = PC::P;
|
||||||
type CS = StrCollectedSubstring<'source>;
|
type CS = StrCollectedSubstring<'source>;
|
||||||
|
|
||||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C> {
|
fn collect(&mut self, predicate: &mut impl Predicate<Self::C>) -> Self::CS {
|
||||||
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>) {
|
|
||||||
let startPosRaw = self._posRaw;
|
let startPosRaw = self._posRaw;
|
||||||
let startPosCP = self._posCodePoints;
|
let startPosCP = self._posCodePoints;
|
||||||
|
|
||||||
let wrongChar: Option<char>;
|
self.skipNext(predicate);
|
||||||
loop {
|
|
||||||
match self._next() {
|
|
||||||
None => {
|
|
||||||
wrongChar = None;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Some(c) => match predicate.check(c) {
|
|
||||||
true => continue,
|
|
||||||
false => {
|
|
||||||
wrongChar = Some(c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let slice = &self._source[startPosRaw..self._posRaw];
|
let slice = &self._source[startPosRaw..self._posRaw];
|
||||||
return (
|
return StrCollectedSubstring {
|
||||||
StrCollectedSubstring {
|
slice: slice,
|
||||||
slice: slice,
|
size: self._posCodePoints - startPosCP,
|
||||||
size: self._posCodePoints - startPosCP,
|
};
|
||||||
},
|
|
||||||
wrongChar,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pos(&self) -> Self::P {
|
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> {
|
fn nextChar(&mut self) -> Option<Self::C> {
|
||||||
return self._next();
|
return self._next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn currentChar(&self) -> Option<Self::C> {
|
||||||
|
return self._current;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,18 +10,32 @@ pub trait SourceStream {
|
|||||||
type P: Pos;
|
type P: Pos;
|
||||||
type CS: CollectedSubstring<C = Self::C>;
|
type CS: CollectedSubstring<C = Self::C>;
|
||||||
|
|
||||||
fn skipNext(&mut self, predicate: &mut impl Predicate<Self::C>) -> Option<Self::C>;
|
|
||||||
|
|
||||||
fn skipCurrent(
|
fn skipCurrent(
|
||||||
&mut self,
|
&mut self,
|
||||||
current: Self::C,
|
|
||||||
predicate: &mut impl Predicate<Self::C>,
|
predicate: &mut impl Predicate<Self::C>,
|
||||||
) -> Option<Self::C> {
|
) -> bool {
|
||||||
if !predicate.check(current) {
|
match self.currentChar() {
|
||||||
return Some(current);
|
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`)
|
* Calling this method on ended stream (previous `nextChar` returned `None`)
|
||||||
* is undefined behavior.
|
* 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 pos(&self) -> Self::P;
|
||||||
|
|
||||||
fn nextChar(&mut self) -> Option<Self::C>;
|
fn nextChar(&mut self) -> Option<Self::C>;
|
||||||
|
|
||||||
|
fn currentChar(&self) -> Option<Self::C>;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user