Skip to content

Error when ternary operator is used in substring expansion (offset or length) #317

@wrefactor

Description

@wrefactor

This is an awkward one to parse, yet unfortunately a common idiom. An example seen in the wild, and two minimal reproducible examples:

# seen in the wild; parses with MISSING '}' after first '}'
address=${address: ${#address} < 8 ? 0 : -8} # Limit to 32-bit

# minimal example 1: parses with ERROR; bash evaluates as ${FOO:0:2}
echo ${FOO: 0 : 1 ? 2 : 3}

# minimal example 2: parses with ERROR; bash evaluates as ${FOO:2:4}
echo ${FOO: 1 ? 2 : 3 : 4}    

All parse correctly with parentheses around the ternary expression.

Full parse trees

Parse trees for each example (without comments) from the playground, but found using tree-sitter-bash 0.25.1.

# playground parse tree for "address=${address: ${#address} < 8 ? 0 : -8}"
program [0, 0] - [1, 0]
  command [0, 0] - [0, 44]
    variable_assignment [0, 0] - [0, 30]
      name: variable_name [0, 0] - [0, 7]
      value: expansion [0, 8] - [0, 30]
        variable_name [0, 10] - [0, 17]
        expansion [0, 19] - [0, 30]
          variable_name [0, 22] - [0, 29]
        MISSING "}" [0, 30] - [0, 30]
    redirect: file_redirect [0, 31] - [0, 34]
      destination: number [0, 33] - [0, 34]
    name: command_name [0, 35] - [0, 36]
      word [0, 35] - [0, 36]
    argument: number [0, 37] - [0, 38]
    argument: word [0, 39] - [0, 40]
    argument: concatenation [0, 41] - [0, 44]
      number [0, 41] - [0, 43]
      word [0, 43] - [0, 44]

# playground parse tree for "echo ${FOO: 0 : 1 ? 2 : 3}"
program [0, 0] - [1, 0]
  command [0, 0] - [0, 26]
    name: command_name [0, 0] - [0, 4]
      word [0, 0] - [0, 4]
    argument: expansion [0, 5] - [0, 26]
      variable_name [0, 7] - [0, 10]
      number [0, 12] - [0, 13]
      ERROR [0, 14] - [0, 21]
        number [0, 16] - [0, 17]
        word [0, 20] - [0, 21]
      number [0, 24] - [0, 25]

# playground parse tree for "echo ${FOO: 1 ? 2 : 3 : 4}"
program [0, 0] - [1, 0]
  command [0, 0] - [0, 26]
    name: command_name [0, 0] - [0, 4]
      word [0, 0] - [0, 4]
    ERROR [0, 5] - [0, 15]
      variable_name [0, 7] - [0, 10]
      number [0, 12] - [0, 13]
    argument: number [0, 16] - [0, 17]
    argument: word [0, 18] - [0, 19]
    argument: number [0, 20] - [0, 21]
    argument: word [0, 22] - [0, 23]
    argument: concatenation [0, 24] - [0, 26]
      number [0, 24] - [0, 25]
      word [0, 25] - [0, 26]

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