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
impl OwnedInteractiveParser
pub fn new(
lark: Arc<Lark>,
text: String,
start: Option<&str>,
) -> Result<Self, ParseError>
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> ⓘ
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
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
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>
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>
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>
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>
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>
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>
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>
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>
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>
pub fn accepts(&self) -> Vec<String>
The terminals this state accepts; see InteractiveParser::accepts.
pub fn last_token(&self) -> Option<&Token>
pub fn last_token(&self) -> Option<&Token>
The last terminal shifted; see InteractiveParser::last_token.
pub fn choices(&self) -> BTreeMap<String, ChoiceAction>
pub fn choices(&self) -> BTreeMap<String, ChoiceAction>
The full action map; see InteractiveParser::choices.
pub fn pretty(&self) -> String
pub fn pretty(&self) -> String
Human-readable choices dump; see InteractiveParser::pretty.
pub fn result(&self) -> Option<&NodeValue>
pub fn result(&self) -> Option<&NodeValue>
The last feed’s return value; see InteractiveParser::result.
pub fn copy_unchecked(&self) -> Self
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>
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.