/// <inheritdoc />
 protected override GrammarNode <Char>?VisitStringTerminal(StringTerminal stringTerminal, OptimizeArgs argument)
 {
     if (stringTerminal.Value.Length == 1)
     {
         return(new CharacterTerminal(stringTerminal.Value[0]));
     }
     else
     {
         return(stringTerminal);
     }
 }
Example #2
0
 /// <summary>
 /// Folds a string terminal node.
 /// </summary>
 /// <param name="characterTerminalString"></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>?VisitStringTerminal(StringTerminal characterTerminalString, TArgument argument) => characterTerminalString;
 protected override String?VisitStringTerminal(StringTerminal stringTerminal, Unit argument) =>
 stringTerminal.Value;
            /// <inheritdoc />
            protected override GrammarNode <Char>?VisitSequence(Sequence <Char> sequence, OptimizeArgs argument)
            {
                var nodes = sequence.GrammarNodes.Select(node => this.Visit(node, argument))
                            .Where(node => node is not null)
                            .ToList();

                for (var nodeIdx = 0; nodeIdx < nodes.Count; nodeIdx++)
                {
loopStart:
                    GrammarNode <Char> currentNode = nodes[nodeIdx] !;

                    if (nodeIdx < nodes.Count - 1)
                    {
                        GrammarNode <Char> nextNode = nodes[nodeIdx + 1] !;
                        if (currentNode is CharacterTerminal currentCharacterTerminal)
                        {
                            if (nextNode is CharacterTerminal nextCharacterTerminal)
                            {
                                nodes.RemoveAt(nodeIdx);
                                nodes[nodeIdx] = new StringTerminal(new String(new[] { currentCharacterTerminal.Value, nextCharacterTerminal.Value }));
                                goto loopStart;
                            }
                            else if (nextNode is StringTerminal nextStringTerminal)
                            {
                                nodes.RemoveAt(nodeIdx);
                                nodes[nodeIdx] = new StringTerminal(currentCharacterTerminal.Value + nextStringTerminal.Value);
                                goto loopStart;
                            }
                        }
                        else if (currentNode is StringTerminal currentStringTerminal)
                        {
                            if (nextNode is CharacterTerminal nextCharacterTerminal)
                            {
                                nodes.RemoveAt(nodeIdx);
                                nodes[nodeIdx] = new StringTerminal(currentStringTerminal.Value + nextCharacterTerminal.Value);
                                goto loopStart;
                            }
                            else if (nextNode is StringTerminal nextStringTerminal)
                            {
                                nodes.RemoveAt(nodeIdx);
                                nodes[nodeIdx] = new StringTerminal(currentStringTerminal.Value + nextStringTerminal.Value);
                                goto loopStart;
                            }
                        }
                    }
                }

                if (nodes.Count == 0)
                {
                    return(null);
                }
                else if (nodes.Count == 1)
                {
                    return(nodes[0]);
                }
                else if (nodes.SequenceEqual(sequence.GrammarNodes))
                {
                    return(sequence);
                }
                else
                {
                    return(new Sequence <Char>(nodes !));
                }
            }
Example #5
0
 /// <summary>
 /// Visits a string terminal.
 /// </summary>
 /// <param name="characterTerminalString"></param>
 /// <param name="argument">The argument data passed by the caller.</param>
 /// <returns>The result of visiting this node.</returns>
 protected abstract TReturn VisitStringTerminal(StringTerminal characterTerminalString, TArgument argument);