-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathjson-matcher.js
115 lines (114 loc) · 3.54 KB
/
json-matcher.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
import {TokenMatcher} from '../../lib/token-matcher.js';
import {JSONGoal} from './json-definitions.js';
export const matcher = (JSONGrammar =>
TokenMatcher.define(
// Matcher generator for this matcher instance
entity =>
TokenMatcher.join(
entity(JSONGrammar.Break()),
entity(JSONGrammar.Whitespace()),
entity(JSONGrammar.String()),
entity(JSONGrammar.Opener()),
entity(JSONGrammar.Closer()),
entity(JSONGrammar.Operator()),
entity(JSONGrammar.Keyword()),
entity(JSONGrammar.Number()),
entity(JSONGrammar.Fallthrough()),
),
// RegExp flags for this matcher instance
'gu',
// Property descriptors for this matcher instance
{goal: {value: JSONGoal, enumerable: true, writable: false}},
))({
Fallthrough: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
.
${entity(TokenMatcher.fallthroughEntity)}
)`,
),
Break: ({lf = true, crlf = false} = {}) =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
${TokenMatcher.join(lf && '\\n', crlf && '\\r\\n')}
${entity(TokenMatcher.breakEntity)}
)`,
),
Whitespace: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
\s+
${entity(TokenMatcher.whitespaceEntity)}
)`,
),
String: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
\\u.{0,4}|\\.|"
${entity(TokenMatcher.quoteEntity)}
)`,
),
Opener: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
\{|\[
${entity(TokenMatcher.openerEntity)}
)`,
),
Closer: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
\}|\]
${entity(TokenMatcher.closerEntity)}
)`,
),
Operator: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
:|,
${entity((text, entity, match, state) => {
match.format = 'punctuation';
TokenMatcher.capture(
state.context.goal.type ||
(state.context.goal === JSONGoal
? 'operator'
: state.context.goal.punctuators && state.context.goal.punctuators[text] === true
? (match.punctuator = 'punctuation')
: 'fault'),
match,
text,
);
})}
)`,
),
Keyword: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `\b(
${TokenMatcher.join(...JSONGoal.keywords)}
${entity((text, entity, match, state) => {
match.format = 'identifier';
TokenMatcher.capture(
state.context.goal.type ||
(state.context.goal.keywords && !!state.context.goal.keywords[text] && 'keyword') ||
'sequence',
match,
text,
);
})}
)\b`,
),
Number: () =>
TokenMatcher.define(
entity => TokenMatcher.sequence/* regexp */ `(
\b[${JSONGoal.ranges.DecimalDigit}]+\.[${JSONGoal.ranges.DecimalDigit}]+[eE][-+]?[${
JSONGoal.ranges.DecimalDigit
}]+
|(?:-|\b)[${JSONGoal.ranges.DecimalDigit}]+\.[${JSONGoal.ranges.DecimalDigit}]+
|(?:-|\b)(?:0|0*[${JSONGoal.ranges.DecimalDigit}]+)
${entity((text, entity, match, state) => {
match.format = 'number';
TokenMatcher.capture(state.context.goal.type || 'number', match, text);
})}
)\b`,
),
});