@@ -782,7 +782,7 @@ enum Decoder {
782
782
Record ( Vec < ( Cow < ' static , str > , Decoder ) > ) ,
783
783
While ( MatchTree , Box < Decoder > ) ,
784
784
Until ( MatchTree , Box < Decoder > ) ,
785
- RepeatFallback ( Box < Decoder > , Box < Decoder > ) ,
785
+ RepeatFallback ( MatchTree , Box < Decoder > , Box < Decoder > ) ,
786
786
RepeatCount ( Expr , Box < Decoder > ) ,
787
787
RepeatUntilLast ( Expr , Box < Decoder > ) ,
788
788
RepeatUntilSeq ( Expr , Box < Decoder > ) ,
@@ -2381,7 +2381,18 @@ impl Decoder {
2381
2381
Rc :: new ( Next :: Repeat ( wide, next. clone ( ) ) ) ,
2382
2382
) ?) ;
2383
2383
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
+ }
2385
2396
}
2386
2397
Format :: Repeat1 ( a) => {
2387
2398
if a. is_nullable ( compiler. module ) {
@@ -2604,43 +2615,33 @@ impl Decoder {
2604
2615
}
2605
2616
Ok ( ( Value :: Seq ( v) , input) )
2606
2617
}
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 ;
2610
2623
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) ;
2616
2632
}
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
+ }
2629
2640
}
2630
- Err ( _err) => break ,
2631
2641
}
2632
2642
}
2633
2643
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) )
2644
2645
}
2645
2646
Decoder :: RepeatCount ( expr, a) => {
2646
2647
let mut input = input;
0 commit comments