Skip to content

Punctuation-separated variable expansions mis-parsed as concatenation with "$" #315

Open

Description

@wrefactor

The expansion of non-braced variable names is incorrectly parsed when separated by punctuation. I think this is a minimal example... Bash will expand the following to foo/bar/ if FOO=foo and BAR=bar:

$FOO/$BAR/

but instead of two variable expansions, the term is parsed as (informally):

command(command_name("$FOO/$"), argument: word("BAR/"))
Details, version info, full parse tree

  • The tree below is from the playground, with anonymous nodes enabled to illustrate
  • Found using tree-sitter-bash 0.25.1; tree-sitter 0.25.2.
  • Equivalent parses are obtained in more realistic contexts, e.g. echo $FOO/$BAR/ and $FOO/$BAR/executable
  • The same occurs if the / characters are swapped for different (combinations of) punctuation, as long as they don't create a different statement type. E.g. the same parse is obtained with {., ?, -, :}, but not with characters that parse a list, redirected_statement, pipeline, etc, such as {&, >, ;}.
# playground parse tree for string "$FOO/$BAR/"
program [0, 0] - [1, 0]
  command [0, 0] - [0, 10]
    name: command_name [0, 0] - [0, 6]
      concatenation [0, 0] - [0, 6]
        simple_expansion [0, 0] - [0, 4]
          $ [0, 0] - [0, 1]
          variable_name [0, 1] - [0, 4]
        word [0, 4] - [0, 5]
        $ [0, 5] - [0, 6]
    argument: word [0, 6] - [0, 10]

The correct parse is obtained if:

  • the term is double-quoted, "$FOO/$BAR/"; or
  • the second variable is braced, $FOO/${BAR}/; or
  • either / is deleted, $FOO$BAR/, $FOO/$BAR, $FOO$BAR; or
  • either / is replaced with whitespace $FOO $BAR/, $FOO/$BAR , $FOO $BAR
Expected tree, obtained by deleting trailing `/`

# playground parse tree for string "$FOO/BAR"
program [0, 0] - [1, 0]
  command [0, 0] - [0, 9]
    name: command_name [0, 0] - [0, 9]
      concatenation [0, 0] - [0, 9]
        simple_expansion [0, 0] - [0, 4]
          $ [0, 0] - [0, 1]
          variable_name [0, 1] - [0, 4]
        word [0, 4] - [0, 5]
        simple_expansion [0, 5] - [0, 9]
          $ [0, 5] - [0, 6]
          variable_name [0, 6] - [0, 9]

I hope this is helpful; thank you for tree-sitter-bash :-)

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions