/** * @file SRF (Simple Record Format) grammar for tree-sitter * @author Emil Lerch * @license MIT */ /// // @ts-check module.exports = grammar({ name: 'srf', extras: _ => [], rules: { document: $ => repeat($._line), _line: $ => choice( $.magic, $.directive, $.comment, $.field, $.blank_line, ), magic: $ => seq( '#!srfv1', optional($.inline_comment), '\n', ), inline_comment: _ => /[ \t]+#[^\n]*/, directive: $ => choice( $.directive_long, $.directive_compact, $.directive_requireeof, $.directive_eof, $.directive_expires, $.directive_created, $.directive_modified, $.directive_unknown, ), directive_long: $ => seq('#!long', optional($.inline_comment), '\n'), directive_compact: $ => seq('#!compact', optional($.inline_comment), '\n'), directive_requireeof: $ => seq('#!requireeof', optional($.inline_comment), '\n'), directive_eof: $ => seq('#!eof', optional($.inline_comment), '\n'), directive_expires: $ => seq( '#!expires=', field('value', $.timestamp), optional($.inline_comment), '\n', ), directive_created: $ => seq( '#!created=', field('value', $.timestamp), optional($.inline_comment), '\n', ), directive_modified: $ => seq( '#!modified=', field('value', $.timestamp), optional($.inline_comment), '\n', ), directive_unknown: _ => seq( /#!/, /[a-zA-Z][a-zA-Z0-9_]*/, optional(seq('=', /[^\n]*/)), '\n', ), timestamp: _ => /[0-9-]+/, comment: _ => token(seq('#', optional(seq(/[^!\n]/, /[^\n]*/)), '\n')), blank_line: _ => token(/[ \t]*\n/), field: $ => choice( $.typed_field, $.untyped_field, ), typed_field: $ => seq( $.key, ':', $.type_hint, ':', optional($.value), /[,\n]/, ), untyped_field: $ => seq( $.key, '::', optional($.value), /[,\n]/, ), key: _ => /[^#\n:, \t][^:,]*/, type_hint: _ => choice( 'string', 'num', 'bool', 'null', 'binary', /[0-9]+/, ), value: _ => /[^\n,]+/, }, });