Sort-key parsing: turns one parquet_sortkey%add key ("ra asc", "-dec", "main.inner.age") into the column name plus a direction flag the C++ engine takes (see parquet_reader_set_sort in parquet_wrapper.cpp). Purely syntactic -- no schema access at all, so nothing here can tell whether a column exists or whether its type is orderable; that validation stays C++-side, where the schema and the decoded array are.
Split out of parquet_read.f90 for the same reasons parquet_read_filter is: a syntax error is reported through the same error-context helpers every other Fortran-side failure uses, the parser is unit-testable in process with no file and no reader, and the bind(C) boundary keeps carrying fixed-width packed strings rather than raw user text.
The grammar is deliberately tiny -- one key is one column and at most one direction word:
key := [ '-' ] NAME [ direction ]
direction := 'asc' | 'ascending' | 'desc' | 'descending'
A leading '-' on the name is shorthand for descending, so "-dec" and "dec desc" are the same key. Direction words are case-insensitive. Giving both forms at once ("-dec desc") is a mistake worth reporting rather than silently resolving, since the two could equally be read as agreeing or as cancelling out.