Skip to content

Commit a026ada

Browse files
authored
Fix duplicate parser lookups (#302)
1 parent c031203 commit a026ada

1 file changed

Lines changed: 41 additions & 5 deletions

File tree

src/Parlot/Fluent/OneOf.cs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)