@@ -24,6 +24,21 @@ pub struct InstructionMatch
24
24
}
25
25
26
26
27
+ impl InstructionMatch
28
+ {
29
+ pub fn is_same ( & self , other : & InstructionMatch ) -> bool
30
+ {
31
+ self . ruledef_ref . 0 == other. ruledef_ref . 0 &&
32
+ self . rule_ref . 0 == other. rule_ref . 0 &&
33
+ self . args . len ( ) == other. args . len ( ) &&
34
+ self . args
35
+ . iter ( )
36
+ . zip ( & other. args )
37
+ . all ( |( a, b) | a. is_same ( & b) )
38
+ }
39
+ }
40
+
41
+
27
42
#[ derive( Clone , Debug ) ]
28
43
pub enum InstructionMatchResolution
29
44
{
@@ -78,6 +93,32 @@ pub struct InstructionArgument
78
93
}
79
94
80
95
96
+ impl InstructionArgument
97
+ {
98
+ pub fn is_same ( & self , other : & InstructionArgument ) -> bool
99
+ {
100
+ if self . span != other. span
101
+ {
102
+ return false ;
103
+ }
104
+
105
+ match ( & self . kind , & other. kind )
106
+ {
107
+ ( InstructionArgumentKind :: Expr ( _) ,
108
+ InstructionArgumentKind :: Expr ( _) ) =>
109
+ true ,
110
+
111
+ ( InstructionArgumentKind :: Nested ( ref a) ,
112
+ InstructionArgumentKind :: Nested ( ref b) ) =>
113
+ a. is_same ( b) ,
114
+
115
+ _ =>
116
+ false ,
117
+ }
118
+ }
119
+ }
120
+
121
+
81
122
#[ derive( Clone , Debug ) ]
82
123
pub enum InstructionArgumentKind
83
124
{
@@ -379,7 +420,7 @@ pub fn match_instr(
379
420
working_matches. extend ( ruledef_matches) ;
380
421
}
381
422
}
382
-
423
+
383
424
if working_matches. len ( ) == 0
384
425
{
385
426
return vec ! [ ] ;
@@ -392,6 +433,10 @@ pub fn match_instr(
392
433
. collect :: < Vec < _ > > ( ) ;
393
434
394
435
436
+ // Identical duplicate matches are already sorted consecutively
437
+ matches. dedup_by ( |a, b| a. is_same ( b) ) ;
438
+
439
+
395
440
// Calculate recursive "exact" pattern-part count for
396
441
// each match
397
442
for mtch in & mut matches
@@ -546,25 +591,45 @@ fn match_with_rule<'src>(
546
591
asm:: RuleParameterType :: Signed ( _) |
547
592
asm:: RuleParameterType :: Integer ( _) =>
548
593
{
549
- return match_with_expr (
550
- defs,
551
- rule,
552
- walker,
553
- needs_consume_all_tokens,
554
- part_index,
555
- match_so_far) ;
594
+ let mut result = vec ! [ ] ;
595
+
596
+ // Try both with and without lookahead character
597
+ for enable_lookahead in [ false , true ]
598
+ {
599
+ result. extend (
600
+ match_with_expr (
601
+ defs,
602
+ rule,
603
+ walker. clone ( ) ,
604
+ needs_consume_all_tokens,
605
+ part_index,
606
+ enable_lookahead,
607
+ match_so_far. clone ( ) ) ) ;
608
+ }
609
+
610
+ return result;
556
611
}
557
612
558
613
asm:: RuleParameterType :: RuledefRef ( ruledef_ref) =>
559
614
{
560
- return match_with_nested_ruledef (
561
- defs,
562
- ruledef_ref,
563
- rule,
564
- walker,
565
- needs_consume_all_tokens,
566
- part_index,
567
- match_so_far) ;
615
+ let mut result = vec ! [ ] ;
616
+
617
+ // Try both with and without lookahead character
618
+ for enable_lookahead in [ false , true ]
619
+ {
620
+ result. extend (
621
+ match_with_nested_ruledef (
622
+ defs,
623
+ ruledef_ref,
624
+ rule,
625
+ walker. clone ( ) ,
626
+ needs_consume_all_tokens,
627
+ part_index,
628
+ enable_lookahead,
629
+ match_so_far. clone ( ) ) ) ;
630
+ }
631
+
632
+ return result;
568
633
}
569
634
}
570
635
}
@@ -585,19 +650,23 @@ fn match_with_rule<'src>(
585
650
fn match_with_expr < ' src > (
586
651
defs : & asm:: ItemDefs ,
587
652
rule : & asm:: Rule ,
588
- walker : & mut syntax:: Walker < ' src > ,
653
+ mut walker : syntax:: Walker < ' src > ,
589
654
needs_consume_all_tokens : bool ,
590
655
at_pattern_part : usize ,
591
- match_so_far : & mut InstructionMatch )
656
+ enable_lookahead : bool ,
657
+ mut match_so_far : InstructionMatch )
592
658
-> WorkingMatches < ' src >
593
659
{
594
660
let walker_start = walker. next_useful_index ( ) ;
595
661
596
- let maybe_expr = parse_with_lookahead (
597
- & rule. pattern ,
598
- at_pattern_part,
599
- walker,
600
- |walker| expr:: parse_optional ( walker) ) ;
662
+ let Some ( maybe_expr) =
663
+ parse_with_lookahead (
664
+ & rule. pattern ,
665
+ at_pattern_part,
666
+ enable_lookahead,
667
+ & mut walker,
668
+ |walker| expr:: parse_optional ( walker) )
669
+ else { return vec ! [ ] } ;
601
670
602
671
let walker_end = walker. get_cursor_index ( ) ;
603
672
let walker_start = std:: cmp:: min ( walker_start, walker_end) ;
@@ -627,35 +696,39 @@ fn match_with_expr<'src>(
627
696
match_with_rule (
628
697
defs,
629
698
rule,
630
- walker,
699
+ & mut walker,
631
700
needs_consume_all_tokens,
632
701
at_pattern_part + 1 ,
633
- match_so_far)
702
+ & mut match_so_far)
634
703
}
635
704
636
705
637
706
fn match_with_nested_ruledef < ' src > (
638
707
defs : & asm:: ItemDefs ,
639
708
nested_ruledef_ref : util:: ItemRef < asm:: Ruledef > ,
640
709
rule : & asm:: Rule ,
641
- walker : & mut syntax:: Walker < ' src > ,
710
+ mut walker : syntax:: Walker < ' src > ,
642
711
needs_consume_all_tokens : bool ,
643
712
at_pattern_part : usize ,
644
- match_so_far : & mut InstructionMatch )
713
+ enable_lookahead : bool ,
714
+ match_so_far : InstructionMatch )
645
715
-> WorkingMatches < ' src >
646
716
{
647
717
let walker_start = walker. next_useful_index ( ) ;
648
718
let walker_limit_prev = walker. get_cursor_limit ( ) ;
649
719
650
- let nested_matches = parse_with_lookahead (
651
- & rule. pattern ,
652
- at_pattern_part,
653
- walker,
654
- |walker| match_with_ruledef (
655
- defs,
656
- nested_ruledef_ref,
657
- walker,
658
- false ) ) ;
720
+ let Some ( nested_matches) =
721
+ parse_with_lookahead (
722
+ & rule. pattern ,
723
+ at_pattern_part,
724
+ enable_lookahead,
725
+ & mut walker,
726
+ |walker| match_with_ruledef (
727
+ defs,
728
+ nested_ruledef_ref,
729
+ walker,
730
+ false ) )
731
+ else { return vec ! [ ] } ;
659
732
660
733
661
734
let mut matches = WorkingMatches :: new ( ) ;
@@ -729,11 +802,17 @@ fn match_with_nested_ruledef<'src>(
729
802
fn parse_with_lookahead < ' src , F , T > (
730
803
pattern : & asm:: RulePattern ,
731
804
at_pattern_part : usize ,
805
+ enable_lookahead : bool ,
732
806
walker : & mut syntax:: Walker < ' src > ,
733
807
parse_fn : F )
734
- -> T
808
+ -> Option < T >
735
809
where F : FnOnce ( & mut syntax:: Walker < ' src > ) -> T
736
810
{
811
+ if !enable_lookahead
812
+ {
813
+ return Some ( parse_fn ( walker) ) ;
814
+ }
815
+
737
816
let maybe_lookahead_char = find_lookahead_char (
738
817
pattern,
739
818
at_pattern_part) ;
@@ -749,11 +828,11 @@ fn parse_with_lookahead<'src, F, T>(
749
828
walker. set_cursor_limit ( limit) ;
750
829
let result = parse_fn ( walker) ;
751
830
walker. set_cursor_limit ( prev_limit) ;
752
- return result;
831
+ return Some ( result) ;
753
832
}
754
833
}
755
834
756
- parse_fn ( walker )
835
+ None
757
836
}
758
837
759
838
0 commit comments