/// <summary> /// If <paramref name="tokenContainer"/> is a single token, then enumerates it. /// If <paramref name="tokenContainer"/> is token collection, then enumerates all contained tokens. /// If <paramref name="recurse"/> is true, then enumerates tree of collections. /// </summary> /// <param name="tokenContainer"></param> /// <param name="recurse"></param> /// <returns>enumerable of tokens</returns> public static IEnumerable <IToken> ListTokens(this IOption tokenContainer, bool recurse = true) { // Is a token if (tokenContainer is IToken token) { // Enumerable if (tokenContainer is ITokenEnumerable enumr) { // Return enumerable as is if (!recurse) { return(enumr); } // Put into queue StructList4 <IToken> queue = new StructList4 <IToken>(); foreach (IToken t in enumr) { queue.Add(t); } StructListSorter <StructList4 <IToken>, IToken> .Reverse(ref queue); StructList4 <IToken> result = new StructList4 <IToken>(); while (queue.Count > 0) { int ix = queue.Count - 1; IToken t = queue[ix]; queue.RemoveAt(ix); if (t is ITokenEnumerable enumr_) { foreach (IToken tt in enumr_) { queue.Add(tt); } } else { result.Add(t); } } return(result.ToArray()); } // Single token else { return new IToken[] { token } }; } else { // No tokens return(no_tokens); } }