Since string_view uses char* for representation, there is no longer a
need to copy into a local char array for most code paths (only when the
input must be modified due to fortran float formatting).
By representing string_view as char* instead of
std::string::const_iterator the string_view class bring possibly
slightly lower overhead, but mostly enables some optimisations.
Perform a pre-pass over the input and remove everything that isn't
interesting. Preserves empty lines to provide accurate line number for
diagnostics/error output.
The use of string_view for keys allows comparison with keywords from the
file buffers to be compared directly, instead of having to go via
std::string. This removes the need for a series of (inherently)
unecessary copies.
Several inner parser functions modified to use string_view, to reduce
unecessary copying (and indirectly allocationg) related to passing
strings around.
Replaces the parser's dependence on streams with string_view, which
won't copy to its internal buffers. Involves hand-rolling std::getline
for string_view to preserve stream-like behaviour.
Replaces the external stream-support by reading the entire contents of
input files at once, rather than lazily through streams. Uses
stringstreams internally, but keeps the entire file in memory through
std::string
openString/File has been renamed to loadString/File
When considering if a keyword is valid, the parser procedures convert
the same string to uppercase twice, with copies. This behaviour has been
changed, and ParserKeyword now assumes it will be given a
correctly-formatted keyword to look up.
Rewrites ParseState to use an explicit stack of open file streams
instead of spawning multiple ParseState objects. While recursion is
*the* most elegant to solve a typical include-file system, the global
nature of eclipse declarations make this clumsy (at best). Instead,
maintain an explicit stack of open files and logically parse the input
as if it was all concatenated into one large file.
Also adds some convenient ways of accessing the current (and
interesting) top of the stack.
Restructures createRawKeyword to use multiple return statements over
if-else and updating variables, reducing indentation to have fewer
contemporary branches.
Changes the control flow of Parser::createRawKeyword to return on
failing to meet preconditions, rather than if-else block. Reduces
indentation and concurrent code paths.
Makes the actual effects of the various condtions more clear by
emphasising the return of the function rather than some possible action
after the loop.
Restructures the per-iteration check of whether or not to continue
parsing to happen first and be an early-break, instead of this flow
being handled by if-else.
The implementation has been rewritten to use iterators and renamed for
internal use. The public static function still exists for testability
and easy verification, but should be considered an internal part of the
parser.