tree-sitter-grammars / tree-sitter-hcl

HCL grammar for tree-sitter
https://tree-sitter-grammars.github.io/tree-sitter-hcl/
Apache License 2.0
95 stars 20 forks source link

block parsing fails when block string_lit is empty string #20

Closed reegnz closed 2 years ago

reegnz commented 2 years ago

Describe the bug The parser fails to parse consul global-management policy that is used by consul when bootstrapping.

❯ tree-sitter parse admin.hcl
(config_file [0, 0] - [36, 0]
  (body [0, 0] - [0, 13]
    (attribute [0, 0] - [0, 13]
      (identifier [0, 0] - [0, 3])
      (expression [0, 6] - [0, 13]
        (literal_value [0, 6] - [0, 13]
          (string_lit [0, 6] - [0, 13]
            (quoted_template_start [0, 6] - [0, 7])
            (template_literal [0, 7] - [0, 12])
            (quoted_template_end [0, 12] - [0, 13]))))))
  (ERROR [2, 0] - [35, 1]
    (identifier [2, 0] - [2, 12])
    (string_lit [2, 13] - [3, 11]
      (quoted_template_start [2, 13] - [2, 14])
      (template_literal [2, 14] - [3, 9])
      (quoted_template_end [3, 10] - [3, 11]))
    (identifier [3, 11] - [3, 16])
    (string_lit [3, 16] - [6, 14]
      (quoted_template_start [3, 16] - [3, 17])
      (template_literal [4, 0] - [6, 12])
      (quoted_template_end [6, 13] - [6, 14]))
    (string_lit [6, 14] - [7, 11]
      (quoted_template_start [6, 14] - [6, 15])
      (template_literal [6, 16] - [7, 9])
      (quoted_template_end [7, 10] - [7, 11]))
    (identifier [7, 11] - [7, 16])
    (string_lit [7, 16] - [10, 12]
      (quoted_template_start [7, 16] - [7, 17])
      (template_literal [8, 0] - [10, 10])
      (quoted_template_end [10, 11] - [10, 12]))
    (string_lit [10, 12] - [11, 11]
      (quoted_template_start [10, 12] - [10, 13])
      (template_literal [10, 14] - [11, 9])
      (quoted_template_end [11, 10] - [11, 11]))
    (identifier [11, 11] - [11, 16])
    (string_lit [11, 16] - [14, 11]
      (quoted_template_start [11, 16] - [11, 17])
      (template_literal [12, 0] - [14, 9])
      (quoted_template_end [14, 10] - [14, 11]))
    (identifier [14, 11] - [14, 16])
    (string_lit [14, 16] - [16, 13]
      (quoted_template_start [14, 16] - [14, 17])
      (template_literal [16, 0] - [16, 11])
      (quoted_template_end [16, 12] - [16, 13]))
    (string_lit [16, 13] - [17, 11]
      (quoted_template_start [16, 13] - [16, 14])
      (template_literal [16, 15] - [17, 9])
      (quoted_template_end [17, 10] - [17, 11]))
    (identifier [17, 11] - [17, 16])
    (string_lit [17, 16] - [20, 12]
      (quoted_template_start [17, 16] - [17, 17])
      (template_literal [18, 0] - [20, 10])
      (quoted_template_end [20, 11] - [20, 12]))
    (identifier [20, 12] - [20, 17])
    (string_lit [20, 17] - [22, 8]
      (quoted_template_start [20, 17] - [20, 18])
      (template_literal [22, 0] - [22, 6])
      (quoted_template_end [22, 7] - [22, 8]))
    (identifier [22, 8] - [22, 13])
    (string_lit [22, 13] - [24, 14]
      (quoted_template_start [22, 13] - [22, 14])
      (template_literal [24, 0] - [24, 12])
      (quoted_template_end [24, 13] - [24, 14]))
    (string_lit [24, 14] - [25, 11]
      (quoted_template_start [24, 14] - [24, 15])
      (template_literal [24, 16] - [25, 9])
      (quoted_template_end [25, 10] - [25, 11]))
    (identifier [25, 11] - [25, 16])
    (string_lit [25, 16] - [28, 16]
      (quoted_template_start [25, 16] - [25, 17])
      (template_literal [26, 0] - [28, 14])
      (quoted_template_end [28, 15] - [28, 16]))
    (string_lit [28, 16] - [29, 11]
      (quoted_template_start [28, 16] - [28, 17])
      (template_literal [28, 18] - [29, 9])
      (quoted_template_end [29, 10] - [29, 11]))
    (identifier [29, 11] - [29, 16])
    (string_lit [29, 16] - [30, 15]
      (quoted_template_start [29, 16] - [29, 17])
      (template_literal [30, 1] - [30, 13])
      (quoted_template_end [30, 14] - [30, 15]))
    (identifier [30, 15] - [30, 20])
    (string_lit [30, 20] - [33, 16]
      (quoted_template_start [30, 20] - [30, 21])
      (template_literal [31, 0] - [33, 14])
      (quoted_template_end [33, 15] - [33, 16]))
    (string_lit [33, 16] - [34, 11]
      (quoted_template_start [33, 16] - [33, 17])
      (template_literal [33, 18] - [34, 9])
      (quoted_template_end [34, 10] - [34, 11]))
    (identifier [34, 11] - [34, 16])
    (quoted_template_start [34, 16] - [34, 17])))
admin.hcl   0 ms    (ERROR [2, 0] - [35, 1])

To Reproduce Steps to reproduce the behavior:

Put this into admin.hcl:

acl = "write"
agent_prefix "" {
    policy = "write"
}
event_prefix "" {
    policy = "write"
}
key_prefix "" {
    policy = "write"
}
keyring = "write"
node_prefix "" {
    policy = "write"
}
operator = "write"
mesh = "write"
query_prefix "" {
    policy = "write"
}
service_prefix "" {
    policy = "write"
    intentions = "write"
}
session_prefix "" {
    policy = "write"
}

And run

tree-sitter parse admin.hcl

Expected behavior The parser parses the provided hcl file without ERROR.

Additional context The hcl above is the global-management policy for consul, which is the default policy to bootstrap consul. One might want to write a similar policy that references empty prefixes, but the tree-sitter parser fails to parse it correctly.

I'm using the parser together with nvim-treesitter and nvim-tree-sitter-textobjects to get syntax highlighting and improved hcl editing in nvim.

reegnz commented 2 years ago

I think the issue might be with https://github.com/MichaHoffmann/tree-sitter-hcl/blob/main/grammar.js#L296, but I don't know how to fix that in the https://github.com/MichaHoffmann/tree-sitter-hcl/blob/main/src/scanner.cc code.

reegnz commented 2 years ago

Or maybe just wrapping the template_literal with an optional would also be fine.

MichaHoffmann commented 2 years ago

Hey @reegnz,

Thanks for reporting, ill have a look!

MichaHoffmann commented 2 years ago

The problem is the empty identifier, template literals can be empty ( wrote a test just now )

MichaHoffmann commented 2 years ago

mhh, according to the spec it would seem that this is invalid hcl if im not reading it wrong https://github.com/hashicorp/hcl/blob/main/hclsyntax/spec.md#identifiers

MichaHoffmann commented 2 years ago

ahh, my bad, you were right, string literals demand some content right now, ill prepare a fix

MichaHoffmann commented 2 years ago

empty templates were ok all along, but not empty string literals and block annotations do not allow templates, thats why it failed i think

MichaHoffmann commented 2 years ago

I merged, nvim-treesitter should be updated automatically by a github action, if the issue persists please feel free to reopen!

Thanks for reporting, good find!

reegnz commented 2 years ago

Thanks!