-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrammar.js
93 lines (78 loc) · 2.76 KB
/
grammar.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module.exports = grammar({
name: 'rampart',
rules: {
// Source files consist of series.
source_file: $ => seq(
repeat($._newline),
repeat($.series),
),
_newline: $ => '\n',
_record_sep: $ => seq(choice('\n', ',', ',\n'), repeat(' ')),
_series_sep: $ => seq(choice('\n', '\0', ';', ';\n', ';\0'), repeat(' '), repeat('\n')),
// Series consist of optional attributes and at least one point and end with at lease one newline.
series: $ => seq(
field('attributes', optional($.attribute_list)),
field('points', $.point_list),
$._series_sep,
),
// Attributes are a list of '@key value' pairs
attribute_list: $ => repeat1(seq($.attribute, $._record_sep)),
// @key value
// @key "v a l u e"
attribute: $ => seq(
'@',
field('key', $.key),
repeat1(' '),
field('value', choice($.value, $.qvalue)),
),
key: $ => $.ustring,
value: $ => field("content", $.ustring),
qvalue: $ => seq(
'"',
field("content", $.qstring),
'"',
),
ustring: $ => /[a-zA-Z0-9._-]+/,
qstring: $ => /[ a-zA-Z0-9._'-]+/,
// Point lists are lists of time, power points
point_list: $ => prec.right(seq(repeat(seq($.point, $._record_sep)), $.point, optional($._record_sep))),
// Times and powers are separated by a space
point: $ => seq(
field('time', $._point_time),
repeat1(' '),
field('power', $._point_power),
),
// If a time starts with a +, it's a relative time. Otherwise it's absolute.
_point_time: $ => choice($.abs_time, $.rel_time, $.sus_time),
abs_time: $ => field('content', $._time),
rel_time: $ => seq(/\+\s*/, field('content', $._time)),
sus_time: $ => '_',
_time: $ => choice($.m, $.hh_mm_ss, $.mm_ss, $.m_ss, $.ss),
// Plain integers are minutes
m: $ => /[0-5]?[0-9]/,
// 15:04:05
hh_mm_ss: $ => /([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]/,
// 4:05, 04:05
m_ss: $ => /[0-5]?[0-9]:[0-5][0-9]/,
// :04:05
mm_ss: $ => /:[0-5][0-9]:[0-5][0-9]/,
// :05
ss: $ => /:[0-5][0-9]/,
// If a power starts with a +, it's a relative power. Otherwise it's absolute.
// If a _ is given instead of a power, the previous power is sustained.
_point_power: $ => choice($.abs_power, $.rel_power, $.sus_power),
abs_power: $ => field('content', $._power),
rel_power: $ => seq(/\+\s*/, field('content', $._power)),
sus_power: $ => '_',
_power: $ => choice($.integer, $.decimal, $.exponent),
// 123
integer: $ => /-?\d(_?\d)*/,
// 123.456
decimal: $ => /-?(\d(_?\d)*)?\.(_?\d)*/,
// 1.23456e2
exponent: $ => /-?(\d(_?\d)*)?(\.(_?\d)*)?[eE]-?\d(_?\d)*/,
comment: $ => /\s*\/\/.*/,
},
// Comments are ignored
extras: $ => [$.comment],
});