-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathgrammar.ts
71 lines (59 loc) · 1.96 KB
/
grammar.ts
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
import { commaSep, optChoice, repChoice } from "./utils";
export = grammar({
name: "json5",
extras: ($) => [$.comment, /\s/],
inline: ($) => [$.name],
rules: {
file: ($) => optChoice($.object, $.array),
comment: (_) =>
token(choice(seq("//", /[^\n]*/), seq("/*", repeat(/./), "*/"))),
object: ($) => seq("{", commaSep($.member), "}"),
member: ($) => seq(field("name", $.name), ":", field("value", $._value)),
name: ($) => choice($.string, $.identifier),
identifier: (_) => {
const identifier_start = /[\$_\p{L}]/;
const identifier_part = choice(identifier_start, /[0-9]/);
return token(seq(identifier_start, repeat(identifier_part)));
},
array: ($) => seq("[", commaSep($._value), "]"),
string: (_) => {
const double_quote = seq(
'"',
repChoice(
seq("\\", choice('"', "\\", "b", "f", "n", "r", "t", "v")),
/[^"\\]/
),
'"'
);
const single_quote = seq(
"'",
repChoice(
seq("\\", choice("'", "\\", "b", "f", "n", "r", "t", "v")),
/[^'\\]/
),
"'"
);
return token(choice(double_quote, single_quote));
},
number: (_) => {
const hex_digit = /[0-9a-fA-F]+/;
const hex_int = seq("0", /[xX]/, hex_digit);
const dec_digit = /[0-9]/;
const exp_part = seq(/[eE]/, optional(/[+-]/), repeat1(dec_digit));
const int_literal = choice("0", seq(/[1-9]/, repeat(dec_digit)));
const dec_literal = choice(
seq(int_literal, ".", repeat(dec_digit), optional(exp_part)),
seq(".", repeat(dec_digit), optional(exp_part)),
seq(int_literal, optional(exp_part))
);
return token(
seq(/[+-]?/, choice(hex_int, dec_literal, "Infinity", "NaN"))
);
},
null: ($) => "null",
true: ($) => "true",
false: ($) => "false",
_value: ($) =>
choice($.object, $.array, $.number, $.string, $.null, $.true, $.false),
},
});