pub struct Parser<'a> { /* private fields */ }Expand description
Push-based LR parser. Call maybe_reduce in a loop,
then shift each token. Rule 0 signals acceptance.
Implementations§
Source§impl<'a> Parser<'a>
impl<'a> Parser<'a>
Sourcepub fn maybe_reduce(
&mut self,
lookahead: Option<Token>,
) -> Result<Option<(usize, usize, usize)>, ParseError>
pub fn maybe_reduce( &mut self, lookahead: Option<Token>, ) -> Result<Option<(usize, usize, usize)>, ParseError>
Check if a reduction should happen for the given lookahead.
Returns Ok(Some((rule, len, start_idx))) if a reduction should occur.
The start_idx together with token_count() forms the half-open range [start_idx, token_count()).
Returns Ok(None) if should shift or if accepted.
Returns Err(ParseError) on parse error.
Sourcepub fn shift(&mut self, token: Token)
pub fn shift(&mut self, token: Token)
Shift a token onto the stack.
Call this only after maybe_reduce returns Ok(None), meaning no
more reductions apply for the current lookahead.
Sourcepub fn restore_checkpoint(&mut self)
pub fn restore_checkpoint(&mut self)
Restore parser state to before the current reduction sequence.
When using a runtime grammar, call this after maybe_reduce returns
a reduction you want to handle yourself, to undo the speculative
stack modifications before continuing.
Sourcepub fn state(&self) -> usize
pub fn state(&self) -> usize
Get the current LR automaton state (an opaque index into the parse table).
Sourcepub fn token_count(&self) -> usize
pub fn token_count(&self) -> usize
Get the count of tokens shifted so far.
Sourcepub fn state_at(&self, depth: usize) -> usize
pub fn state_at(&self, depth: usize) -> usize
Get the LR automaton state at a given stack depth (0 = bottom of stack).
Sourcepub fn format_error(
&self,
terminal: SymbolId,
ctx: &impl ErrorContext,
display_names: Option<&[(&str, &str)]>,
tokens: Option<&[&str]>,
) -> String
pub fn format_error( &self, terminal: SymbolId, ctx: &impl ErrorContext, display_names: Option<&[(&str, &str)]>, tokens: Option<&[&str]>, ) -> String
Format a parse error into a detailed message.
Call this after maybe_reduce returns an error.
display_names: optional map from grammar names to user-friendly names (e.g.,"SEMI"→"';'").tokens: optional token texts by index (must include the error token at indextoken_count()).
§Adding source locations
The parser is push-based, so the lexer knows the source position when each token is pushed. Capture the location before pushing and use it when formatting the error:
loop {
let (line, col) = src.line_col();
let tok = lex_one_token(&mut src);
if let Err(ParseError::Syntax { terminal }) = parser.push(tok, &mut actions) {
let msg = parser.format_error(terminal, ctx, None, None);
return Err(format!("{line}:{col}: {msg}"));
}
}Sourcepub fn recover(&mut self, buffer: &[Token]) -> Vec<RecoveryInfo>
pub fn recover(&mut self, buffer: &[Token]) -> Vec<RecoveryInfo>
Recover from parse errors by finding minimum-cost repairs.
Takes the remaining token buffer (starting from the error token). Returns a list of errors found, each with the repairs applied. An empty result means no viable recovery was found within the search budget. On success the parser state is advanced past the repaired region and parsing can continue.