Skip to content

grammar(tcl, bash): a bare \ row joins the previous command, not the next row #1808

Open

Description

@dekobon

Both the Tcl grammar (vendored, tree-sitter-tcl/) and tree-sitter-bash 0.25.1 (upstream) treat a row holding only a continuation \ as a join with the row before it. They merge two commands into one, where the interpreter runs two. Found auditing PR #1804's tests (#1445).

Tcl

puts a
\
# c

tclsh prints a. The bare row and # c join into one logical line, a comment. The grammar produces one command whose words are a, #, c:

{command} (1,1)-(3,4)
├─ {simple_word} : puts
╰─ {word_list}
   ├─ {simple_word} : a
   ├─ {simple_word} : #
   ╰─ {simple_word} : c

puts a / \ / puts b likewise parses as one puts a puts b command, although tclsh runs both and prints a and b.

Bash

echo a \
          # (empty row)
\
echo b

bash prints a and then b: the empty row ends the first command. tree-sitter-bash parses one command with words a echo b.

Effect

input metric bca interpreter's reading
Tcl puts a / \ / # c loc (sloc, ploc, cloc, blank) (3, 3, 0, 0) (3, 1, 2, 0)
Tcl puts a / \ / puts b abc.branches (calls) 1 2
Bash echo a \ / empty / \ / echo b abc.branches (calls) 1 2

Halstead happens to agree on these shapes, since the operand multiset is the same. loc's bare-row reader (#1445) is right on the row it reads, but the comment it should join is not a comment node here: it is two words of a command.

Pins

tcl_bare_continuation_rows_are_code_or_comment (src/metrics/loc.rs) pins the Tcl loc row with FIXME(#this).

Fix

A grammar change in both cases. For Tcl it is the vendored grammar, regenerated per AGENTS.md "Tree-sitter grammars". For Bash it is an upstream report. Patching around it in a metric would mean re-deriving command boundaries from bytes.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions