0

I am writing a Tree-Sitter grammar, I want to include escape sequences as child nodes within string literals, but I also want to avoid matching comments as extras within string literals.

The input "https://example.com" is not parsed correctly because of the //.

extras: $ => [$.comment],
rules: [
    comment: $ => choice(
      seq('//', /[^\n]*\n?/),
      seq('/*', /([^\*]|\*[^\/])*/, '*/'),
    ),
    escape: $ => /\\./,

    // This one detects escape sequences, but fails on `//`
    string: $ => seq('"', repeat(choice(/[^\"\\]/, $.escape)), '"'),

    // This one doesn't detect escape sequences, but does not fail on `//`
    string: $ => /"([^\"\\]|\\.)*"/,
],

I tried the token.immediate modifier, but I did not manage to make it work (I don't really understand how is it supposed to be used). In the following example, the calls to token.immediate have no effect.

string: $ => seq('"', optional($._string_tail), token.immediate('"')),
_string_tail: $ => seq(
    choice(
        token.immediate(/[^\"\\]/),
        alias(token.immediate(/\\./), $.escape)
    ),
    optional($._string_tail)
),

I also tried to put a lower precedence on comment rule, but it has no effect.

uben
  • 1,221
  • 2
  • 11
  • 20

0 Answers0