/// <summary> /// More custom parsing of a statement (ends with a custom termination char). /// </summary> /// <param name="termination">The custom termination character (e.g. ; for the standard case).</param> /// <param name="terminationMissing">Function (to generate an error) that is called if the termination character is not found.</param> /// <param name="handleCharacter">An optional function that is invoked for every character.</param> /// <returns>The finalized statement.</returns> internal Statement ParseStatement(char termination, Func <ParseEngine, YAMPParseError> terminationMissing = null, Func <char, Statement, bool> handleCharacter = null) { var terminated = false; var statement = new Statement(); while (parsing && ptr < characters.Length) { if (handleCharacter != null && handleCharacter(characters[ptr], statement)) { continue; } if (IsWhiteSpace(characters[ptr])) { ptr++; currentColumn++; } else if (IsNewLine(characters[ptr])) { ptr++; currentColumn = 1; currentLine++; } else if (characters[ptr] == termination) { terminated = true; currentColumn++; ptr++; break; } else if (ptr < characters.Length - 1 && IsComment(characters[ptr], characters[ptr + 1])) { if (IsLineComment(characters[ptr], characters[ptr + 1])) { AdvanceToNextLine(); } else { AdvanceTo("*/"); } } else { ParseBlock(statement); } } if (!terminated) { AddError(terminationMissing != null ? terminationMissing(this) : new YAMPTerminatorMissingError(currentLine, currentColumn, termination)); } return(statement.Finalize(this)); }
/// <summary> /// More custom parsing of a statement (ends with a custom termination char). /// </summary> /// <param name="termination">The custom termination character (e.g. ; for the standard case).</param> /// <param name="terminationMissing">Function (to generate an error) that is called if the termination character is not found.</param> /// <param name="handleCharacter">An optional function that is invoked for every character.</param> /// <returns>The finalized statement.</returns> internal Statement ParseStatement(Char termination, Func <ParseEngine, YAMPParseError> terminationMissing = null, Func <Char, Statement, Boolean> handleCharacter = null) { var terminated = false; var statement = new Statement(); while (_parsing && _ptr < _characters.Length) { if (handleCharacter == null || !handleCharacter(_characters[_ptr], statement)) { if (IsWhiteSpace(_characters[_ptr])) { _ptr++; _currentColumn++; } else if (IsNewLine(_characters[_ptr])) { _ptr++; _currentColumn = 1; _currentLine++; } else if (_characters[_ptr] == termination) { terminated = true; _currentColumn++; _ptr++; break; } else if (_ptr < _characters.Length - 1 && IsComment(_characters[_ptr], _characters[_ptr + 1])) { if (IsLineComment(_characters[_ptr], _characters[_ptr + 1])) { AdvanceToNextLine(); } else { AdvanceTo("*/"); } } else { ParseBlock(statement); } } } if (!terminated) { AddError(terminationMissing != null ? terminationMissing(this) : new YAMPTerminatorMissingError(_currentLine, _currentColumn, termination)); } return(statement.Finalize(this)); }
/// <summary> /// Standard parsing of a statement (ends with ; or }). /// </summary> /// <returns>The finalized statment.</returns> internal Statement ParseStatement() { var statement = new Statement(); while (parsing && ptr < characters.Length) { if (IsWhiteSpace(characters[ptr])) { ptr++; currentColumn++; } else if (IsNewLine(characters[ptr])) { ptr++; currentColumn = 1; currentLine++; } else if (characters[ptr] == ';') { statement.IsMuted = true; currentColumn++; ptr++; break; } else if (characters[ptr] == '}') { terminated = true; parsing = false; ptr++; currentColumn++; break; } else if (ptr < characters.Length - 1 && IsComment(characters[ptr], characters[ptr + 1])) { if (IsLineComment(characters[ptr], characters[ptr + 1])) { AdvanceToNextLine(); } else { AdvanceTo("*/"); } } else if (ParseBlock(statement).IsFinished) { break; } } return(statement.Finalize(this)); }
/// <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(); bool ws = false, 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); }