'tree-sitter grammar to distinguish between identifier and implicit assignment

I'm trying to create a grammar which can distinguish between a assignment expression with a explicit assignment operator, like

T1=1

and an implicit assignment like

T1

where the variable names for the explicit assignment can have trailing numbers and the ones for implicit assignment cannot, i.e. the former should assign 1 to T1 and the latter 1 to T.

I came up with the following simple grammar:

module.exports = grammar({
    name: 'test',
    rules: {
        root: $ => repeat($.a),

        a: $ => choice($.i, $.e),

        i: $ => seq($.s, $.n),
        e: $ => seq($.sn, '=', $.n),

        s: $ => /[A-Z]+/,
        sn: $ => /[A-Z]+[0-9]*/,

        n: $ => /[0-9]+/
    }
});

This works for these test cases

T 1
T1=1
T1 = 1

but doesn't for

T1

or

T=1

This is the test file i'm working with:

====================================
works
====================================
T 1
T1=1
T1 = 1
---
(root
    (a (i (s)  (n)))
    (a (e (sn) (n)))
    (a (e (sn) (n))))
====================================
e1) doesn't work
====================================
T1
---
(root (a (i (s)  (n))))
====================================
e2) doesn't work either
====================================
T=1
---
(root (a (e (sn) (n))))
====================================
e1) results in
(root (ERROR (sn)))
and
e2) in
(root (a (i (s) (ERROR) (n))))
====================================

I tried to tinker with precedence, f.e. give $.i a higher number, but nothing helped so far. I don't think the grammar is ambiguous but maybe i just don't see it clearly?

Is it possible to express such a grammar with tree-sitter?

I also postet this on GH.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source