-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.js
55 lines (48 loc) · 1.26 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
const IDENT = /\p{XID_Start}[-\p{XID_Continue}]*/u
module.exports = grammar({
name: 'gsp',
extras: $ => [/\p{Pattern_White_Space}+/u],
rules: {
document: $ => repeat($._toplevel),
_toplevel: $ => choice($.comment, $.node),
comment: $ => seq(
'/',
optional(seq(
field('name', $.ident),
optional(field('attrs', $.attr_list)),
)),
field('body', $.node_body),
),
node: $ => seq(
field('name', $.ident),
optional(field('attrs', $.attr_list)),
field('body', $.node_body),
),
node_body: $ => seq(
'{',
choice(
repeat($._toplevel),
seq(choice('-', '='), optional($.text)),
),
'}',
),
attr_list: $ => repeat1(choice(
$.attr,
$.id_attr,
$.class_attr,
)),
attr: $ => seq(
field('name', $.ident),
optional(seq('=', field('value', $.string))),
),
id_attr: $ => seq('#',
field('name', alias(token.immediate(IDENT), $.ident))),
class_attr: $ => seq('.',
field('name', alias(token.immediate(IDENT), $.ident))),
text: $ => repeat1(choice($.raw_text, $.inline_node)),
raw_text: $ => /(\\[@}\\]|[^@}\\\p{Pattern_White_Space}])((\\[@}\\]|[^@}\\])*(\\[@}\\]|[^@}\\\p{Pattern_White_Space}]))?/u,
inline_node: $ => seq('@', $._toplevel),
ident: $ => IDENT,
string: $ => /"(\\["\\]|[^"\\])*"/,
},
})