Skip to content

Parse error with negated variable assignments in conditional #318

@wrefactor

Description

@wrefactor

variable_assignments in a condition parse correctly, but not negated variable assignments. In both examples below, it tries to parse a negated command but fails in absence of a command_name. Adding a null command, : immediately after the variable assignments (or, less usefully, removing the negation), allows both to parse correctly.

# example found in the wild (heavily cut-down)
if ! IFS=$'\n' REPLY=$(cat response); then :; else :; fi;

# minimal example
if ! FOO='foo' BAR='bar'; then :; else :; fi;
Full parse for the examples above

Parse trees from playground for the examples above (without comments); also as seen on tree-sitter-bash 0.25.1

# if ! IFS=$'\n' REPLY=$(cat response); then :; else :; fi;
program [0, 0] - [1, 0]
  if_statement [0, 0] - [0, 56]
    condition: negated_command [0, 3] - [0, 36]
      command [0, 5] - [0, 36]
        variable_assignment [0, 5] - [0, 14]
          name: variable_name [0, 5] - [0, 8]
          value: ansi_c_string [0, 9] - [0, 14]
        variable_assignment [0, 15] - [0, 36]
          name: variable_name [0, 15] - [0, 20]
          value: command_substitution [0, 21] - [0, 36]
            command [0, 23] - [0, 35]
              name: command_name [0, 23] - [0, 26]
                word [0, 23] - [0, 26]
              argument: word [0, 27] - [0, 35]
        name: command_name [0, 36] - [0, 36]
          MISSING word [0, 36] - [0, 36]
    command [0, 43] - [0, 44]
      name: command_name [0, 43] - [0, 44]
        word [0, 43] - [0, 44]
    else_clause [0, 46] - [0, 53]
      command [0, 51] - [0, 52]
        name: command_name [0, 51] - [0, 52]
          word [0, 51] - [0, 52]

# if ! FOO='foo' BAR='bar'; then :; else :; fi;
program [0, 0] - [1, 0]
  if_statement [0, 0] - [0, 44]
    condition: negated_command [0, 3] - [0, 24]
      command [0, 5] - [0, 24]
        variable_assignment [0, 5] - [0, 14]
          name: variable_name [0, 5] - [0, 8]
          value: raw_string [0, 9] - [0, 14]
        variable_assignment [0, 15] - [0, 24]
          name: variable_name [0, 15] - [0, 18]
          value: raw_string [0, 19] - [0, 24]
        name: command_name [0, 24] - [0, 24]
          MISSING word [0, 24] - [0, 24]
    command [0, 31] - [0, 32]
      name: command_name [0, 31] - [0, 32]
        word [0, 31] - [0, 32]
    else_clause [0, 34] - [0, 41]
      command [0, 39] - [0, 40]
        name: command_name [0, 39] - [0, 40]
          word [0, 39] - [0, 40]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions