tree-sitter-goal
Version:
Goal grammar for tree-sitter
45 lines (44 loc) • 2.07 kB
JavaScript
const delimited = s => choice(...['/', '#', '`', '"', "'", '%'].map(d => seq(s, token.immediate(d), new RegExp(`[^${d}]*`), d)))
module.exports = grammar({
name: 'goal',
supertypes: $ => [$.atom, $.N, $.t, $.e],
conflicts: $ => [[$.n, $.strand], [$.strand], [$.e, $.te], [$.atom, $.args]],
extras: $ => [/[\t ]+/, $.inline_comment, $.block_comment],
rules: {
S: $ => optional($.E),
E: $ => repeat1(choice($.e, $.line_comment, token('\n'), token(';'))),
e: $ => choice($.nve, $.te, $.block, $.t),
nve: $ => prec.right(seq($.n, $.v, optional($.e))),
te: $ => prec.right(seq($.t, $.e)),
t: $ => prec.right(choice($.n, $.v)),
v: $ => prec.left(choice($.V, $.a, $.A)),
n: $ => choice($.apply, $.strand, $.N),
N: $ => choice($.atom, $.group, $.lambda),
V: _ => /::|[:+\-*%!&|<>=~,^#_$?@.]/,
A: _ => token(choice('/', '\\', "'", ',')),
a: $ => seq($.v, token.immediate(choice('/', '\\', "'"))),
atom: $ => choice($.nil, $.infinity, $.binairy, $.int, $.number, $.hex, $.exponential, $.duration, $.name, $.string, $.qq, $.rq, $.rx),
strand: $ => seq($.N, repeat1($.N)),
block: $ => seq('[', optional($.E), ']'),
apply: $ => seq($.t, token.immediate('['), optional($.E), ']'),
group: $ => seq('(', optional($.E), ')'),
lambda: $ => seq('{', optional($.args), optional($.E), '}'),
args: $ => seq('[', $.name, repeat(seq(';', $.name)), ']'),
nil: _ => /0[in]/,
infinity: _ => /-?0w/i,
string: _ => seq('"', repeat(choice(/[^"\\]/, seq('\\', /./))), '"'),
qq: _ => delimited('qq'),
rq: _ => delimited('rq'),
rx: _ => delimited('rx'),
binairy: _ => token(/0b[01]+/),
int: _ => token(/-?\d+/),
number: _ => token(/-?\d+\.\d+/),
hex: _ => token(/-?0x[\da-f]+/i),
exponential: _ => token(/-?\d+e[+-]?\d+/i),
name: _ => /[a-zA-Z_π][\w_π]*/,
duration: _ => token(/-?(\d+(?:\.\d+)?(?:e[+-]?\d+)?[hms])+/),
inline_comment: _ => token(/[\t ]+\/[^\n]*/),
block_comment: _ => token(/\/(?:\n.*)*?\n\\/),
line_comment: _ => /\/[^\n]*/,
}
})