The simplest method is to assume that the SQL script was written in a reasonably readable manner and that there is either 1 statement-per-line or that statements are split over multiple lines and you will not have the case where there are multiple statements on a single line.
The majority of cases can be handled by:
Read the next line and trim any leading white-space:
- If it starts with
SET or COLUMN then you have a SQL/Plus directive which will (typically) consist of a single line; that line is your statement.
- If it starts with
CREATE FUNCTION, CREATE PROCEDURE, CREATE PACKAGE, DECLARE or BEGIN (and a following white-space character) then you will have a PL/SQL block that will be terminated with a / on a separate line and you can read lines until you have found it and that is your complete statement.
- If it starts with
-- then it is a comment and you can skip the rest of the line and prepend it to the next statement (since comments are part of the next statement).
- If it starts with
/* then it is an inline comment and you can read until the next */ and then repeat by processing the rest of the line (the comment will be prepended to the next statement).
- Otherwise, read until the next
; that is at the end of a line (or followed by a comment) (or / on a separate line) and that is your complete statement.
Then repeat, reading the next line.
This is not guaranteed to work on 100% of cases (i.e. if you have multi-line string literals which happen to have a ; at then end of a line within the literal). You should review the output to see if there are any additional cases that need to be handled but for relatively simple scripts it should work.
If you have developers that like writing (less readable) scripts with multiple statements on the same line then you may need to implement a parser.
set echo off, or variable substitution using&), they won't translate to anything else.