Hi, I am extremely new to Lezer and language parsing in general, so excuse me if this question was asked before, but my limited knowledge makes it hard to find similar problems to mine So please point me to a thread that answered this question before if it exists.
I want to add interpolation to JSON. That means I want to add to the current grammar a term to match sequences of the kind ${something}.
Now since JSON is a fairly simple language, I managed to do it for the case:
But as you might have guessed I received the following error: Overlapping tokens string and Interpolation used in same context (example: "\"${}\"")
The error makes sense and I understand why I get it, but I don’t know how to solve it.
The final thing I want to match is sth. like "${env1} some text ${env2}" but differentiating between “some string” and “${env}” would be good a good start.
I think this shows the way towards the solution. Make the string rule use multiple tokens (one for the opening quote, followed by any number of string content or interpolation start tokens, closed by another quote), and allow both content tokens and interpolations inside of it.
char* will greedily match as much as possible. I would expect you’ll want to put the ${ token in the @local tokens block, and keep the interpolation rule as a whole outside of it, and not make it a single token, so you can do normal tokenizing of its content.
As you can see now the closing bracket is not matched correctly anymore and I can’t seem to fix it. Do you have an idea where this could come from? here is the current grammar:
Do you mean matched as in matchBrackets or as in highlighted? The former should work with the openedBy/closedBy attributes. The highlighting should just be a matter of assigning the correct highlighting tags (which you don’t show in your post).
As you can see there is still a bug where it does not match the closing brace with the opening brace of the interpolation. To still make it work I had to change the regular JSON braces to a different token, so that I can highlight all “}” the same way I highlight the interpolation content. TBH this is really confusing to me as I basically ended up copying the JavaScript template literals.
I will leave the final grammar here as a reference anyway as some might benefit from it:
The brackets not lighting up from one side is because Lezer turns the } into InterpolationEnd { "}" }, and it will look at the inner }, not the InterpolationEnd to see what should be highlighted.
You can fix this by removing } from the tokens list: