Skip to content

fix: end a command at newline unless the line is continued - #53

Open
dpezto wants to merge 3 commits into
mainfrom
fix/cmd-newline-gate
Open

fix: end a command at newline unless the line is continued#53
dpezto wants to merge 3 commits into
mainfrom
fix/cmd-newline-gate

Conversation

@dpezto

@dpezto dpezto commented Jul 28, 2026

Copy link
Copy Markdown
Owner

A bare newline no longer lets a command absorb the next line as its arguments. set followed by title "foo" on the next line used to parse as one valid cmd_set; gnuplot rejects both lines independently. Commands now end at a newline, semicolon, comment, or EOF unless the line ends with a backslash.

Mechanism: every cmd_* rule gates its argument tail behind the existing zero-width same-line scanner token _gval_sep (_gval_tail where the tail can begin with a range block: plot, splot, vfill, fit, stats). When the gate declines, the command reduces to a bare node and the orphaned next line surfaces as a statement-level ERROR, matching the shape the corpus already documents for replot. The _set_multiplot/_unset_multiplot pair carries a mandatory gate so the multiplot_block GLR branch shifts the same token and keeps its dynamic-precedence tie. cmd_undefine is untouched; its token.immediate tail was already newline-bounded. The scanner's gate whitelist gains { so complex literals (print {1,2}) still bind on the same line.

A command with no arguments (set, plot) now parses as a valid empty node; rejecting it is left to downstream tooling. Remaining same-line gaps (assignment right-hand side, set for tails) are recorded in docs/deferred.md.

Numbers: parser.c +35,297 bytes (+0.14 %), STATE 11616 to 11645, LARGE_STATE_COUNT down 1, TOKEN_COUNT unchanged. Corpus 230 to 240, all green; the synthetic oracle and external validation file parse with no new ERROR or MISSING nodes, including their heavy backslash-continuation sections. keywords.json regenerates with no diff; node-types.json changes are only required-to-optional flips on command children.

Commands previously accepted their arguments across a raw newline, so
invalid input like a bare 'set' followed by 'title "foo"' on the next
line parsed as one valid statement. Gnuplot ends a command at end of
line unless the line ends with a backslash; semicolons separate
commands on one line.

Every cmd_* rule now gates its argument tail behind the zero-width
same-line token _gval_sep (or _gval_tail where the tail can start with
a range block: plot, splot, vfill, fit, stats). The gate declines at a
newline, semicolon, comment, or EOF, so the orphaned next line becomes
a statement-level ERROR; backslash continuation still works. The
_set_multiplot/_unset_multiplot pair carries a mandatory gate so the
multiplot_block GLR branch can shift the same token and keep its
dynamic-precedence tie. cmd_undefine is unchanged: its token.immediate
tail was already newline-bounded. The scanner's gate whitelist gains
'{' so a complex literal ('print {1,2}') still binds on the same line.

A bare command with no arguments ('set', 'plot') now parses as a valid
empty node; rejecting it is left to downstream tooling. Remaining gaps
(assignment right-hand side, 'set for' tails) are recorded in
docs/deferred.md.

Cost: parser.c +35,297 bytes (+0.14 %), +29 states, TOKEN_COUNT and
LARGE_STATE_COUNT flat. Corpus grows 230 to 240.
Copilot AI review requested due to automatic review settings July 28, 2026 02:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added the size/xl huge — split or scrutinize label Jul 28, 2026
@codecov

codecov Bot commented Jul 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

dpezto added 2 commits July 27, 2026 21:03
…ncat

Inside a generic option body, a word immediately followed by a dot is
string concatenation on a variable ('set print pal.".gp"'), but the
keyword tables claimed the word anyway: 'pal' matched the palette row,
and error recovery inserted a zero-width identifier to rebuild the
expression, leaving a missing node in an otherwise valid tree.

Both scanner paths now decline on an adjacent dot: the gate word-peek
emits the plain separator so the word stays a value, and scan_keywords
refuses every keyword table in generic bodies, mirroring the existing
constant-word denylist. Spaced leading-dot numbers ('at graph .5',
'rotate by .5') are unaffected because their dot is not adjacent to the
word; the eccentric adjacent form 'set size.5' still parses through the
bespoke option head, matching gnuplot's tokenizer.

The zero-width node predates the newline-gate work; it went unnoticed
because 'tree-sitter parse' prints such nodes without a MISSING label,
so grep-based oracle checks never saw it. Scanner-only change: parse
tables are untouched.
The comment justified the \w+_ prefix with 'set fit prefix', which does
not exist (probed on 6.0.4: unrecognized option). Fit parameters are
plain variables with no prefix system; the user-selectable prefix comes
from 'stats ... name' and its synonym 'prefix'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl huge — split or scrutinize

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants