pub struct GrammarMatcher { /* private fields */ }Expand description
A stateful matcher that matches sampled tokens against a compiled grammar — the core of grammar-guided generation.
One GrammarMatcher tracks one request’s decoding state. Each
decode step Metrale Engine calls Self::fill_next_token_bitmask to learn
which tokens are legal, samples one, then Self::accept_token.
Self::rollback undoes accepted tokens (e.g. for speculative
decoding); Self::reset returns to the initial state.
Implementations§
Source§impl GrammarMatcher
impl GrammarMatcher
Sourcepub fn forced_token(&mut self) -> Option<i32>
pub fn forced_token(&mut self) -> Option<i32>
The single grammar-forced next token, if the current state admits exactly one legal token.
Returns Some(token_id) when the constrained grammar leaves the
caller no choice — the token is fully determined, so the model
sampling step for this position can be skipped and token_id
emitted directly (then fed back through Self::accept_token).
Returns None when the continuation is a genuine choice (two or
more legal tokens), the state is dead (zero legal tokens), or the
matcher has already terminated.
This does NOT mutate the matcher: it computes the next-token
bitmask exactly as Self::fill_next_token_bitmask would and
inspects its cardinality. The returned token is the unique set
bit of that authoritative mask, so accepting it is equivalent to
the normal sample-then-accept path.
The packed-bitmask buffer is reused from the matcher’s scratch
(FillScratch::coalesce_bitmask), so a repeated forced_token
call — e.g. inside the Self::next_forced_tokens chain walk —
costs no per-call heap allocation.
Sourcepub fn forced_from_bitmask(
&self,
bitmask: &mut [i32],
index: usize,
) -> Option<i32>
pub fn forced_from_bitmask( &self, bitmask: &mut [i32], index: usize, ) -> Option<i32>
Inspect an already-filled next-token bitmask for the forced-token condition — the zero-extra-work entry point.
A caller that has just run Self::fill_next_token_bitmask for
the current decode step already holds the authoritative mask;
it can pass that buffer here to learn whether the step is forced
without a second partition computation. bitmask / index must
be the same buffer and slice index handed to the fill call.
Returns Some(token_id) iff the mask has exactly one bit set
(the forced token), None otherwise. Behaves identically to
Self::forced_token but reuses the caller’s mask, so the
per-token server loop pays the coalescence check for free:
let nontrivial = matcher.fill_next_token_bitmask(&mut buf, 0, false);
if let Some(tok) = matcher.forced_from_bitmask(&buf, 0) {
// skip the model sample — emit `tok` directly
}Sourcepub fn next_forced_tokens(&mut self, max: usize) -> Vec<i32>
pub fn next_forced_tokens(&mut self, max: usize) -> Vec<i32>
The maximal chain of grammar-forced tokens starting at the current state.
Coalescence’s forced-chain: after emitting a forced token the next state may itself be forced. This walks that chain and returns every forced token in order, so the caller can skip the model sample for the whole run at once. The returned vector is empty when the current state is not forced.
The matcher state is left completely UNCHANGED: each forced
token is virtually accepted to peek at the next state, and every
such virtual accept is rolled back before returning. The caller
is responsible for feeding the returned tokens back through
Self::accept_token for real.
The walk stops at the first non-forced state, at a dead state, or once a forced token terminates the matcher (a forced stop token is included as the final element — the matcher would terminate there, so there is nothing further to force).
A max cap bounds the chain length; pass usize::MAX for an
unbounded walk. A cap of 0 returns an empty vector.
Sourcepub fn accept_forced_chain(&mut self, max: usize) -> Vec<i32>
pub fn accept_forced_chain(&mut self, max: usize) -> Vec<i32>
Detect the forced chain and ACCEPT it in place — the efficient server primitive for Coalescence.
Unlike Self::next_forced_tokens, which peeks and rolls back
(leaving the caller to re-accept every token), this advances the
matcher as it walks: each forced token is detected and kept.
The matcher’s parser is therefore traversed once, not twice — no
rollback, no caller re-accept. The returned vector lists the
tokens accepted, in order, so the caller can append them to its
output and skip the model sample for each.
On return the matcher state has advanced past the whole forced run — exactly as if the caller had sampled and accepted those tokens one by one. The walk stops at the first non-forced state (the next position is a genuine choice and must be sampled), at a dead state, or once a forced token terminates the matcher.
max caps the run length (usize::MAX for unbounded); 0
accepts nothing and returns an empty vector.
Source§impl GrammarMatcher
impl GrammarMatcher
Sourcepub fn find_completion_to_accept(&mut self, max_bytes: usize) -> Option<Vec<u8>>
pub fn find_completion_to_accept(&mut self, max_bytes: usize) -> Option<Vec<u8>>
A grammar-legal byte sequence that advances the grammar from its
CURRENT state to one where the root rule can complete (a stop token
is legal), or None if none is found within max_bytes and the node
budget. The matcher state is left UNCHANGED.
Returns Some(empty) when the grammar can already stop here.
Soundness: every byte of a returned path is applied via
parser.advance, and a path is only returned once
parser.is_completed() holds — so the result is always a grammar-legal
completion. Closure-first ordering means it is not guaranteed to be the
globally shortest close, but it is a valid one and is found without
exploring content breadth.
Sourcepub fn find_completion_token_ids(
&mut self,
max_bytes: usize,
) -> Option<Vec<i32>>
pub fn find_completion_token_ids( &mut self, max_bytes: usize, ) -> Option<Vec<i32>>
Like Self::find_completion_to_accept, but returns the close as
content token ids, greedily encoded against this matcher’s vocab
(sorted_decoded_vocab, which excludes stop/special tokens — so a
close never emits a control token). Returns Some(empty) when the
grammar can already stop, and None when no bounded close exists or
a close byte is not representable as a content token.
Source§impl GrammarMatcher
impl GrammarMatcher
Sourcepub fn fill_next_token_bitmask(
&mut self,
bitmask: &mut [i32],
index: usize,
debug: bool,
) -> Result<bool, FillError>
pub fn fill_next_token_bitmask( &mut self, bitmask: &mut [i32], index: usize, debug: bool, ) -> Result<bool, FillError>
Fill bitmask with the set of tokens acceptable for the next
decode position.
index selects the matcher’s slice when the caller batches
several matchers into one tensor; for a single matcher pass 0.
debug is accepted for API parity (no effect here).
Returns Ok(true) when the mask is not all-accepting (so it
must be applied to the logits), Ok(false) when every token is
legal. Returns Err if the matcher has terminated or the buffer
is too small. Port of FillNextTokenBitmask.
Sourcepub fn find_jump_forward_string(&mut self) -> Vec<u8> ⓘ
pub fn find_jump_forward_string(&mut self) -> Vec<u8> ⓘ
Find the jump-forward string: the longest prefix that is forced by the grammar regardless of which token is sampled.
The matcher state is left unchanged. Port of
FindJumpForwardString: at each step every latest scanable
state must agree on exactly one acceptable byte; the union of
acceptable bytes having size 1 is the equivalent condition.
Sourcepub fn find_jump_forward_string_lossy(&mut self) -> String
pub fn find_jump_forward_string_lossy(&mut self) -> String
find_jump_forward_string as a UTF-8 String, lossily decoding
non-UTF-8 bytes. Convenience for callers that want text.
Source§impl GrammarMatcher
impl GrammarMatcher
Sourcepub fn new(
compiled_grammar: CompiledGrammar,
override_stop_tokens: Option<Vec<i32>>,
terminate_without_stop_token: bool,
max_rollback_tokens: i32,
) -> Self
pub fn new( compiled_grammar: CompiledGrammar, override_stop_tokens: Option<Vec<i32>>, terminate_without_stop_token: bool, max_rollback_tokens: i32, ) -> Self
Construct a matcher from a CompiledGrammar.
override_stop_tokens— whenSome, replaces the tokenizer’s detected stop tokens; must be non-empty (panics otherwise, matching the C++XGRAMMAR_CHECK).terminate_without_stop_token— terminate on root-rule completion without needing a stop token.max_rollback_tokens— accepted for API faithfulness; the C++ deprecated and ignores it (rollback is unbounded).
Port of the GrammarMatcher constructor.
Sourcepub fn from_compiled_grammar(compiled_grammar: CompiledGrammar) -> Self
pub fn from_compiled_grammar(compiled_grammar: CompiledGrammar) -> Self
Convenience constructor with default options (no stop-token override, requires a stop token, unbounded rollback).
Sourcepub fn compiled_grammar(&self) -> &CompiledGrammar
pub fn compiled_grammar(&self) -> &CompiledGrammar
The compiled grammar this matcher runs.
Sourcepub fn tokenizer_info(&self) -> &TokenizerInfo
pub fn tokenizer_info(&self) -> &TokenizerInfo
The tokenizer info the grammar was compiled against.
Sourcepub fn stop_token_ids(&self) -> &[i32]
pub fn stop_token_ids(&self) -> &[i32]
The stop token ids that terminate this matcher.
Sourcepub fn max_rollback_tokens(&self) -> i32
pub fn max_rollback_tokens(&self) -> i32
The maximum number of rollback tokens — always -1 (unbounded),
matching the deprecated C++ behavior.
Sourcepub fn is_terminated(&self) -> bool
pub fn is_terminated(&self) -> bool
True if the matcher has terminated. When
terminate_without_stop_token is set this is “root rule
completed”; otherwise it is “a stop token was accepted”.
Port of IsTerminated.
Sourcepub fn is_grammar_completed(&self) -> bool
pub fn is_grammar_completed(&self) -> bool
True if the root rule has matched at the current position — a stop token may be emitted now. Exposed for callers that need the raw completion state independently of termination policy.
Sourcepub fn accept_token(&mut self, token_id: i32, debug: bool) -> bool
pub fn accept_token(&mut self, token_id: i32, debug: bool) -> bool
Accept one sampled token and advance the matcher.
Returns false (without mutating state) if the token is not
grammar-legal, is out of range, is a special token, or the
matcher has already terminated. A stop token terminates the
matcher. Port of AcceptToken.
Sourcepub fn accept_string(&mut self, s: &str, debug: bool) -> bool
pub fn accept_string(&mut self, s: &str, debug: bool) -> bool
Accept a literal string, advancing the matcher byte by byte.
The whole string counts as one rollback step. Used to seed a
matcher or in tests. Port of AcceptString.
Sourcepub fn accept_bytes(&mut self, bytes: &[u8], debug: bool) -> bool
pub fn accept_bytes(&mut self, bytes: &[u8], debug: bool) -> bool
Accept a literal byte string — the byte-level form of
Self::accept_string (token bytes are not always UTF-8).
Sourcepub fn rollback(&mut self, n: i32)
pub fn rollback(&mut self, n: i32)
Roll back the matcher by n accepted tokens / strings.
Each prior accept_token/accept_string is one unit; a stop
token is a zero-byte unit whose rollback un-terminates the
matcher. Panics if n exceeds the recorded history. Port of
Rollback.
Sourcepub fn num_history_steps(&self) -> usize
pub fn num_history_steps(&self) -> usize
Number of accepted tokens / strings currently in the rollback history.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for GrammarMatcher
impl RefUnwindSafe for GrammarMatcher
impl Send for GrammarMatcher
impl Sync for GrammarMatcher
impl Unpin for GrammarMatcher
impl UnwindSafe for GrammarMatcher
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.