@@ -28,6 +28,42 @@ public OneOf(Parser<T>[] parsers)
2828 Parsers = parsers ?? throw new ArgumentNullException ( nameof ( parsers ) ) ;
2929 OriginalParsers = parsers ;
3030
31+ static void AddUniqueRange ( List < Parser < T > > target , IReadOnlyList < Parser < T > > items )
32+ {
33+ for ( var i = 0 ; i < items . Count ; i ++ )
34+ {
35+ var item = items [ i ] ;
36+
37+ var exists = false ;
38+ for ( var j = 0 ; j < target . Count ; j ++ )
39+ {
40+ if ( ReferenceEquals ( target [ j ] , item ) )
41+ {
42+ exists = true ;
43+ break ;
44+ }
45+ }
46+
47+ if ( ! exists )
48+ {
49+ target . Add ( item ) ;
50+ }
51+ }
52+ }
53+
54+ static void AddUniqueSingle ( List < Parser < T > > target , Parser < T > item )
55+ {
56+ for ( var j = 0 ; j < target . Count ; j ++ )
57+ {
58+ if ( ReferenceEquals ( target [ j ] , item ) )
59+ {
60+ return ;
61+ }
62+ }
63+
64+ target . Add ( item ) ;
65+ }
66+
3167 // We can't build a lookup table if there is only one parser
3268 if ( Parsers . Count <= 1 )
3369 {
@@ -63,28 +99,28 @@ public OneOf(Parser<T>[] parsers)
6399
64100 if ( c != OtherSeekableChar )
65101 {
66- lookupTable [ c ] . AddRange ( subParsers ) ;
102+ AddUniqueRange ( lookupTable [ c ] , subParsers ) ;
67103 }
68104 else
69105 {
70106 _otherParsers ??= [ ] ;
71- _otherParsers . AddRange ( subParsers ! ) ;
107+ AddUniqueRange ( _otherParsers , subParsers ) ;
72108
73109 foreach ( var entry in lookupTable )
74110 {
75- entry . Value . AddRange ( subParsers ) ;
111+ AddUniqueRange ( entry . Value , subParsers ) ;
76112 }
77113 }
78114 }
79115 }
80116 else
81117 {
82118 _otherParsers ??= [ ] ;
83- _otherParsers . Add ( parser ) ;
119+ AddUniqueSingle ( _otherParsers , parser ) ;
84120
85121 foreach ( var entry in lookupTable )
86122 {
87- entry . Value . Add ( parser ) ;
123+ AddUniqueSingle ( entry . Value , parser ) ;
88124 }
89125 }
90126 }
0 commit comments