alemuller / tree-sitter-make

MIT License
44 stars 16 forks source link

Errors parsing $(call ...) with string arguments that include spaces #8

Open guy4261 opened 2 years ago

guy4261 commented 2 years ago

Consider the Makefile docs $(call variable,param,param,…) should be legitimate, right?

If your Makefile looks like this:

# Makefile
define logger
    echo $1
endef

a:
    $(call logger, '(string_param_with_parentheses)')
    $(call logger, '(spaces are OK)')
    $(call logger, "(double quotes are fine)")

Then running make will work fine:

$ make
echo  '(string_param_with_parentheses)'
(string_param_with_parentheses)
echo  '(spaces are OK)'
(spaces are OK)
echo  "(double quotes are fine)"
(double quotes are fine)

However, parsing it will get you an error:

repro = b"""
define logger
    echo $1
endef

a:
    $(call logger, '(string_param_with_parentheses)')
    $(call logger, '(spaces are OK)')
    $(call logger, "(double quotes are fine)")
"""

parsed = parser.parse(repro).walk().node.children
print(parsed[1].children[-1].children[0].children[0].children[0].children[2])
print(parsed[1].children[-1].children[1].children[0].children[0].children[2])
print(parsed[1].children[-1].children[2].children[0].children[0].children[2])

The printout indicates parsing errors:

<Node kind=ERROR, start_point=(6, 3), end_point=(6, 18)>
<Node kind=ERROR, start_point=(7, 3), end_point=(7, 18)>
<Node kind=ERROR, start_point=(8, 3), end_point=(8, 18)>
alemuller commented 2 years ago

This works with the grammar on the master branch. The parsing of arguments was one of the reasons I made the rewrite.

Freed-Wu commented 1 year ago

And, even if param doesn't contain space, the arguments isn't be split:

all:
    $(call f,test)
>>> tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2]
<Node type=arguments, start_point=(1, 8), end_point=(1, 14)>
>>> tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2].children
[<Node type=text, start_point=(1, 8), end_point=(1, 14)>]
>>> tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2].children[0]
<Node type=text, start_point=(1, 8), end_point=(1, 14)>
>>> tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2].children[0].text
f,test
>>> tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2].children[0].children
[]

However, tree.root_node.children[0].children[2].children[0].children[0].children[0].children[-2].children[0].children should be a list containing three elements: f, ,, test