-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgrammar.js
121 lines (113 loc) · 2.86 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
module.exports = grammar({
name: "LBNF",
extras: $ => [
/\s/,
$.comment,
],
rules: {
grammar: $ => repeat(seq($.def, ';')),
def: $ => choice(
seq($.label, '.', $.cat, '::=', repeat($.item)),
seq('comment', $.string),
seq('comment', $.string, $.string),
seq('internal', $.label, '.', $.cat, '::=', repeat($.item)),
seq('token', $.ident, $.reg),
seq('position', 'token', $.ident, $.reg),
seq('entrypoints', seperate1($.ident)),
seq('separator', optional('nonempty'), $.cat, $.string),
seq('terminator', optional('nonempty'), $.cat, $.string),
seq('coercions', $.ident, $.integer),
seq('rules', $.ident, '::=', seperate1(repeat($.item), '|')),
seq('layout', seperate1($.string)),
seq('layout', 'stop', seperate1($.string)),
seq('layout', 'toplevel')
),
item: $ => choice(
$.string,
$.cat
),
cat: $ => choice(
seq('[', $.cat, ']'),
$.ident
),
label: $ => choice(
$.label_id,
seq($.label_id, repeat($.prof_item)),
seq($.label_id, $.label_id, repeat($.prof_item))
),
label_id: $ => choice(
$.ident,
'_',
seq('[', ']'),
seq('(', ':', ')'),
seq('(', ':', '[', ']', ')')
),
prof_item: $ => seq('(', '[', seperate($.int_list), ']', ',', '[', seperate($.integer), ']', ')'),
int_list: $ => seq('[', seperate($.integer), ']'),
reg2: $ => choice(
seq($.reg2, $.reg3),
$.reg3
),
reg1: $ => choice(
seq($.reg1, '|', $.reg2),
seq($.reg2, '-', $.reg2),
$.reg2
),
reg3: $ => choice(
seq($.reg3, '*'),
seq($.reg3, '+'),
seq($.reg3, '?'),
'eps',
$.char,
seq('[', $.string, ']'),
seq('{', $.string, '}'),
'digit',
'letter',
'upper',
'lower',
'char',
seq('(', $.reg, ')'),
),
reg: $ => $.reg1,
integer: $ => /\d+/,
char: $ => seq(
'\'',
choice(
$.escape_sequence,
token.immediate(/[^\n']/)
),
'\''
),
string: $ => seq(
'"',
repeat(choice(
token.immediate(prec(1, /[^\\"\n]+/)),
$.escape_sequence
)),
'"'
),
escape_sequence: $ => token.immediate(seq(
'\\',
choice(
/[^xuU]/,
/\d{2,3}/,
/x[0-9a-fA-F]{2,}/,
/u[0-9a-fA-F]{4}/,
/U[0-9a-fA-F]{8}/
)
)),
// char: $ => token(seq('\'', /([^'\n]|\\(.|\n))/, '\'')),
// string: $ => token(seq('"', /([^"\n]|\\(.|\n))*/, '"')),
ident: $ => /[a-zA-Z]\w*/,
comment: $ => token(choice(
seq('--', /.*/),
seq('{-', repeat(choice(/[^-]/, /-[^}]/)), '-}')
)),
}
});
function seperate(rule, separator=',') {
return optional(seperate1(rule, separator))
}
function seperate1(rule, separator=',') {
return seq(rule, repeat(seq(separator, rule)))
}