@bablr/language-en-regex-vm-pattern 0.9.0 → 0.11.0
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/lib/grammar.js +30 -37
- package/lib/grammar.macro.js +37 -43
- package/package.json +8 -8
package/lib/grammar.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* @macrome
|
|
2
2
|
* @generatedby @bablr/macrome-generator-bablr
|
|
3
|
-
* @generatedfrom ./grammar.macro.js#
|
|
3
|
+
* @generatedfrom ./grammar.macro.js#c3c390f3e54607dfde1d07c0e099e54294ab7f32
|
|
4
4
|
* This file is autogenerated. Please do not edit it directly.
|
|
5
5
|
* When editing run `npx macrome watch` then change the file this is generated from.
|
|
6
6
|
*/
|
|
@@ -10,31 +10,17 @@ import { re, spam as m } from '@bablr/boot';
|
|
|
10
10
|
import { Node, CoveredBy, InjectFrom, UndefinedAttributes, AllowEmpty, Literal } from '@bablr/helpers/decorators';
|
|
11
11
|
import objectEntries from 'iter-tools-es/methods/object-entries';
|
|
12
12
|
import * as Shared from '@bablr/helpers/productions';
|
|
13
|
-
import { eat, eatMatch, match,
|
|
14
|
-
import { buildString
|
|
13
|
+
import { eat, eatMatch, match, shiftMatch, guard, defineAttribute, fail, o } from '@bablr/helpers/grammar';
|
|
14
|
+
import { buildString } from '@bablr/helpers/builders';
|
|
15
15
|
export const canonicalURL = 'https://bablr.org/languages/core/en/bablr-regex-pattern';
|
|
16
16
|
export const dependencies = {};
|
|
17
|
+
export const defaultMatcher = m`<Pattern />`;
|
|
17
18
|
const escapables = new Map(objectEntries({
|
|
18
19
|
n: '\n',
|
|
19
20
|
r: '\r',
|
|
20
21
|
t: '\t',
|
|
21
22
|
0: '\0'
|
|
22
23
|
}));
|
|
23
|
-
export const getCooked = (escapeNode, span, ctx) => {
|
|
24
|
-
let cooked;
|
|
25
|
-
const codeNode = escapeNode.get('code');
|
|
26
|
-
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
27
|
-
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
28
|
-
if (!type) {
|
|
29
|
-
const match_ = ctx.sourceTextFor(codeNode);
|
|
30
|
-
cooked = escapables.get(match_) || match_;
|
|
31
|
-
} else if (type === 'u' || type === 'x') {
|
|
32
|
-
cooked = parseInt(value, 16);
|
|
33
|
-
} else {
|
|
34
|
-
throw new Error();
|
|
35
|
-
}
|
|
36
|
-
return cooked.toString(10);
|
|
37
|
-
};
|
|
38
24
|
const flagCharacters = {
|
|
39
25
|
global: 'g',
|
|
40
26
|
ignoreCase: 'i',
|
|
@@ -46,7 +32,7 @@ const flagCharacters = {
|
|
|
46
32
|
const unique = flags => flags.length === new Set(flags).size;
|
|
47
33
|
const getSpecialPattern = span => {
|
|
48
34
|
if (span === 'Pattern') {
|
|
49
|
-
return re`/[
|
|
35
|
+
return re`/[*+?{}[\]().^$|\n\\<>]/`;
|
|
50
36
|
} else if (span === 'CharacterClass') {
|
|
51
37
|
return re`/[\]\\]/`;
|
|
52
38
|
} else {
|
|
@@ -62,7 +48,7 @@ export const grammar = class RegexGrammar {
|
|
|
62
48
|
}
|
|
63
49
|
*[(_FlagsDecs = [UndefinedAttributes(Object.keys(flagCharacters)), AllowEmpty, Node], _GroupDecs = [CoveredBy('Element'), Node], _AssertionDecs = CoveredBy('Element'), _StartOfInputAssertionDecs = [CoveredBy('Assertion'), Node], _EndOfInputAssertionDecs = [CoveredBy('Assertion'), Node], _WordBoundaryAssertionDecs = [UndefinedAttributes(['negate']), CoveredBy('Assertion'), Node], _GapDecs = [CoveredBy('Assertion'), Node], _CharacterDecs = [CoveredBy('Element'), CoveredBy('CharacterClassElement'), Node], _CharacterClassDecs = [UndefinedAttributes(['negate']), CoveredBy('Element'), Node], _CharacterClassRangeDecs = [CoveredBy('CharacterClassElement'), Node], _CharacterSetDecs = CoveredBy('Element'), _AnyCharacterSetDecs = [CoveredBy('Element'), CoveredBy('CharacterSet'), Node], _DigitCharacterSetDecs = [UndefinedAttributes(['negate']), CoveredBy('Element'), CoveredBy('CharacterSet'), Node], _SpaceCharacterSetDecs = [UndefinedAttributes(['negate']), CoveredBy('Element'), CoveredBy('CharacterSet'), Node], _WordCharacterSetDecs = [UndefinedAttributes(['negate']), CoveredBy('Element'), CoveredBy('CharacterSet'), Node], _QuantifierDecs = [UndefinedAttributes(['min', 'max']), Node], _AnyDecs = InjectFrom(Shared), _KeywordDecs = [Literal, Node, InjectFrom(Shared)], _PunctuatorDecs = [Literal, Node, InjectFrom(Shared)], "Pattern")]() {
|
|
64
50
|
yield eat(m`openToken: <*Punctuator '/' { balanced: '/', balancedSpan: 'Pattern' } />`);
|
|
65
|
-
yield eat(m`<
|
|
51
|
+
yield eat(m`<__Alternatives />`);
|
|
66
52
|
yield eat(m`closeToken: <*Punctuator '/' { balancer: true } />`);
|
|
67
53
|
yield eat(m`flags$: <Flags />`);
|
|
68
54
|
}
|
|
@@ -89,36 +75,36 @@ export const grammar = class RegexGrammar {
|
|
|
89
75
|
*Alternatives() {
|
|
90
76
|
do {
|
|
91
77
|
yield eat(m`alternatives[]$: <Alternative />`);
|
|
92
|
-
} while (yield eatMatch(m
|
|
78
|
+
} while (yield eatMatch(m`#separatorTokens[]: <*Punctuator '|' />`));
|
|
93
79
|
}
|
|
94
80
|
*Alternative() {
|
|
95
|
-
yield eat(m`elements[]+$: <
|
|
81
|
+
yield eat(m`elements[]+$: <__Elements />`);
|
|
96
82
|
}
|
|
97
83
|
*Elements() {
|
|
98
84
|
yield eat(m`.[]: []`);
|
|
99
85
|
while (yield match(re`/[^|]/`)) {
|
|
100
|
-
yield eat(m`.[]+: <
|
|
86
|
+
yield eat(m`.[]+: <_Element />`);
|
|
101
87
|
}
|
|
102
88
|
}
|
|
103
89
|
*Element() {
|
|
104
90
|
yield guard(m`<*Keyword /[*+?]/ />`);
|
|
105
|
-
yield eat(m`<
|
|
91
|
+
yield eat(m`<__Any />`, [m`<CharacterClass '[' />`, m`<Group '(?:' />`, m`<__Assertion /[$^]|\\b/i />`, m`<Gap '\\g' />`, m`<__CharacterSet /\.|\\[dswp]/i />`, m`<*Character />`]);
|
|
106
92
|
if (yield match(re`/[*+?{]/`)) {
|
|
107
|
-
return
|
|
93
|
+
return shiftMatch(m`<Quantifier />`);
|
|
108
94
|
}
|
|
109
95
|
}
|
|
110
96
|
*Group() {
|
|
111
97
|
yield eat(m`openToken: <*Punctuator '(?:' { balanced: ')' } />`);
|
|
112
|
-
yield eat(m`<
|
|
98
|
+
yield eat(m`<__Alternatives />`);
|
|
113
99
|
yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
|
|
114
100
|
}
|
|
115
101
|
*CapturingGroup() {
|
|
116
102
|
yield eat(m`openToken: <*Punctuator '(' { balanced: ')' } />`);
|
|
117
|
-
yield eat(m`<
|
|
103
|
+
yield eat(m`<__Alternatives />`);
|
|
118
104
|
yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
|
|
119
105
|
}
|
|
120
106
|
*Assertion() {
|
|
121
|
-
yield eat(m`<
|
|
107
|
+
yield eat(m`<__Any />`, [m`<StartOfInputAssertion '^' />`, m`<EndOfInputAssertion '$' />`, m`<WordBoundaryAssertion /\\b/i />`]);
|
|
122
108
|
}
|
|
123
109
|
*StartOfInputAssertion() {
|
|
124
110
|
yield eat(m`sigilToken: <*Keyword '^' />`);
|
|
@@ -131,7 +117,7 @@ export const grammar = class RegexGrammar {
|
|
|
131
117
|
}) {
|
|
132
118
|
yield eatMatch(m`escapeToken: <*Punctuator '\\' />`);
|
|
133
119
|
const m_ = yield eat(m`value: <*Keyword /b/i />`);
|
|
134
|
-
yield defineAttribute('negate',
|
|
120
|
+
yield defineAttribute('negate', ctx.sourceTextFor(m_) === 'B');
|
|
135
121
|
}
|
|
136
122
|
*Gap() {
|
|
137
123
|
yield eatMatch(m`escapeToken: <*Punctuator '\\' />`);
|
|
@@ -151,14 +137,14 @@ export const grammar = class RegexGrammar {
|
|
|
151
137
|
}));
|
|
152
138
|
yield defineAttribute('negate', !!negate);
|
|
153
139
|
while (yield match(re`/./s`)) {
|
|
154
|
-
yield eat(m`elements[]+$: <
|
|
140
|
+
yield eat(m`elements[]+$: <_CharacterClassElement />`);
|
|
155
141
|
}
|
|
156
142
|
yield eat(m`closeToken: <*Punctuator ']' { balancer: true } />`);
|
|
157
143
|
}
|
|
158
144
|
*CharacterClassElement() {
|
|
159
|
-
yield eat(m`<
|
|
145
|
+
yield eat(m`<__Any />`, [m`<__CharacterSet /\\[dswp]/i />`, m`<Gap '\\g' />`, m`<*Character />`]);
|
|
160
146
|
if (yield match('-')) {
|
|
161
|
-
return
|
|
147
|
+
return shiftMatch(m`<CharacterClassRange />`);
|
|
162
148
|
}
|
|
163
149
|
}
|
|
164
150
|
*CharacterClassRange() {
|
|
@@ -167,7 +153,7 @@ export const grammar = class RegexGrammar {
|
|
|
167
153
|
yield eat(m`max+$: <*Character />`);
|
|
168
154
|
}
|
|
169
155
|
*CharacterSet() {
|
|
170
|
-
yield eat(m`<
|
|
156
|
+
yield eat(m`<__Any />`, [m`<AnyCharacterSet '.' />`, m`<DigitCharacterSet /\\[dD]/ />`, m`<SpaceCharacterSet /\\[sS]/ />`, m`<WordCharacterSet /\\[wW]/ />`]);
|
|
171
157
|
}
|
|
172
158
|
*AnyCharacterSet() {
|
|
173
159
|
yield eat(m`sigilToken: <*Keyword '.' />`);
|
|
@@ -196,7 +182,7 @@ export const grammar = class RegexGrammar {
|
|
|
196
182
|
*Quantifier({
|
|
197
183
|
ctx
|
|
198
184
|
}) {
|
|
199
|
-
yield eat(m`element+$: <
|
|
185
|
+
yield eat(m`element+$: <_Element />`);
|
|
200
186
|
let attrs, sigil;
|
|
201
187
|
if (sigil = yield eatMatch(m`sigilToken: <*Keyword /[*+?]/ />`)) {
|
|
202
188
|
switch (ctx.sourceTextFor(sigil)) {
|
|
@@ -218,6 +204,8 @@ export const grammar = class RegexGrammar {
|
|
|
218
204
|
max: 1
|
|
219
205
|
};
|
|
220
206
|
break;
|
|
207
|
+
default:
|
|
208
|
+
yield fail();
|
|
221
209
|
}
|
|
222
210
|
} else if (yield eat(m`openToken: <*Punctuator '{' { balanced: '}' } />`)) {
|
|
223
211
|
let max;
|
|
@@ -251,17 +239,22 @@ export const grammar = class RegexGrammar {
|
|
|
251
239
|
const parentSpan = state.span;
|
|
252
240
|
yield eat(m`escape: <*Punctuator '\\' { openSpan: 'Escape' } />`);
|
|
253
241
|
let m_;
|
|
242
|
+
let cooked;
|
|
254
243
|
if (m_ = yield match(re`/[\\/nrt0]/`)) {
|
|
255
244
|
const match_ = ctx.sourceTextFor(m_);
|
|
256
245
|
yield eat(m`code: <*Keyword ${buildString(match_)} { closeSpan: 'Escape' } />`);
|
|
246
|
+
cooked = escapables.get(match_) || match_;
|
|
257
247
|
} else if (m_ = yield match(getSpecialPattern(parentSpan))) {
|
|
258
|
-
|
|
259
|
-
yield eat(m`code: <*Keyword ${buildString(
|
|
248
|
+
cooked = ctx.sourceTextFor(m_);
|
|
249
|
+
yield eat(m`code: <*Keyword ${buildString(cooked)} { closeSpan: 'Escape' } />`);
|
|
260
250
|
} else if (yield match(re`/[ux]/`)) {
|
|
261
|
-
yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
251
|
+
let code = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
252
|
+
let value = code.get('value');
|
|
253
|
+
cooked = String.fromCodePoint(parseInt(ctx.sourceTextFor(value), 16));
|
|
262
254
|
} else {
|
|
263
255
|
yield fail();
|
|
264
256
|
}
|
|
257
|
+
yield defineAttribute('cooked', cooked);
|
|
265
258
|
}
|
|
266
259
|
*EscapeCode() {
|
|
267
260
|
if (yield eatMatch(m`type: <*Keyword 'u' />`)) {
|
package/lib/grammar.macro.js
CHANGED
|
@@ -13,18 +13,20 @@ import {
|
|
|
13
13
|
eat,
|
|
14
14
|
eatMatch,
|
|
15
15
|
match,
|
|
16
|
-
|
|
16
|
+
shiftMatch,
|
|
17
17
|
guard,
|
|
18
18
|
defineAttribute,
|
|
19
19
|
fail,
|
|
20
20
|
o,
|
|
21
21
|
} from '@bablr/helpers/grammar';
|
|
22
|
-
import { buildString
|
|
22
|
+
import { buildString } from '@bablr/helpers/builders';
|
|
23
23
|
|
|
24
24
|
export const canonicalURL = 'https://bablr.org/languages/core/en/bablr-regex-pattern';
|
|
25
25
|
|
|
26
26
|
export const dependencies = {};
|
|
27
27
|
|
|
28
|
+
export const defaultMatcher = m`<Pattern />`;
|
|
29
|
+
|
|
28
30
|
const escapables = new Map(
|
|
29
31
|
objectEntries({
|
|
30
32
|
n: '\n',
|
|
@@ -34,25 +36,6 @@ const escapables = new Map(
|
|
|
34
36
|
}),
|
|
35
37
|
);
|
|
36
38
|
|
|
37
|
-
export const getCooked = (escapeNode, span, ctx) => {
|
|
38
|
-
let cooked;
|
|
39
|
-
const codeNode = escapeNode.get('code');
|
|
40
|
-
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
41
|
-
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
42
|
-
|
|
43
|
-
if (!type) {
|
|
44
|
-
const match_ = ctx.sourceTextFor(codeNode);
|
|
45
|
-
|
|
46
|
-
cooked = escapables.get(match_) || match_;
|
|
47
|
-
} else if (type === 'u' || type === 'x') {
|
|
48
|
-
cooked = parseInt(value, 16);
|
|
49
|
-
} else {
|
|
50
|
-
throw new Error();
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return cooked.toString(10);
|
|
54
|
-
};
|
|
55
|
-
|
|
56
39
|
const flagCharacters = {
|
|
57
40
|
global: 'g',
|
|
58
41
|
ignoreCase: 'i',
|
|
@@ -66,7 +49,7 @@ const unique = (flags) => flags.length === new Set(flags).size;
|
|
|
66
49
|
|
|
67
50
|
const getSpecialPattern = (span) => {
|
|
68
51
|
if (span === 'Pattern') {
|
|
69
|
-
return re`/[
|
|
52
|
+
return re`/[*+?{}[\]().^$|\n\\<>]/`;
|
|
70
53
|
} else if (span === 'CharacterClass') {
|
|
71
54
|
return re`/[\]\\]/`;
|
|
72
55
|
} else {
|
|
@@ -78,7 +61,7 @@ export const grammar = class RegexGrammar {
|
|
|
78
61
|
@Node
|
|
79
62
|
*Pattern() {
|
|
80
63
|
yield eat(m`openToken: <*Punctuator '/' { balanced: '/', balancedSpan: 'Pattern' } />`);
|
|
81
|
-
yield eat(m`<
|
|
64
|
+
yield eat(m`<__Alternatives />`);
|
|
82
65
|
yield eat(m`closeToken: <*Punctuator '/' { balancer: true } />`);
|
|
83
66
|
yield eat(m`flags$: <Flags />`);
|
|
84
67
|
}
|
|
@@ -110,27 +93,27 @@ export const grammar = class RegexGrammar {
|
|
|
110
93
|
*Alternatives() {
|
|
111
94
|
do {
|
|
112
95
|
yield eat(m`alternatives[]$: <Alternative />`);
|
|
113
|
-
} while (yield eatMatch(m
|
|
96
|
+
} while (yield eatMatch(m`#separatorTokens[]: <*Punctuator '|' />`));
|
|
114
97
|
}
|
|
115
98
|
|
|
116
99
|
@AllowEmpty
|
|
117
100
|
@Node
|
|
118
101
|
*Alternative() {
|
|
119
|
-
yield eat(m`elements[]+$: <
|
|
102
|
+
yield eat(m`elements[]+$: <__Elements />`);
|
|
120
103
|
}
|
|
121
104
|
|
|
122
105
|
@AllowEmpty
|
|
123
106
|
*Elements() {
|
|
124
107
|
yield eat(m`.[]: []`);
|
|
125
108
|
while (yield match(re`/[^|]/`)) {
|
|
126
|
-
yield eat(m`.[]+: <
|
|
109
|
+
yield eat(m`.[]+: <_Element />`);
|
|
127
110
|
}
|
|
128
111
|
}
|
|
129
112
|
|
|
130
113
|
*Element() {
|
|
131
114
|
yield guard(m`<*Keyword /[*+?]/ />`);
|
|
132
115
|
|
|
133
|
-
yield eat(m`<
|
|
116
|
+
yield eat(m`<__Any />`, [
|
|
134
117
|
m`<CharacterClass '[' />`,
|
|
135
118
|
m`<Group '(?:' />`,
|
|
136
119
|
m`<__Assertion /[$^]|\\b/i />`,
|
|
@@ -140,7 +123,7 @@ export const grammar = class RegexGrammar {
|
|
|
140
123
|
]);
|
|
141
124
|
|
|
142
125
|
if (yield match(re`/[*+?{]/`)) {
|
|
143
|
-
return
|
|
126
|
+
return shiftMatch(m`<Quantifier />`);
|
|
144
127
|
}
|
|
145
128
|
}
|
|
146
129
|
|
|
@@ -148,23 +131,23 @@ export const grammar = class RegexGrammar {
|
|
|
148
131
|
@Node
|
|
149
132
|
*Group() {
|
|
150
133
|
yield eat(m`openToken: <*Punctuator '(?:' { balanced: ')' } />`);
|
|
151
|
-
yield eat(m`<
|
|
134
|
+
yield eat(m`<__Alternatives />`);
|
|
152
135
|
yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
|
|
153
136
|
}
|
|
154
137
|
|
|
155
138
|
@Node
|
|
156
139
|
*CapturingGroup() {
|
|
157
140
|
yield eat(m`openToken: <*Punctuator '(' { balanced: ')' } />`);
|
|
158
|
-
yield eat(m`<
|
|
141
|
+
yield eat(m`<__Alternatives />`);
|
|
159
142
|
yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
|
|
160
143
|
}
|
|
161
144
|
|
|
162
145
|
@CoveredBy('Element')
|
|
163
146
|
*Assertion() {
|
|
164
|
-
yield eat(m`<
|
|
165
|
-
m
|
|
166
|
-
m
|
|
167
|
-
m
|
|
147
|
+
yield eat(m`<__Any />`, [
|
|
148
|
+
m`<StartOfInputAssertion '^' />`,
|
|
149
|
+
m`<EndOfInputAssertion '$' />`,
|
|
150
|
+
m`<WordBoundaryAssertion /\\b/i />`,
|
|
168
151
|
]);
|
|
169
152
|
}
|
|
170
153
|
|
|
@@ -186,7 +169,7 @@ export const grammar = class RegexGrammar {
|
|
|
186
169
|
*WordBoundaryAssertion({ ctx }) {
|
|
187
170
|
yield eatMatch(m`escapeToken: <*Punctuator '\\' />`);
|
|
188
171
|
const m_ = yield eat(m`value: <*Keyword /b/i />`);
|
|
189
|
-
yield defineAttribute('negate',
|
|
172
|
+
yield defineAttribute('negate', ctx.sourceTextFor(m_) === 'B');
|
|
190
173
|
}
|
|
191
174
|
|
|
192
175
|
@CoveredBy('Assertion')
|
|
@@ -218,21 +201,21 @@ export const grammar = class RegexGrammar {
|
|
|
218
201
|
yield defineAttribute('negate', !!negate);
|
|
219
202
|
|
|
220
203
|
while (yield match(re`/./s`)) {
|
|
221
|
-
yield eat(m`elements[]+$: <
|
|
204
|
+
yield eat(m`elements[]+$: <_CharacterClassElement />`);
|
|
222
205
|
}
|
|
223
206
|
|
|
224
207
|
yield eat(m`closeToken: <*Punctuator ']' { balancer: true } />`);
|
|
225
208
|
}
|
|
226
209
|
|
|
227
210
|
*CharacterClassElement() {
|
|
228
|
-
yield eat(m`<
|
|
211
|
+
yield eat(m`<__Any />`, [
|
|
229
212
|
m`<__CharacterSet /\\[dswp]/i />`,
|
|
230
213
|
m`<Gap '\\g' />`,
|
|
231
214
|
m`<*Character />`,
|
|
232
215
|
]);
|
|
233
216
|
|
|
234
217
|
if (yield match('-')) {
|
|
235
|
-
return
|
|
218
|
+
return shiftMatch(m`<CharacterClassRange />`);
|
|
236
219
|
}
|
|
237
220
|
}
|
|
238
221
|
|
|
@@ -246,7 +229,7 @@ export const grammar = class RegexGrammar {
|
|
|
246
229
|
|
|
247
230
|
@CoveredBy('Element')
|
|
248
231
|
*CharacterSet() {
|
|
249
|
-
yield eat(m`<
|
|
232
|
+
yield eat(m`<__Any />`, [
|
|
250
233
|
m`<AnyCharacterSet '.' />`,
|
|
251
234
|
m`<DigitCharacterSet /\\[dD]/ />`,
|
|
252
235
|
m`<SpaceCharacterSet /\\[sS]/ />`,
|
|
@@ -300,7 +283,7 @@ export const grammar = class RegexGrammar {
|
|
|
300
283
|
@UndefinedAttributes(['min', 'max'])
|
|
301
284
|
@Node
|
|
302
285
|
*Quantifier({ ctx }) {
|
|
303
|
-
yield eat(m`element+$: <
|
|
286
|
+
yield eat(m`element+$: <_Element />`);
|
|
304
287
|
|
|
305
288
|
let attrs, sigil;
|
|
306
289
|
|
|
@@ -315,6 +298,8 @@ export const grammar = class RegexGrammar {
|
|
|
315
298
|
case '?':
|
|
316
299
|
attrs = { min: 0, max: 1 };
|
|
317
300
|
break;
|
|
301
|
+
default:
|
|
302
|
+
yield fail();
|
|
318
303
|
}
|
|
319
304
|
} else if (yield eat(m`openToken: <*Punctuator '{' { balanced: '}' } />`)) {
|
|
320
305
|
let max;
|
|
@@ -356,18 +341,27 @@ export const grammar = class RegexGrammar {
|
|
|
356
341
|
yield eat(m`escape: <*Punctuator '\\' { openSpan: 'Escape' } />`);
|
|
357
342
|
|
|
358
343
|
let m_;
|
|
344
|
+
let cooked;
|
|
359
345
|
|
|
360
346
|
if ((m_ = yield match(re`/[\\/nrt0]/`))) {
|
|
361
347
|
const match_ = ctx.sourceTextFor(m_);
|
|
362
348
|
yield eat(m`code: <*Keyword ${buildString(match_)} { closeSpan: 'Escape' } />`);
|
|
349
|
+
|
|
350
|
+
cooked = escapables.get(match_) || match_;
|
|
363
351
|
} else if ((m_ = yield match(getSpecialPattern(parentSpan)))) {
|
|
364
|
-
|
|
365
|
-
yield eat(m`code: <*Keyword ${buildString(
|
|
352
|
+
cooked = ctx.sourceTextFor(m_);
|
|
353
|
+
yield eat(m`code: <*Keyword ${buildString(cooked)} { closeSpan: 'Escape' } />`);
|
|
366
354
|
} else if (yield match(re`/[ux]/`)) {
|
|
367
|
-
yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
355
|
+
let code = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
356
|
+
|
|
357
|
+
let value = code.get('value');
|
|
358
|
+
|
|
359
|
+
cooked = String.fromCodePoint(parseInt(ctx.sourceTextFor(value), 16));
|
|
368
360
|
} else {
|
|
369
361
|
yield fail();
|
|
370
362
|
}
|
|
363
|
+
|
|
364
|
+
yield defineAttribute('cooked', cooked);
|
|
371
365
|
}
|
|
372
366
|
|
|
373
367
|
@Node
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/language-en-regex-vm-pattern",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "A BABLR language for nonbacktracking JS-style regexes",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=12.0.0"
|
|
@@ -21,19 +21,19 @@
|
|
|
21
21
|
"test": "mocha"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@babel/runtime": "
|
|
25
|
-
"@bablr/boot": "0.
|
|
26
|
-
"@bablr/helpers": "0.
|
|
27
|
-
"@bablr/agast-helpers": "0.
|
|
28
|
-
"@bablr/agast-vm-helpers": "0.
|
|
24
|
+
"@babel/runtime": "7.28.2",
|
|
25
|
+
"@bablr/boot": "0.10.0",
|
|
26
|
+
"@bablr/helpers": "0.24.0",
|
|
27
|
+
"@bablr/agast-helpers": "0.9.0",
|
|
28
|
+
"@bablr/agast-vm-helpers": "0.9.0",
|
|
29
29
|
"iter-tools-es": "7.5.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#
|
|
32
|
+
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#c97bfa4b3663f8378e9b3e42bb5a41e685406cf9",
|
|
33
33
|
"@bablr/macrome": "^0.1.3",
|
|
34
34
|
"@bablr/macrome-generator-bablr": "^0.3.2",
|
|
35
35
|
"@qnighy/dedent": "0.1.1",
|
|
36
|
-
"bablr": "^0.
|
|
36
|
+
"bablr": "^0.10.0",
|
|
37
37
|
"enhanced-resolve": "^5.12.0",
|
|
38
38
|
"eslint": "^8.47.0",
|
|
39
39
|
"eslint-import-resolver-enhanced-resolve": "^1.0.5",
|