public override IMatched <Unit> Parse(ParseState state, Token[] tokens, ExpressionBuilder builder) { state.Colorize(tokens, Color.Whitespace, Color.Keyword); if (builder.ToExpression().If(out var expression, out var exception)) { var comprehensions = new List <(Symbol, Expression, IMaybe <Expression>, string)>(); if (getInnerComprehension(state).ValueOrCast <Unit>(out var tuple, out var asUnit)) { var(comparisand, source, ifExp) = tuple; var image = $"for {comparisand} := {source}"; comprehensions.Add((comparisand, source, ifExp, image)); } else { return(asUnit); } while (state.More) { var parser = new InnerComprehensionParser(builder, comprehensions); if (parser.Scan(state).If(out _, out var anyException)) { } else if (anyException.If(out exception)) { return(failedMatch <Unit>(exception)); } else { break; } } var stack = new Stack <(Symbol, Expression, IMaybe <Expression>, string)>(); foreach (var item in comprehensions) { stack.Push(item); } For forStatement; var images = new StringBuilder(); if (stack.Count > 0) { var(symbol, source, ifExp, image) = stack.Pop(); images.Append(image); var yieldStatement = new Yield(expression); var block = new Block(yieldStatement); if (ifExp.If(out var boolean)) { block = new Block(new If(boolean, block)); } forStatement = new For(symbol, source, block); } else { return(notMatched <Unit>()); } while (stack.Count > 0) { var(symbol, source, ifExp, image) = stack.Pop(); images.Append(image); var block = new Block(forStatement); if (ifExp.If(out var boolean)) { block = new Block(new If(boolean, block)); } forStatement = new For(symbol, source, block); } builder.Clear(); state.CreateReturnType(); var statements = new List <Statement> { forStatement, new Return(new Expression(new NoneSymbol()), state.GetReturnType()) }; state.RemoveReturnType(); builder.Add(new ComprehensionSymbol(new Block(statements), images.ToString())); return(Unit.Matched()); } else { return(failedMatch <Unit>(exception)); } }