srf-tree-sitter/grammar.js

114 lines
2.2 KiB
JavaScript

/**
* @file SRF (Simple Record Format) grammar for tree-sitter
* @author Emil Lerch
* @license MIT
*/
/// <reference types="tree-sitter-cli/dsl" />
// @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,]+/,
},
});