@bablr/boot 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/lib/builders.js +422 -0
- package/lib/index.js +124 -19
- package/lib/languages/cstml.js +258 -90
- package/lib/languages/instruction.js +10 -5
- package/lib/languages/regex.js +124 -36
- package/lib/languages/spamex.js +30 -59
- package/lib/miniparser.js +12 -10
- package/lib/path.js +3 -3
- package/lib/print.js +352 -0
- package/lib/utils.js +9 -8
- package/package.json +8 -5
- package/shorthand.macro.js +200 -104
- package/lib/languages/number.js +0 -38
- package/lib/languages/string.js +0 -86
package/lib/languages/cstml.js
CHANGED
|
@@ -1,118 +1,198 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
const Number = require('./number.js');
|
|
1
|
+
const objectEntries = require('iter-tools-es/methods/object-entries');
|
|
2
|
+
|
|
4
3
|
const { buildCovers } = require('../utils.js');
|
|
5
4
|
const sym = require('../symbols.js');
|
|
6
5
|
|
|
7
6
|
const _ = /\s+/y;
|
|
8
7
|
const PN = 'Punctuator';
|
|
9
8
|
const ID = 'Identifier';
|
|
9
|
+
const KW = 'Keyword';
|
|
10
10
|
const LIT = 'Literal';
|
|
11
11
|
|
|
12
12
|
const name = 'CSTML';
|
|
13
13
|
|
|
14
|
-
const
|
|
14
|
+
const canonicalURL = 'https://bablr.org/languages/core/cstml';
|
|
15
|
+
|
|
16
|
+
const dependencies = {};
|
|
17
|
+
|
|
18
|
+
const escapables = new Map(
|
|
19
|
+
objectEntries({
|
|
20
|
+
n: '\n',
|
|
21
|
+
r: '\r',
|
|
22
|
+
t: '\t',
|
|
23
|
+
0: '\0',
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const cookEscape = (escape, span) => {
|
|
28
|
+
let hexMatch;
|
|
29
|
+
|
|
30
|
+
if (!escape.startsWith('\\')) {
|
|
31
|
+
throw new Error('string escape must start with \\');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if ((hexMatch = /\\u([0-9a-f]{4})/iy.exec(escape))) {
|
|
35
|
+
//continue
|
|
36
|
+
} else if ((hexMatch = /\\u{([0-9a-f]+)}/iy.exec(escape))) {
|
|
37
|
+
//continue
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (hexMatch) {
|
|
41
|
+
return String.fromCodePoint(parseInt(hexMatch[1], 16));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const litPattern = span === 'Single' ? /\\([\\gnrt0'])/y : /\\([\\gnrt0"])/y;
|
|
45
|
+
const litMatch = litPattern.exec(escape);
|
|
46
|
+
|
|
47
|
+
if (litMatch) {
|
|
48
|
+
if (litMatch[1] === 'g') {
|
|
49
|
+
return null;
|
|
50
|
+
} else {
|
|
51
|
+
return escapables.get(litMatch[1]) || litMatch[1];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
throw new Error('unable to cook string escape');
|
|
56
|
+
};
|
|
15
57
|
|
|
16
58
|
const covers = buildCovers({
|
|
17
59
|
[sym.node]: [
|
|
60
|
+
'Document',
|
|
61
|
+
'DocumentVersion',
|
|
62
|
+
'DoctypeTag',
|
|
18
63
|
'Attribute',
|
|
19
64
|
'Property',
|
|
65
|
+
'Reference',
|
|
20
66
|
'TagType',
|
|
67
|
+
'Null',
|
|
68
|
+
'Gap',
|
|
21
69
|
'Node',
|
|
22
|
-
'
|
|
23
|
-
'
|
|
70
|
+
'IdentifierPath',
|
|
71
|
+
'OpenFragmentTag',
|
|
24
72
|
'OpenNodeTag',
|
|
25
73
|
'CloseNodeTag',
|
|
74
|
+
'CloseFragmentTag',
|
|
26
75
|
'Terminal',
|
|
76
|
+
'Number',
|
|
77
|
+
'Digit',
|
|
78
|
+
'String',
|
|
79
|
+
'Content',
|
|
80
|
+
'UnsignedInteger',
|
|
27
81
|
],
|
|
28
82
|
[sym.fragment]: ['Attributes', 'Fragment'],
|
|
29
83
|
Attribute: ['MappingAttribute', 'BooleanAttribute'],
|
|
30
|
-
AttributeValue: ['String
|
|
84
|
+
AttributeValue: ['String', 'Number'],
|
|
31
85
|
TagType: ['Identifier', 'GlobalIdentifier'],
|
|
32
86
|
Terminal: ['Literal', 'Trivia', 'Escape'],
|
|
87
|
+
PropertyValue: ['Gap', 'Node', 'Null'],
|
|
33
88
|
EmbeddedTerminal: ['Literal', 'Escape'],
|
|
89
|
+
Number: ['Integer', 'Infinity'],
|
|
34
90
|
});
|
|
35
91
|
|
|
36
92
|
const grammar = class CSTMLMiniparserGrammar {
|
|
37
93
|
Fragment(p) {
|
|
38
94
|
p.eatMatchTrivia(_);
|
|
39
|
-
p.eatProduction('
|
|
40
|
-
p.eatProduction('FragmentChildren');
|
|
41
|
-
p.eatProduction('CloseNodeTag', { path: 'close' });
|
|
42
|
-
p.eatMatchTrivia(_);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
FragmentChildren(p) {
|
|
95
|
+
p.eatProduction('OpenFragmentTag', { path: 'open' });
|
|
46
96
|
p.eatMatchTrivia(_);
|
|
47
|
-
while (p.match(
|
|
48
|
-
|
|
49
|
-
p.eatProduction('Trivia', { path: 'children[]' });
|
|
50
|
-
} else {
|
|
51
|
-
p.eatProduction('Property', { path: 'children[]' });
|
|
52
|
-
}
|
|
97
|
+
while (p.match(/<[^/]/y) || p.atExpression) {
|
|
98
|
+
p.eatProduction('Node', { path: 'root' });
|
|
53
99
|
p.eatMatchTrivia(_);
|
|
54
100
|
}
|
|
101
|
+
p.eatProduction('CloseFragmentTag', { path: 'close' });
|
|
102
|
+
p.eatMatchTrivia(_);
|
|
55
103
|
}
|
|
56
104
|
|
|
57
105
|
// @Node
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
106
|
+
Document(p) {
|
|
107
|
+
p.eatProduction('DoctypeTag', { path: 'doctype' });
|
|
108
|
+
p.eatProduction('Fragment', { path: 'tree' });
|
|
109
|
+
}
|
|
61
110
|
|
|
62
|
-
|
|
111
|
+
// @Node
|
|
112
|
+
DoctypeTag(p) {
|
|
113
|
+
p.eat('<!', PN, { path: 'open' });
|
|
114
|
+
p.eatProduction('UnsignedInteger', { path: 'version' });
|
|
115
|
+
p.eat(':', PN, { path: 'versionSeparator' });
|
|
116
|
+
p.eat('cstml', KW, { path: 'doctype' });
|
|
63
117
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
p.eatProduction('
|
|
118
|
+
let sp = p.eatMatchTrivia(_);
|
|
119
|
+
|
|
120
|
+
if ((sp && p.match(/\w+/y)) || p.atExpression) {
|
|
121
|
+
p.eatProduction('Attributes');
|
|
122
|
+
sp = p.eatMatchTrivia(_);
|
|
68
123
|
}
|
|
124
|
+
|
|
125
|
+
p.eat('>', PN, { path: 'close' });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// @Node
|
|
129
|
+
Null(p) {
|
|
130
|
+
p.eat('null', KW, { path: 'value' });
|
|
69
131
|
}
|
|
70
132
|
|
|
71
|
-
|
|
72
|
-
|
|
133
|
+
// @Node
|
|
134
|
+
Gap(p) {
|
|
135
|
+
p.eat('<//>', PN, { path: 'value' });
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// @Node
|
|
139
|
+
Node(p) {
|
|
140
|
+
if (p.match('<>')) throw new Error('Fragment is not a node');
|
|
141
|
+
|
|
142
|
+
let open = p.eatProduction('OpenNodeTag', { path: 'open' });
|
|
73
143
|
|
|
74
144
|
p.eatMatchTrivia(_);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
} else {
|
|
79
|
-
p.eatProduction('Property', { path: 'children[]' });
|
|
80
|
-
properties++;
|
|
81
|
-
}
|
|
145
|
+
|
|
146
|
+
if (open.properties.flags?.token) {
|
|
147
|
+
p.eatProduction('NodeChild', { path: 'children[]' }, { token: true });
|
|
82
148
|
p.eatMatchTrivia(_);
|
|
149
|
+
} else {
|
|
150
|
+
while (!p.match('</')) {
|
|
151
|
+
p.eatProduction('NodeChild', { path: 'children[]' });
|
|
152
|
+
p.eatMatchTrivia(_);
|
|
153
|
+
}
|
|
83
154
|
}
|
|
84
155
|
|
|
85
|
-
|
|
156
|
+
p.eatProduction('CloseNodeTag', { path: 'close' });
|
|
86
157
|
}
|
|
87
158
|
|
|
88
|
-
|
|
89
|
-
|
|
159
|
+
NodeChild(p, _, props) {
|
|
160
|
+
const { token } = props || {};
|
|
90
161
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
162
|
+
if (token) {
|
|
163
|
+
p.eatProduction('Literal');
|
|
164
|
+
} else {
|
|
165
|
+
if (p.match(/<\*?#/y)) {
|
|
166
|
+
p.eatProduction('Node');
|
|
167
|
+
} else if (p.match(/\w/y)) {
|
|
168
|
+
p.eatProduction('Property');
|
|
169
|
+
} else if (p.match(/['"]/y)) {
|
|
170
|
+
p.eatProduction('Literal');
|
|
98
171
|
}
|
|
99
|
-
p.eatMatchTrivia(_);
|
|
100
172
|
}
|
|
101
|
-
|
|
102
|
-
if (!properties) throw new Error('Nodes must match text');
|
|
103
173
|
}
|
|
104
174
|
|
|
105
175
|
// @Node
|
|
106
176
|
Property(p) {
|
|
107
|
-
p.
|
|
177
|
+
p.eatProduction('Reference', { path: 'reference' });
|
|
108
178
|
p.eatMatchTrivia(_);
|
|
109
179
|
p.eat(':', PN, { path: 'mapOperator' });
|
|
110
180
|
p.eatMatchTrivia(_);
|
|
111
|
-
p.eatProduction('
|
|
181
|
+
p.eatProduction('PropertyValue', { path: 'value' });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
PropertyValue(p) {
|
|
185
|
+
if (p.match('null')) {
|
|
186
|
+
p.eatProduction('Null');
|
|
187
|
+
} else if (p.match('<//>')) {
|
|
188
|
+
p.eatProduction('Gap');
|
|
189
|
+
} else {
|
|
190
|
+
p.eatProduction('Node');
|
|
191
|
+
}
|
|
112
192
|
}
|
|
113
193
|
|
|
114
194
|
// @Node
|
|
115
|
-
|
|
195
|
+
OpenFragmentTag(p) {
|
|
116
196
|
p.eat('<', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
|
|
117
197
|
p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
|
|
118
198
|
}
|
|
@@ -120,30 +200,22 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
120
200
|
// @Node
|
|
121
201
|
OpenNodeTag(p) {
|
|
122
202
|
p.eat('<', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
|
|
123
|
-
p.eatProduction('TagType', { path: 'type' });
|
|
124
|
-
|
|
125
|
-
let sp = p.eatMatchTrivia(_);
|
|
126
203
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
204
|
+
let tr = p.eatMatch('#', PN, { path: 'triviaFlag' });
|
|
205
|
+
let tok = p.eatMatch('*', PN, { path: 'tokenFlag' });
|
|
206
|
+
let esc = p.eatMatch('@', PN, { path: 'escapeFlag' });
|
|
207
|
+
let exp = p.eatMatch('+', PN, { path: 'expressionFlag' });
|
|
131
208
|
|
|
132
|
-
|
|
133
|
-
p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
|
|
134
|
-
}
|
|
209
|
+
if ((tr && esc) || (exp && (tr || esc))) throw new Error();
|
|
135
210
|
|
|
136
|
-
// @Node
|
|
137
|
-
TerminalNodeShorthandTag(p) {
|
|
138
|
-
p.eat('<|', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
|
|
139
|
-
p.eatMatchTrivia(_);
|
|
140
211
|
p.eatProduction('TagType', { path: 'type' });
|
|
141
212
|
|
|
142
213
|
let sp = p.eatMatchTrivia(_);
|
|
143
214
|
|
|
144
|
-
let
|
|
145
|
-
if (sp && p.match(/['"/]/y)) {
|
|
146
|
-
|
|
215
|
+
let iv;
|
|
216
|
+
if (tok && sp && (p.match(/['"/]/y) || p.atExpression)) {
|
|
217
|
+
iv = p.eatProduction('String', { path: 'intrinsicValue' });
|
|
218
|
+
|
|
147
219
|
sp = p.eatMatchTrivia(_);
|
|
148
220
|
}
|
|
149
221
|
|
|
@@ -153,7 +225,10 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
153
225
|
}
|
|
154
226
|
|
|
155
227
|
p.eatMatchTrivia(_);
|
|
156
|
-
|
|
228
|
+
if (iv) {
|
|
229
|
+
p.eat('/', PN, { path: 'selfClosingToken' });
|
|
230
|
+
}
|
|
231
|
+
p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
|
|
157
232
|
}
|
|
158
233
|
|
|
159
234
|
// @Node
|
|
@@ -162,6 +237,12 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
162
237
|
p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
|
|
163
238
|
}
|
|
164
239
|
|
|
240
|
+
// @Node
|
|
241
|
+
CloseFragmentTag(p) {
|
|
242
|
+
p.eat('</', PN, { path: 'open', startSpan: 'Tag', balanced: '>' });
|
|
243
|
+
p.eat('>', PN, { path: 'close', endSpan: 'Tag', balancer: true });
|
|
244
|
+
}
|
|
245
|
+
|
|
165
246
|
// @Fragment
|
|
166
247
|
Attributes(p) {
|
|
167
248
|
let sp = true;
|
|
@@ -181,7 +262,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
181
262
|
|
|
182
263
|
// @Cover
|
|
183
264
|
Attribute(p) {
|
|
184
|
-
if (p.match(/\w
|
|
265
|
+
if (p.match(/\w[\w-_]*\s*=/y)) {
|
|
185
266
|
p.eatProduction('MappingAttribute');
|
|
186
267
|
} else {
|
|
187
268
|
p.eatProduction('BooleanAttribute');
|
|
@@ -190,6 +271,7 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
190
271
|
|
|
191
272
|
// @Node
|
|
192
273
|
BooleanAttribute(p) {
|
|
274
|
+
p.eat('!', KW, { path: 'negated' });
|
|
193
275
|
p.eat(/\w+/y, ID, { path: 'key' });
|
|
194
276
|
}
|
|
195
277
|
|
|
@@ -205,31 +287,41 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
205
287
|
// @Cover
|
|
206
288
|
AttributeValue(p) {
|
|
207
289
|
if (p.match(/['"]/y)) {
|
|
208
|
-
p.eatProduction('String
|
|
209
|
-
} else if (p.match(
|
|
210
|
-
p.eatProduction('Number
|
|
290
|
+
p.eatProduction('String');
|
|
291
|
+
} else if (p.match(/[\d+-]/y)) {
|
|
292
|
+
p.eatProduction('Number');
|
|
211
293
|
}
|
|
212
294
|
}
|
|
213
295
|
|
|
214
|
-
// @Cover
|
|
215
296
|
TagType(p) {
|
|
216
|
-
if (p.match(
|
|
217
|
-
p.eatProduction('
|
|
297
|
+
if (p.match(/[\w.]+:/y)) {
|
|
298
|
+
p.eatProduction('LanguageReference', { path: 'language' });
|
|
299
|
+
p.eat(':', PN, { path: 'namespaceOperator' });
|
|
300
|
+
p.eatProduction('Identifier', { path: 'type' });
|
|
218
301
|
} else {
|
|
219
|
-
p.
|
|
302
|
+
p.eatProduction('Identifier', { path: 'type' });
|
|
220
303
|
}
|
|
221
304
|
}
|
|
222
305
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
306
|
+
LanguageReference(p) {
|
|
307
|
+
if (p.match(/['"]/y)) {
|
|
308
|
+
p.eatProduction('String');
|
|
309
|
+
} else {
|
|
310
|
+
p.eatProduction('IdentifierPath');
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
IdentifierPath(p) {
|
|
315
|
+
p.eatProduction('Identifier', { path: 'segments[]' });
|
|
316
|
+
while (p.match('.')) {
|
|
317
|
+
p.eat('.', PN, { path: 'separators[]' });
|
|
318
|
+
p.eatProduction('Identifier', { path: 'segments[]' });
|
|
319
|
+
}
|
|
228
320
|
}
|
|
229
321
|
|
|
230
322
|
// @Node
|
|
231
323
|
Identifier(p) {
|
|
232
|
-
p.eatLiteral(/\w
|
|
324
|
+
p.eatLiteral(/\w[\w-_]*/y);
|
|
233
325
|
}
|
|
234
326
|
|
|
235
327
|
// @Cover
|
|
@@ -245,6 +337,13 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
245
337
|
}
|
|
246
338
|
}
|
|
247
339
|
|
|
340
|
+
// @Node
|
|
341
|
+
Reference(p) {
|
|
342
|
+
p.eatProduction('Identifier', { path: 'name' });
|
|
343
|
+
p.eatMatchTrivia(_);
|
|
344
|
+
p.eatMatch('[]', PN, { path: 'arrayOperator' });
|
|
345
|
+
}
|
|
346
|
+
|
|
248
347
|
// @Cover
|
|
249
348
|
EmbeddedTerminal(p) {
|
|
250
349
|
if (p.match(/!['"]/y)) {
|
|
@@ -259,22 +358,91 @@ const grammar = class CSTMLMiniparserGrammar {
|
|
|
259
358
|
// @Node
|
|
260
359
|
Escape(p) {
|
|
261
360
|
p.eat('!', PN, { path: 'escapeOperator' });
|
|
262
|
-
p.eatProduction('String
|
|
361
|
+
p.eatProduction('String', { path: 'rawValue' });
|
|
263
362
|
p.eatMatchTrivia(_);
|
|
264
363
|
p.eat(':', PN, { path: 'rawOperator' });
|
|
265
|
-
p.eatProduction('String
|
|
364
|
+
p.eatProduction('String', { path: 'value' });
|
|
266
365
|
}
|
|
267
366
|
|
|
268
367
|
// @Node
|
|
269
368
|
Trivia(p) {
|
|
270
369
|
p.eat('#', PN, { path: 'trivializeOperator' });
|
|
271
|
-
p.eatProduction('String
|
|
370
|
+
p.eatProduction('String', { path: 'value' });
|
|
272
371
|
}
|
|
273
372
|
|
|
274
373
|
// @Node
|
|
275
374
|
Literal(p) {
|
|
276
|
-
p.eatProduction('String
|
|
375
|
+
p.eatProduction('String', { path: 'value' });
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
Number(p) {
|
|
379
|
+
if (p.match(/-?\d/y)) {
|
|
380
|
+
p.eatProduction('Integer');
|
|
381
|
+
} else {
|
|
382
|
+
p.eatProduction('Infinity');
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// @Node
|
|
387
|
+
Integer(p) {
|
|
388
|
+
p.eatMatch('-', 'Punctuator', { path: 'negative' });
|
|
389
|
+
p.eatProduction('Digits', { path: 'digits[]' });
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// @Node
|
|
393
|
+
UnsignedInteger(p) {
|
|
394
|
+
p.eatProduction('Digits', { path: 'digits[]' });
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
// @Node
|
|
398
|
+
Infinity(p) {
|
|
399
|
+
p.eatMatch(/[+-]/, 'Punctuator', { path: 'sign' });
|
|
400
|
+
p.eat('Infinity', 'Keyword', { path: 'value' });
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
Digits(p) {
|
|
404
|
+
while (p.match(/\d/y)) {
|
|
405
|
+
p.eatProduction('Digit');
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// @Node
|
|
410
|
+
Digit(p) {
|
|
411
|
+
p.eatLiteral(/\d/y);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// @Node
|
|
415
|
+
String(p) {
|
|
416
|
+
const q = p.match(/['"]/y) || '"';
|
|
417
|
+
|
|
418
|
+
const span = q === '"' ? 'Double' : 'Single';
|
|
419
|
+
|
|
420
|
+
p.eat(q, PN, { path: 'open', startSpan: span, balanced: q });
|
|
421
|
+
while (p.match(/./sy) || p.atExpression) {
|
|
422
|
+
p.eatProduction('Content', { path: 'content' });
|
|
423
|
+
}
|
|
424
|
+
p.eat(q, PN, { path: 'close', endSpan: span, balancer: true });
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// @Node
|
|
428
|
+
Content(p) {
|
|
429
|
+
let esc, lit;
|
|
430
|
+
let i = 0;
|
|
431
|
+
do {
|
|
432
|
+
esc =
|
|
433
|
+
p.span.type === 'Single'
|
|
434
|
+
? p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|[\\gnrt0'])/y)
|
|
435
|
+
: p.eatMatchEscape(/\\(u(\{\d{1,6}\}|\d{4})|[\\gnrt0"])/y);
|
|
436
|
+
lit =
|
|
437
|
+
p.span.type === 'Single'
|
|
438
|
+
? p.eatMatchLiteral(/[^\r\n\0\\']+/y)
|
|
439
|
+
: p.eatMatchLiteral(/[^\r\n\0\\"]+/y);
|
|
440
|
+
i++;
|
|
441
|
+
} while (esc || lit);
|
|
442
|
+
if (i === 1 && !esc && !lit) {
|
|
443
|
+
throw new Error('Invalid string content');
|
|
444
|
+
}
|
|
277
445
|
}
|
|
278
446
|
};
|
|
279
447
|
|
|
280
|
-
module.exports = { name, dependencies, covers, grammar };
|
|
448
|
+
module.exports = { name, canonicalURL, dependencies, covers, grammar, cookEscape, escapables };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Spamex = require('./spamex.js');
|
|
2
|
+
const CSTML = require('./cstml.js');
|
|
2
3
|
const Regex = require('./regex.js');
|
|
3
|
-
const StringLanguage = require('./string.js');
|
|
4
4
|
const { node } = require('../symbols.js');
|
|
5
5
|
const { buildCovers } = require('../utils.js');
|
|
6
6
|
|
|
@@ -12,7 +12,9 @@ const LIT = 'Literal';
|
|
|
12
12
|
|
|
13
13
|
const name = 'Instruction';
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const canonicalURL = 'https://bablr.org/languages/core/bablr-vm-instruction';
|
|
16
|
+
|
|
17
|
+
const dependencies = { Spamex, CSTML, Regex };
|
|
16
18
|
|
|
17
19
|
const covers = buildCovers({
|
|
18
20
|
[node]: ['Call', 'Punctuator', 'Property', 'Expression'],
|
|
@@ -21,7 +23,8 @@ const covers = buildCovers({
|
|
|
21
23
|
'Array',
|
|
22
24
|
'Tuple',
|
|
23
25
|
'Identifier',
|
|
24
|
-
'
|
|
26
|
+
'CSTML:String',
|
|
27
|
+
'CSTML:Gap',
|
|
25
28
|
'Regex:Pattern',
|
|
26
29
|
'Boolean',
|
|
27
30
|
'Null',
|
|
@@ -47,7 +50,9 @@ const grammar = class InstructionMiniparserGrammar {
|
|
|
47
50
|
} else if (p.match('(')) {
|
|
48
51
|
p.eatProduction('Tuple');
|
|
49
52
|
} else if (p.match(/['"]/y)) {
|
|
50
|
-
p.eatProduction('
|
|
53
|
+
p.eatProduction('CSTML:String');
|
|
54
|
+
} else if (p.match('<//>')) {
|
|
55
|
+
p.eatProduction('CSTML:Gap');
|
|
51
56
|
} else if (p.match('/')) {
|
|
52
57
|
p.eatProduction('Regex:Pattern');
|
|
53
58
|
} else if (p.match(/true|false/y)) {
|
|
@@ -133,4 +138,4 @@ const grammar = class InstructionMiniparserGrammar {
|
|
|
133
138
|
}
|
|
134
139
|
};
|
|
135
140
|
|
|
136
|
-
module.exports = { name, dependencies, covers, grammar };
|
|
141
|
+
module.exports = { name, canonicalURL, dependencies, covers, grammar };
|