Exemple #1
0
 /// <summary>
 /// Folds a negated set node.
 /// </summary>
 /// <param name="negatedSet"></param>
 /// <param name="argument">The argument to be passed to the visitor method.</param>
 /// <returns>
 /// <list type="number">
 /// <item>The original node if it's to be kept</item>
 /// <item>A different node to replace the original node with</item>
 /// <item>Null if the node is to be removed</item>
 /// </list>
 /// </returns>
 protected override GrammarNode <Char>?VisitNegatedSet(NegatedSet negatedSet, TArgument argument) => negatedSet;
 protected override String?VisitNegatedSet(NegatedSet negatedSet, Unit argument) => null;
Exemple #3
0
 /// <summary>
 /// Visits a negated set node.
 /// </summary>
 /// <param name="negatedSet"></param>
 /// <param name="argument">The argument data passed by the caller.</param>
 /// <returns>The result of visiting this node.</returns>
 protected abstract TReturn VisitNegatedSet(NegatedSet negatedSet, TArgument argument);
            protected override GrammarNode <Char>?VisitNegatedSet(NegatedSet negatedSet, OptimizeArgs argument)
            {
                var characters = negatedSet.Characters.ToList();
                var ranges     = negatedSet.Ranges.ToList();
                var categories = negatedSet.UnicodeCategories.ToList();
                // We don't want inner sets to be optimized since we'll flatten them.
                OptimizeArgs childrenArgument    = argument.WithIsParentASet(true);
                List <GrammarNode <Char> > nodes =
                    negatedSet.Nodes.Select(node => this.Visit(node, childrenArgument))
                    .Where(node => node is not null)
                    .ToList() !;

                var nodeIdx = 0;

                while (true)
                {
loopStart:
                    if (nodeIdx >= nodes.Count)
                    {
                        break;
                    }

                    GrammarNode <Char> node = nodes[nodeIdx] !;
                    switch (node.Kind)
                    {
                    case GrammarNodeKind.CharacterTerminal:
                    {
                        var characterTerminal = (CharacterTerminal)node;
                        nodes.RemoveAt(nodeIdx);
                        characters.Add(characterTerminal.Value);
                        goto loopStart;
                    }

                    case GrammarNodeKind.CharacterRange:
                    {
                        var characterRange = (CharacterRange)node;
                        nodes.RemoveAt(nodeIdx);
                        ranges.Add(characterRange.Range);
                        goto loopStart;
                    }

                    case GrammarNodeKind.CharacterUnicodeCategoryTerminal:
                    {
                        var unicodeCategoryTerminal = (UnicodeCategoryTerminal)node;
                        nodes.RemoveAt(nodeIdx);
                        categories.Add(unicodeCategoryTerminal.Category);
                        goto loopStart;
                    }

                    case GrammarNodeKind.CharacterSet:
                    {
                        var subSet = (Set)node;
                        nodes.RemoveAt(nodeIdx);
                        characters.AddRange(subSet.Characters);
                        ranges.AddRange(subSet.Ranges);
                        categories.AddRange(subSet.UnicodeCategories);
                        nodes.AddRange(subSet.Nodes);
                        goto loopStart;
                    }
                    }
                    nodeIdx++;
                }

                characters.Sort();
                OptimizationAlgorithms.ExpandRanges(characters, ranges, true);
                OptimizationAlgorithms.RangifyCharacters(characters, ranges, true);
                OptimizationAlgorithms.MergeRanges(ranges);

                ImmutableArray <Char> flattenedRanges = CharUtils.FlattenRanges(ranges);
                var categoriesFlagSet = CharUtils.CreateCategoryFlagSet(categories);

                OptimizationAlgorithms.RemoveMatchedCharacters(characters, flattenedRanges, categoriesFlagSet);

                // Characters are still sorted at this point
                CharacterBitVector?characterBitVector = null;

                if (characters.Any())
                {
                    var charactersDistance = characters[characters.Count - 1] - characters[0];
                    if (charactersDistance is > 1 and <= 256)
                    {
                        characterBitVector = new CharacterBitVector(characters);
                    }
                }

                return(new OptimizedNegatedSet(
                           characters.ToImmutableHashSet(),
                           flattenedRanges,
                           categoriesFlagSet,
                           nodes.ToImmutableArray(),
                           characterBitVector));
            }
Exemple #5
0
 /// <summary>
 /// Initializes a new set element.
 /// </summary>
 /// <param name="negatedSet"></param>
 public SetElement(NegatedSet negatedSet) : this((GrammarNode <Char>)negatedSet)
 {
 }