Example #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++;
            }
        }
Example #2
0
 /// <summary>
 /// Initializes as empty.
 /// </summary>
 public SafeLazyChildSyntaxOrEmpty(PgnSyntax parent, int start)
 {
     lazyNodeIfNonEmpty = default;
     nodeIfEmpty        = new PgnEmptySyntax(parent, start);
 }
Example #3
0
 internal PgnEmptySyntax(PgnSyntax parentSyntax, int start)
 {
     ParentSyntax = parentSyntax;
     Start        = start;
 }