/// <inheritdoc /> protected override GrammarNode <Char>?VisitStringTerminal(StringTerminal stringTerminal, OptimizeArgs argument) { if (stringTerminal.Value.Length == 1) { return(new CharacterTerminal(stringTerminal.Value[0])); } else { return(stringTerminal); } }
/// <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 !)); } }
/// <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);