Ejemplo n.º 1
0
        private IEnumerable <IPgnSymbol> ChildTerminalSymbolsInRange(int start, int length)
        {
            // Find the first child node that intersects with the given range.
            // Can safely call GetChildIndexAfter because of invariant: start < this.Length
            int childIndex       = GetChildIndexAfter(0 <= start ? start : 0);
            int childEndPosition = GetChildStartPosition(childIndex);

            while (childIndex < ChildCount && childEndPosition < start + length)
            {
                int childStartPosition = childEndPosition;
                childEndPosition = GetChildStartOrEndPosition(childIndex + 1);

                // Skip empty child nodes.
                if (childStartPosition < childEndPosition)
                {
                    PgnSyntax childNode = GetChild(childIndex);

                    if (childNode.IsTerminalSymbol(out IPgnSymbol pgnTerminalSymbol))
                    {
                        yield return(pgnTerminalSymbol);
                    }
                    else
                    {
                        // Translate to relative child position by subtracting childStartPosition.
                        foreach (var descendant in childNode.ChildTerminalSymbolsInRange(start - childStartPosition, length))
                        {
                            yield return(descendant);
                        }
                    }
                }

                childIndex++;
            }
        }