File tree Expand file tree Collapse file tree 2 files changed +41
-12
lines changed Expand file tree Collapse file tree 2 files changed +41
-12
lines changed Original file line number Diff line number Diff line change @@ -398,20 +398,29 @@ impl Hir {
398398 /// Returns the alternation of the given expressions.
399399 ///
400400 /// This flattens the alternation as appropriate.
401- pub fn alternation ( mut exprs : Vec < Hir > ) -> Hir {
402- if exprs. is_empty ( ) {
403- return Hir :: fail ( ) ;
404- } else if exprs. len ( ) == 1 {
405- return exprs. pop ( ) . unwrap ( ) ;
406- }
407- match exprs. len ( ) {
408- 0 => Hir :: empty ( ) ,
409- 1 => exprs. pop ( ) . unwrap ( ) ,
410- _ => {
411- let props = Properties :: alternation ( & exprs) ;
412- Hir { kind : HirKind :: Alternation ( exprs) , props }
401+ pub fn alternation ( hirs : Vec < Hir > ) -> Hir {
402+ // We rebuild the alternation by simplifying it. We proceed similarly
403+ // as the concatenation case. But in this case, there's no literal
404+ // simplification happening. We're just flattening alternations.
405+ let mut new = vec ! [ ] ;
406+ for hir in hirs {
407+ let ( kind, props) = hir. into_parts ( ) ;
408+ match kind {
409+ HirKind :: Alternation ( hirs2) => {
410+ new. extend ( hirs2) ;
411+ }
412+ kind => {
413+ new. push ( Hir { kind, props } ) ;
414+ }
413415 }
414416 }
417+ if new. is_empty ( ) {
418+ return Hir :: fail ( ) ;
419+ } else if new. len ( ) == 1 {
420+ return new. pop ( ) . unwrap ( ) ;
421+ }
422+ let props = Properties :: alternation ( & new) ;
423+ Hir { kind : HirKind :: Alternation ( new) , props }
415424 }
416425
417426 /// Returns an HIR expression for `.`.
Original file line number Diff line number Diff line change @@ -3335,4 +3335,24 @@ mod tests {
33353335 ] )
33363336 ) ;
33373337 }
3338+
3339+ // This tests that the smart Hir::alternation constructor simplifies the
3340+ // given exprs in a way we expect.
3341+ #[ test]
3342+ fn smart_alternation ( ) {
3343+ assert_eq ! (
3344+ t( "(?:foo)|(?:bar)" ) ,
3345+ hir_alt( vec![ hir_lit( "foo" ) , hir_lit( "bar" ) ] )
3346+ ) ;
3347+ assert_eq ! (
3348+ t( "quux|(?:abc|def|xyz)|baz" ) ,
3349+ hir_alt( vec![
3350+ hir_lit( "quux" ) ,
3351+ hir_lit( "abc" ) ,
3352+ hir_lit( "def" ) ,
3353+ hir_lit( "xyz" ) ,
3354+ hir_lit( "baz" ) ,
3355+ ] )
3356+ ) ;
3357+ }
33383358}
You can’t perform that action at this time.
0 commit comments