-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
grammar.js
47 lines (46 loc) · 1.23 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
module.exports = grammar({
name: 'uri',
rules: {
source_file: $ => repeat(seq($._definition, '\n')),
_definition: $ => choice(
// $._ignore,
$.uri
),
// _ignore: $ => /;.*/,
uri: $ => seq(
$.scheme,
':',
choice(
prec(2, seq($.authority, $.path)), // e.g., https://example.com/foo
$.authority, // e.g., https://example.com
$.path, // e.g., file:///home
),
optional(seq('?', $.query)),
optional(seq('#', $.fragment)),
),
authority: $ => seq(
'//',
optional($.userinfo),
optional(choice(
prec(2, seq($.host, ':', $.port)),
$.host,
)),
),
scheme: $ => /[a-zA-Z][a-zA-Z0-9+.-]*/,
userinfo: $ => /[^\n@]+@/, // TODO: should separate @
host: $ => choice(
// host without colon
/[^\n@:/]+/, // no-colon
// host not beginning with colon
seq(/[^\n@:/]+/, /[^\n@/]*:/, choice(
/[^\n@/:0-9][^\n@/:]*/, // : followed by non-numeric
/[0-9]+[^\n@/:0-9][^\n@/:]*/, // : followed by non-numeric
)),
// TODO: should support ^:
),
port: $ => /\d+/,
path: $ => seq(/[^\n?#]/, /([^\n?#]*)?/),
query: $ => /[^\n#]*/,
fragment: $ => /[^\n]*/,
}
});