Skip to content

Commit

Permalink
Fix memory issue with large character set ranges
Browse files Browse the repository at this point in the history
Fixes #48
  • Loading branch information
cwensley committed May 23, 2021
1 parent 9abf3ea commit 235b3a0
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 5 deletions.
17 changes: 17 additions & 0 deletions Eto.Parse.Tests/Samples/LargeCharcterSetRange.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Eto.Parse.Grammars;
using NUnit.Framework;

namespace Eto.Parse.Tests.Samples
{
[TestFixture]
public class LargeCharcterSetRange
{
[Test]
public void LargeRangeShouldntCauseMemoryException()
{
var _grammar = new EbnfGrammar(EbnfStyle.W3c).Build($"id ::= [a-zA-Z\u0100-\uffff_][0-9a-zA-Z\u0100-\uffff_]*", "id");
var _match = _grammar.Match("张三李四");
}

}
}
26 changes: 21 additions & 5 deletions Eto.Parse/Grammar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ public class Grammar : UnaryParser
public bool AllowPartialMatch { get; set; }

public bool Trace { get; set; }

/// <summary>
/// Sets the maximum character set range when <see cref="GrammarOptimizations.CharacterSetAlternations"/> is enabled.
/// </summary>
/// <value></value>
public int MaxCharacterSetRangeOptimization { get; set; } = 100;

public GrammarOptimizations Optimizations { get; set; }

Expand Down Expand Up @@ -264,6 +270,7 @@ void OptimizeCharacterSets()
{
var chars = new List<char>();
var inverse = new List<char>();
var additionalParsers = new List<Parser>();
for (int i1 = 0; i1 < alt.Items.Count; i1++)
{
Parser item = alt.Items[i1];
Expand All @@ -288,12 +295,19 @@ void OptimizeCharacterSets()
var charRange = item as CharRangeTerminal;
if (charRange != null)
{
for (char i = charRange.Start; i <= charRange.End; i++)
if (charRange.End - charRange.Start > MaxCharacterSetRangeOptimization)
{
additionalParsers.Add(charRange);
}
else
{
if (charRange.Inverse)
inverse.Add(i);
else
chars.Add(i);
for (char i = charRange.Start; i <= charRange.End; i++)
{
if (charRange.Inverse)
inverse.Add(i);
else
chars.Add(i);
}
}
continue;
}
Expand All @@ -313,6 +327,8 @@ void OptimizeCharacterSets()
{
Inverse = true
});
if (additionalParsers.Count > 0)
alt.Items.AddRange(additionalParsers);
}
}
}
Expand Down

0 comments on commit 235b3a0

Please sign in to comment.