Skip to main content

OwnedInteractiveParser

Struct OwnedInteractiveParser 

pub struct OwnedInteractiveParser { /* private fields */ }
Expand description

An interactive LALR parser that owns its backing Lark and input text, so it can be stored in a binding handle and driven token-by-token across calls. Build one with Lark’s interactive entry (bindings call OwnedInteractiveParser::new).

Mirrors Lark’s InteractiveParser (the mutable variant): feed_token one token, feed_next to pull-and-feed the next lexer token (Self::feed_token / Self::feed_next), exhaust_lexer/resume_parse to drive to the end, feed_eof to finish, plus accepts/choices/pretty introspection and copy to fork. The immutable copy-on-feed variant is provided by the language bindings on top of copy; core only carries the mutable parser.

Beyond Lark: peek_next borrows the next token unfed as &mut Token, so it can be retyped or rewritten before any driving call sends it, and peeked reports what is queued without lexing. This is the substrate a binding builds its own substitution call on — no guest writes through a borrow (Python hands its guest a COPY of the peeked token and commits edits explicitly, a JS object cannot write through wasm, C feeds by name), so a parameterized edit — “send the queued token, but as terminal X with value Y” — belongs here once rather than re-derived per binding. A binding must NOT hand out a raw pointer to the borrowed token: it lives in the cursor’s queue and is moved out by the next feed of any kind.

Implementations§

§

impl OwnedInteractiveParser

pub fn new( lark: Arc<Lark>, text: String, start: Option<&str>, ) -> Result<Self, ParseError>

Seat an owning interactive parser over text, starting at start (or the grammar’s single start symbol when None). Errors exactly as Lark::interactive_borrowed does — non-LALR, custom-lexer, or an unresolvable start raise ParseError.

pub fn parse_table(&self) -> Arc<ParseTable>

The parse table (for terminal-id lookups when building tokens to feed, and for materializing a finished tree). Cheap Arc clone.

pub fn text(&self) -> &str

The seated source text — so a caller (e.g. the C binding) can render a parse error’s get_context caret against the real input instead of an empty string.

pub fn transformer_held_by_current_thread(&self) -> bool

Whether THIS thread currently holds the backing Lark’s embedded transformer hook (i.e. the call site is inside a transformer callback window); see Lark::transformer_held_by_current_thread. Bindings use it to reject a reentrant drive with a clean error before the feed would deadlock on the hook mutex.

pub fn feed_token(&mut self, token: Token) -> Result<(), ParseError>

Feed one token; see InteractiveParser::feed_token.

pub fn feed_next(&mut self) -> Result<Option<Token>, ParseError>

Pull the next lexer token, feed it, and return it (or None at end of input); see InteractiveParser::feed_next. The lazy step behind iter_parse.

pub fn peek_next(&mut self) -> Result<Option<&mut Token>, ParseError>

Borrow the next token without feeding it — the lexer’s proposal, open to revision; see InteractiveParser::peek_next. The next driving call sends it.

Retyping it to $END through this borrow is the one edit that breaks the parse (see Self::retype_peeked, which rejects that id); prefer retype_peeked for a checked rewrite.

pub fn peeked(&self) -> Option<&Token>

What is queued for the next feed, if anything — read-only, and it does not lex; see InteractiveParser::peeked.

pub fn retype_peeked( &mut self, type_id: usize, value: Option<&str>, ) -> Result<bool, ParseError>

Rewrite the token Self::peek_next is holding: send it as terminal type_id, and with value when given.

Returns false only at END OF INPUT. It does NOT mean “nothing was queued”: this goes through peek_next, which LEXES when the queue is empty — so with an empty queue it pulls a fresh token and rewrites that one. The Python binding relies on exactly that (it is the apply-onto-the-next-token arm of feed_next), but a caller reading this as a no-op guard would be wrong.

The parameterized drain a binding needs. A binding cannot hand peek_next’s &mut Token to its guest, and feeding a replacement by name would build a Token::synthetic and null all six positions — so the substitution happens HERE, on the queued token, which keeps them. The rewritten token is sent by the next driving call, as any queued token is. type_id should come from ParseTable::token_id; an out-of-range id is rejected here as a Configuration error rather than left to index-panic on the next feed (this is pub, and a panic crossing an FFI boundary aborts instead of raising). $END is rejected for a different reason: the queued token is sent by an ordinary driving call, which accepts the grammar but hands back a token and never the finished tree — retyping to $END would leave the caller an unfinishable parse. Finish with Self::feed_eof.

pub fn exhaust_lexer(&mut self) -> Result<Vec<Token>, ParseError>

Feed every remaining lexer token; see InteractiveParser::exhaust_lexer.

pub fn feed_eof(&mut self) -> Result<ParsedTree, ParseError>

Finish with a bare $END; see InteractiveParser::feed_eof.

pub fn resume_parse(&mut self) -> Result<ParsedTree, ParseError>

Drive the rest of the parse to completion; see InteractiveParser::resume_parse.

pub fn accepts(&self) -> Vec<String>

The terminals this state accepts; see InteractiveParser::accepts.

pub fn last_token(&self) -> Option<&Token>

The last terminal shifted; see InteractiveParser::last_token.

pub fn choices(&self) -> BTreeMap<String, ChoiceAction>

The full action map; see InteractiveParser::choices.

pub fn pretty(&self) -> String

Human-readable choices dump; see InteractiveParser::pretty.

pub fn result(&self) -> Option<&NodeValue>

The last feed’s return value; see InteractiveParser::result.

pub fn copy_unchecked(&self) -> Self

Fork into an independent parser sharing the same backing grammar + text; see InteractiveParser::copy. The fork keeps the same Arc backings alive.

With an embedded transformer= whose hook defers work (a batching binding), the two branches’ value stacks share the original’s pending single-consumption values, so whichever branch resolves one first steals it from the other. This method does NOT check for that, which is why it must be asked for BY NAME: Self::copy refuses instead. Call it only where a transformer is impossible by construction (WASM), or where the caller already refused (the Python binding raises in its own copy).

pub fn copy(&self) -> Result<Self, ParseError>

Fork into an independent parser, REFUSING when the instance carries an embedded transformer — the two branches would otherwise share the original’s pending single-consumption values (see Self::copy_unchecked, which does not check).

Checked BY DEFAULT on purpose: a caller who never thinks about transformers gets the safe answer, and the unchecked fork has to be asked for by name.

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

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.