Skip to main content

Munch

Struct Munch 

Source
pub struct Munch { /* private fields */ }
Expand description

Many patterns, matched anchored at one offset, longest wins.

Immutable, and Send + Sync on the same terms as crate::Regex: the C handle owns the buffers its scans rewrite, so the type keeps a pool of handles and leases one per scan.

Implementations§

Source§

impl Munch

Source

pub fn new<I, S>(patterns: I) -> Result<Self, Error>
where S: AsRef<str>, I: IntoIterator<Item = S>,

Compile every pattern in patterns as one anchored slate, with the default semantics crate::Regex::new uses.

§Errors

Error::NothingLexable when no pattern could be determinized, which is the only refusal that leaves nothing to work with. A partial refusal is success — read it with Munch::declined.

Source

pub fn patterns(&self) -> &[String]

The patterns this was compiled from, in order, exactly as they were given. Index i here is the index a Token reports.

Source

pub fn len(&self) -> usize

How many patterns the slate was built from, refusals included.

Source

pub fn is_empty(&self) -> bool

Whether the slate holds no patterns at all. Such a slate matches nothing.

Source

pub fn declined(&self) -> &[Refusal]

Every pattern the engine could not take, ascending. Empty is the normal case.

// A backreference cannot be determinized, and must not cost the others.
let m = irgx::Munch::new(["[a-z]+", r"(a)\1", "[0-9]+"])?;
assert_eq!(m.declined().len(), 1);
assert_eq!(m.declined()[0].pattern, 1);
assert_eq!(m.token("123", 0).unwrap().patterns(), &[2]);
Source

pub fn admitted(&self) -> usize

How many patterns can win at once — the upper bound on Token::patterns’s length, and the capacity Munch::scan_into never needs to grow past.

The admitted count, not Munch::len: a declined pattern can never win, so it can never be reported.

Source

pub fn token(&self, text: &str, at: usize) -> Option<Token>

The longest token beginning at exactly at, over every pattern.

None when nothing starts there. at == text.len() is legal and asks the only question left at the end of the input: does anything accept the empty string.

§Panics

On an engine fault, or if at is past the end of text. See Munch::try_token.

Source

pub fn try_token(&self, text: &str, at: usize) -> Result<Option<Token>, Error>

Munch::token, reporting a fault instead of panicking.

§Errors

Error::Search or Error::OutOfMemory if the engine could not answer, and Error::Inconsistent if at is past the end of text.

Source

pub fn token_among(&self, text: &str, at: usize, allow: &[u32]) -> Option<Token>

The longest token beginning at exactly at, restricted to the patterns allow names.

Restriction happens during the walk, not after: a forbidden pattern reaching further would otherwise hide every permitted one behind it.

let m = irgx::Munch::new(["if", "[a-z]+"])?;
// Unrestricted, the identifier wins and swallows the keyword.
assert_eq!(m.token("iffy", 0).unwrap().patterns(), &[1]);
// Restricted to the keyword, the answer is `if` — not nothing, which is
// what filtering the unrestricted answer would have produced.
assert_eq!(m.token_among("iffy", 0, &[0]).unwrap().len(), 2);

An empty allow permits nothing, which is a real question with a knowable answer (None) rather than an error: a lexer state can legitimately reach a point where no terminal is legal. Naming a pattern the engine declined is a no-op, so a caller with a fallback need not also remember which its blind terminals were.

§Panics

As Munch::token. See Munch::try_token_among.

Source

pub fn try_token_among( &self, text: &str, at: usize, allow: &[u32], ) -> Result<Option<Token>, Error>

Munch::token_among, reporting a fault instead of panicking.

§Errors

As Munch::try_token.

Source

pub fn shortest_among( &self, text: &str, at: usize, allow: &[u32], ) -> Option<Token>

The shortest non-empty token beginning at exactly at, restricted to the patterns allow names. See Pick::Shortest for when that is the question you have.

§Panics

As Munch::token. See Munch::try_shortest_among.

Source

pub fn try_shortest_among( &self, text: &str, at: usize, allow: &[u32], ) -> Result<Option<Token>, Error>

Munch::shortest_among, reporting a fault instead of panicking.

§Errors

As Munch::try_token.

Source

pub fn scan_into( &self, text: &str, at: usize, allow: Option<&[u32]>, pick: Pick, winners: &mut Vec<u32>, ) -> Result<Option<usize>, Error>

One scan, writing the winning patterns into winners instead of allocating — the allocation-free form the other four are built on.

A lexer calls this once per token, and a Box<[u32]> per token is a real cost for an answer that is almost always one number long. This form reuses the caller’s buffer: winners is cleared, filled with the winning pattern indices ascending, and the token’s byte length is returned. Ok(None) means nothing starts at at, and leaves winners empty.

let m = irgx::Munch::new(["[a-z]+", "[0-9]+", r"\s+"])?;
let text = "ab 12";
let mut winners = Vec::with_capacity(m.admitted());
let mut at = 0;
let mut spans = Vec::new();
while at < text.len() {
    let len = m
        .scan_into(text, at, None, irgx::Pick::Longest, &mut winners)?
        .filter(|len| *len > 0)
        .expect("every byte of this text starts some token");
    spans.push((at..at + len, winners[0]));
    at += len;
}
assert_eq!(spans, vec![(0..2, 0), (2..3, 2), (3..5, 1)]);
§Errors

As Munch::try_token.

Trait Implementations§

Source§

impl Clone for Munch

Source§

fn clone(&self) -> Self

Recompiles the patterns, because a compiled slate cannot be duplicated through the C ABI. The compile is pure, so the clone behaves identically.

§Panics

If the recompile fails. The patterns already compiled once, so the only way that happens is an allocation failure.

1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Munch

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl !Freeze for Munch

§

impl RefUnwindSafe for Munch

§

impl Send for Munch

§

impl Sync for Munch

§

impl Unpin for Munch

§

impl UnsafeUnpin for Munch

§

impl UnwindSafe for Munch

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.