pub struct Engine<C> { /* private fields */ }Expand description
The multi-pass fixpoint driver.
An engine owns a Schedule of passes and runs them over a
ParseTree in rounds:
- Round
rappliesschedule[r]to every node whosedepth == rand whose status isUnparsedorFailed. - Nodes expanded in round
rcreate children at depthr + 1; nodes that fail are retried at depthr + 1by the next pass. - The run reaches its fixpoint when a round finds no ready nodes, or
after
max_roundsrounds.
§Examples
use increparse::{Engine, Outcome, ParseTree, Pass, Schedule, SerialExecutor, Span};
struct MarkDone;
impl Pass for MarkDone {
type Ctx = ();
fn parse(&self, _source: &str, _span: Span, _ctx: &()) -> Outcome<()> {
Outcome::Done
}
}
let engine = Engine::with((MarkDone,));
let mut tree = ParseTree::new(0, Span::new(0, 3, 0), ());
let report = engine.run("abc", &mut tree, &SerialExecutor, &increparse::CancelToken::new());
assert!(report.reached_fixpoint);
assert_eq!(tree.status(tree.root()), increparse::Status::Done);Implementations§
Source§impl<C> Engine<C>
impl<C> Engine<C>
Sourcepub fn new(schedule: Schedule<C>) -> Engine<C>
pub fn new(schedule: Schedule<C>) -> Engine<C>
Creates an engine with default EngineConfig.
Sourcepub fn with(passes: impl Passes<C>) -> Engine<C>
pub fn with(passes: impl Passes<C>) -> Engine<C>
Creates an engine from passes directly — a tuple of mixed pass types
(up to 12) or a Vec of boxed passes:
use increparse::{pass_fn, Engine, Outcome, Span};
let a = pass_fn(|_source: &str, _span, _ctx: &()| Outcome::Done);
let b = pass_fn(|_source: &str, _span, _ctx: &()| Outcome::Done);
let engine = Engine::with((a, b)); // round 0 runs `a`, round 1 runs `b`Sourcepub fn with_config(passes: impl Passes<C>, config: EngineConfig) -> Engine<C>
pub fn with_config(passes: impl Passes<C>, config: EngineConfig) -> Engine<C>
Creates an engine with an explicit configuration.
Sourcepub fn config(&self) -> &EngineConfig
pub fn config(&self) -> &EngineConfig
The engine’s configuration.
Sourcepub fn max_rounds(&self) -> usize
pub fn max_rounds(&self) -> usize
The effective round cap: the configured cap, or one round per pass.
Sourcepub fn run<E>(
&self,
source: &str,
tree: &mut ParseTree<C>,
exec: &E,
cancel: &CancelToken,
) -> RunReport
pub fn run<E>( &self, source: &str, tree: &mut ParseTree<C>, exec: &E, cancel: &CancelToken, ) -> RunReport
Runs passes over tree until the fixpoint, the round cap, or
cancellation.
source must be the same text (at the revision the tree was created
with) that passes will slice via their spans. The tree is updated
in place; if the run is cancelled partway, the merged prefix of each
batch keeps the tree consistent and a later call resumes where this
one stopped.
When re-expanding a node that already has children (after
ParseTree::edit), produced children are matched against the
existing ones by span and context — equal children are reused
whole, so only the edited regions are re-parsed. This is why C
must implement PartialEq.
A run over an already-settled tree reports reached_fixpoint without
doing any work. A run over a non-settled tree with an empty schedule
does no work and reports neither fixpoint nor cancellation — the
root simply stays Unparsed.