/// <summary>Parses a sequence of Kaleidoscope source text into AST nodes</summary>
 /// <param name="source">source sequence of expressions</param>
 /// <param name="parser">Kaleidoscope parser stack to parse the input</param>
 /// <param name="errorHandler">Handler for AST Generation errors</param>
 /// <returns>Observable sequence of AST nodes</returns>
 /// <remarks>
 /// This explicitly swallows <see cref="CodeGeneratorException"/> that occur during parse by
 /// calling the <paramref name="errorHandler"/> to report the error and
 /// producing nothing. This allows for a more robust sequence as user input errors are
 /// expected to occur and shouldn't stop the complete sequence.
 /// </remarks>
 public static IObservable <IAstNode> ParseWith(this IObservable <string> source
                                                , IKaleidoscopeParser parser
                                                , Action <CodeGeneratorException> errorHandler
                                                )
 {
     return(from expression in source
            let node = ParseAndReportErrors(expression, parser, errorHandler)
                       where node != null
                       select node);
 }
 private static IAstNode ParseAndReportErrors(string expression
                                              , IKaleidoscopeParser parser
                                              , Action <CodeGeneratorException> codeGeneratorExceptionHandler
                                              )
 {
     try
     {
         return(parser.Parse(expression));
     }
     catch (CodeGeneratorException ex)
     {
         codeGeneratorExceptionHandler(ex);
         return(null);
     }
 }