2

I have a grammar like this:

terminator = '\n';

module.exports = grammar({
  name: 'sciname',

  rules: {
    source_file: ($) => repeat($._sci_name),

    _sci_name: ($) => seq($.uninomial, optional($.tail), terminator),

    _uninomial: ($) => /[A-Z][a-z]+/,

    uninomial: ($) => choice($._uninomial, seq($.genus, $.subgenus)),

    genus: ($) => $._uninomial,

    subgenus: ($) => seq('(', $._uninomial, ')'),

    tail: ($) => /.+/,
  },
});

tail rule suppose to catch anything that comes after uninomial. However I have trouble with this test:

=====================
Subgenus
=====================

Bubo (Bubo)

---------------------

(source_file (uninomial (genus) (subgenus)))

producing:

(source_file (uninomial) (tail))

instead of

(source_file (uninomial (genus) (subgenus)))

Changing precedence does not seem to influence this behavior. Is there a way to make a "catch-all" rule like tail to engage only if all other previous rules failed?

dimus
  • 8,712
  • 10
  • 45
  • 56

1 Answers1

1

According to https://github.com/tree-sitter/tree-sitter/discussions/1407

ahlinc writes:

Try to assign a lower lexer precedence to your tail with a token(prec(-1, ...)) construct like:

tail: ($) => token(prec(-1, /[^\s]+/)),
dimus
  • 8,712
  • 10
  • 45
  • 56