/// <summary> /// Scans the current parse engine for a matrix expression. /// </summary> /// <param name="engine">The parse engine to use.</param> /// <returns>The found expression or NULL.</returns> public override Expression Scan(ParseEngine engine) { var column = engine.CurrentColumn; var line = engine.CurrentLine; var chars = engine.Characters; var start = engine.Pointer; if (chars[start] == '[') { engine.Advance(); var terminated = false; var statement = new Statement(); var ws = false; var nl = false; while (engine.Pointer < chars.Length && engine.IsParsing) { if (ParseEngine.IsWhiteSpace(chars[engine.Pointer])) { ws = true; engine.Advance(); } else if (ParseEngine.IsNewLine(chars[engine.Pointer])) { nl = true; engine.Advance(); } else if (chars[engine.Pointer] == ']') { terminated = true; engine.Advance(); break; } else if (chars[engine.Pointer] == ',') { ws = false; nl = false; statement.Push(engine, new ColumnOperator(engine)); engine.Advance(); } else if (chars[engine.Pointer] == ';') { ws = false; nl = false; statement.Push(engine, new RowOperator(engine)); engine.Advance(); } else if (engine.Pointer < chars.Length - 1 && ParseEngine.IsComment(chars[engine.Pointer], chars[engine.Pointer + 1])) { if (ParseEngine.IsLineComment(chars[engine.Pointer], chars[engine.Pointer + 1])) { engine.AdvanceToNextLine(); } else { engine.AdvanceTo("*/"); } } else { engine.ParseBlock(statement, nl ? (Operator) new RowOperator(engine) : (ws ? new ColumnOperator(engine) : null)); ws = false; nl = false; } } if (!terminated) { var err = new YAMPMatrixNotClosedError(line, column); engine.AddError(err); } var container = statement.Finalize(engine).Container; return(new MatrixExpression(line, column, engine.Pointer - start, engine.Query, container ?? new ContainerExpression())); } return(null); }