Skip to content

Commit 557d9a6

Browse files
committed
Fix hacks for RepeatFallback
1 parent a7b755c commit 557d9a6

File tree

1 file changed

+34
-33
lines changed

1 file changed

+34
-33
lines changed

src/lib.rs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,7 @@ enum Decoder {
782782
Record(Vec<(Cow<'static, str>, Decoder)>),
783783
While(MatchTree, Box<Decoder>),
784784
Until(MatchTree, Box<Decoder>),
785-
RepeatFallback(Box<Decoder>, Box<Decoder>),
785+
RepeatFallback(MatchTree, Box<Decoder>, Box<Decoder>),
786786
RepeatCount(Expr, Box<Decoder>),
787787
RepeatUntilLast(Expr, Box<Decoder>),
788788
RepeatUntilSeq(Expr, Box<Decoder>),
@@ -2381,7 +2381,18 @@ impl Decoder {
23812381
Rc::new(Next::Repeat(wide, next.clone())),
23822382
)?);
23832383

2384-
Ok(Decoder::RepeatFallback(dnarrow, dwide))
2384+
// Under the precondition that narrow is a subset of wide, the union of the two matchtrees is just the
2385+
// matchtree for wide
2386+
2387+
let wide_star = Format::Repeat(wide.clone());
2388+
let f_wide = Format::Tuple(vec![(**wide).clone(), wide_star]);
2389+
let f_empty = Format::EMPTY;
2390+
2391+
if let Some(tree) = MatchTree::build(compiler.module, &[f_wide, f_empty], next) {
2392+
Ok(Decoder::RepeatFallback(tree, dnarrow, dwide))
2393+
} else {
2394+
Err(format!("Cannot build match tree for {format:?}"))
2395+
}
23852396
}
23862397
Format::Repeat1(a) => {
23872398
if a.is_nullable(compiler.module) {
@@ -2604,43 +2615,33 @@ impl Decoder {
26042615
}
26052616
Ok((Value::Seq(v), input))
26062617
}
2607-
Decoder::RepeatFallback(subset, superset) => {
2608-
let mut accum = Vec::new();
2609-
let mut incr_input = input;
2618+
Decoder::RepeatFallback(tree, subset, superset) => {
2619+
let mut input = input;
2620+
let mut v = Vec::new();
2621+
let mut decoder = subset;
2622+
let mut fellback = false;
26102623

2611-
loop {
2612-
match subset.parse(program, scope, incr_input) {
2613-
Ok((b, next_input)) => {
2614-
accum.push(b);
2615-
incr_input = next_input;
2624+
while tree.matches(input).ok_or(ParseError::NoValidBranch {
2625+
offset: input.offset,
2626+
})? == 0
2627+
{
2628+
match decoder.parse(program, scope, input) {
2629+
Ok((va, next_input)) => {
2630+
input = next_input;
2631+
v.push(va);
26162632
}
2617-
Err(_err) => break,
2618-
}
2619-
}
2620-
2621-
// track the last offset we reached to see if we get any further
2622-
let checkpoint = incr_input.offset;
2623-
2624-
loop {
2625-
match superset.parse(program, scope, incr_input) {
2626-
Ok((b, next_input)) => {
2627-
accum.push(b);
2628-
incr_input = next_input;
2633+
err @ Err(_) => {
2634+
if fellback {
2635+
return err;
2636+
} else {
2637+
decoder = superset;
2638+
fellback = true;
2639+
}
26292640
}
2630-
Err(_err) => break,
26312641
}
26322642
}
26332643

2634-
if let Err(e) = (Decoder::EndOfInput).parse(program, scope, incr_input) {
2635-
return Err(e);
2636-
}
2637-
2638-
let fellthrough = incr_input.offset > checkpoint;
2639-
2640-
Ok((
2641-
Value::Fallback(fellthrough, Box::new(Value::Seq(accum))),
2642-
incr_input,
2643-
)) // index 1
2644+
Ok((Value::Fallback(fellback, Box::new(Value::Seq(v))), input))
26442645
}
26452646
Decoder::RepeatCount(expr, a) => {
26462647
let mut input = input;

0 commit comments

Comments
 (0)