|
AWK Minifier
Conservative AWK source minification
|
Accepted
AWK Minifier v0.1.0 deliberately preserved physical newlines. That choice made the first implementation conservative, but it also left a large amount of structural whitespace in otherwise minified output. Minifying the project's own development artifact demonstrates the gap clearly: comments and horizontal whitespace shrink, while hundreds of physical newlines remain.
AWK newlines cannot safely be deleted as ordinary whitespace. The AWK grammar uses NEWLINE both as a statement or rule terminator and in grammar positions where a newline is optional. A blind rewrite can therefore change control flow, merge rules, create an empty loop body, or otherwise produce different valid source.
The POSIX AWK grammar provides enough structure to make the distinction explicit. Statements and top-level items can use newline or semicolon terminators. Newlines are optional in specific grammatical contexts, including after an opening brace, a comma, logical && or ||, do, else, and the closing parenthesis of an if, for, or ordinary while header. Function definitions permit optional newlines between the parameter-list closing parenthesis and the action. Nested actions are themselves terminated statements.
Backslash-newline continuation between source tokens can be removed without creating a statement boundary. Portability testing found a narrower boundary inside literals: GNU/Linux AWKs and the macOS system AWK do not provide uniform observable behavior for backslash-newline embedded in string or regexp literal source. The portable contract therefore rejects that construct instead of normalizing it according to one implementation.
do ... while requires additional context. The closing parenthesis of an ordinary while header can be followed by an optional newline before its body, while the closing parenthesis of the trailing while in a do ... while statement completes the statement and therefore requires a terminator before a following sibling statement. Treating those cases alike would change meaning.
AWK Minifier SHALL classify physical newlines as part of lexical/contextual transformation.
For successful portable-AWK input, transformed output SHALL contain no physical newlines except the newline immediately following a preserved first-line shebang. Consequently:
This physical-line invariant describes transformed program source. It does not require build-owned release metadata to be passed through the current candidate transformer; ADR-022 continues to govern production .min.awk construction.
The transformer SHALL handle source newlines according to these classes:
#! shebang SHALL be preserved so the following program does not become part of the interpreter directive.newline_opt position SHALL be discarded. A single ASCII space MAY be emitted when removing the newline is necessary to keep adjacent keyword/token text lexically separate, notably after do or else.; rather than by a physical newline.Leading horizontal indentation on a new physical source line SHALL remain removable indentation. Collapsing the entire program onto one output line MUST NOT accidentally turn source indentation into new separator spaces after every inserted semicolon.
The recognizer SHALL maintain enough explicit context to distinguish at least:
if, for, and ordinary while headers;do statements and the brace depth at which their body begins; andwhile statement from the trailing while belonging to a pending do statement.A nested action closing brace is already a terminated statement and therefore does not require an inserted semicolon before a following statement, else, or do ... while trailer. A top-level rule still requires item separation; a function definition may use its grammar-defined optional newline after the closing brace.
The transformer SHALL continue to use contextual slash recognition and buffered publication from ADR-018. Newline handling MUST NOT replace those mechanisms with raw regular-expression substitutions over source lines.
Candidate self-minification remains test-only under ADR-019 and ADR-022. Tests MAY run the current modular transformer over the current development artifact to prove that the maintained source collapses to the shebang plus a single program line. That evidence MUST NOT replace the pinned previous-release transformer used for production .min.awk provenance.
while headers and do ... while trailers are distinguished.Rejected. The first implementation established semantic safety, but preserving all line boundaries leaves a large and unnecessary portion of source formatting in a product whose purpose is minification.
Rejected because NEWLINE is a real AWK grammar token. Deleting a statement or rule terminator can merge constructs or change control flow.
Rejected because grammar-optional newlines after control headers, do, else, commas, and other continuation contexts are not statement terminators. Inserting a semicolon after if (condition) or an ordinary while (condition), for example, can create an empty body and change the program while remaining syntactically plausible.
Rejected after portability testing showed different observable behavior across the supported AWK implementations. Choosing the GNU/Linux interpretation would make successful transformation depend on implementation-specific source semantics. Failing closed provides a stable portable contract and preserves the buffered no-partial-success property.
Rejected as unnecessarily conservative. The POSIX grammar identifies where newlines are optional, and small explicit context stacks can distinguish the important cases without retaining hundreds of line breaks.
Rejected for the current scope. A full parser could classify every grammatical boundary, but it would substantially expand the implementation and audit surface. The selected recognizer records only the structural context necessary for the newline decision while retaining conservative behavior elsewhere.
Rejected by ADR-019 and ADR-022. Candidate self-minification is useful behavioral evidence, not production release provenance.
The lexer gains explicit parenthesis, brace, function-header, and do ... while state. The output layer preserves a physical newline only for a shebang boundary; ordinary source-line boundaries become either nothing or semicolons.
Tests must cover exact physical-line counts, statement separation, top-level rule separation, control headers on the preceding line, nested conditionals, ordinary while, for, simple and braced do ... while, function-definition line breaks, explicit backslash continuation between tokens, rejection of backslash-newline inside string and regexp literals, comments around optional newlines, semantic equivalence, idempotence, and candidate self-minification.
This change deliberately improves the runtime transformer before the production build transformer is advanced. A release containing this behavior can therefore become a future previous-release trust anchor without weakening ADR-022's build lineage.
This ADR refines ADR-018's conservative whitespace/newline treatment. ADR-018's portable-AWK runtime, contextual recognition, semantic-preservation priority, and buffered-output requirements remain governing.
This ADR does not supersede ADR-019 or ADR-022. Those decisions continue to govern how a released .min.awk artifact is produced and which released transformer may participate in that production path.