@bablr/language-en-regex-vm-pattern 0.7.1 → 0.9.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.
Files changed (3) hide show
  1. package/lib/grammar.js +151 -10216
  2. package/lib/grammar.macro.js +147 -127
  3. package/package.json +16 -9
@@ -1,14 +1,25 @@
1
- import { i, re } from '@bablr/boot/shorthand.macro';
1
+ import { re, spam as m } from '@bablr/boot';
2
2
  import {
3
3
  Node,
4
4
  CoveredBy,
5
5
  InjectFrom,
6
- UnboundAttributes,
6
+ UndefinedAttributes,
7
7
  AllowEmpty,
8
+ Literal,
8
9
  } from '@bablr/helpers/decorators';
9
10
  import objectEntries from 'iter-tools-es/methods/object-entries';
10
11
  import * as Shared from '@bablr/helpers/productions';
11
- import { buildString, buildBoolean, buildNumber, buildNullTag } from '@bablr/helpers/builders';
12
+ import {
13
+ eat,
14
+ eatMatch,
15
+ match,
16
+ holdForMatch,
17
+ guard,
18
+ defineAttribute,
19
+ fail,
20
+ o,
21
+ } from '@bablr/helpers/grammar';
22
+ import { buildString, buildBoolean } from '@bablr/helpers/builders';
12
23
 
13
24
  export const canonicalURL = 'https://bablr.org/languages/core/en/bablr-regex-pattern';
14
25
 
@@ -66,17 +77,17 @@ const getSpecialPattern = (span) => {
66
77
  export const grammar = class RegexGrammar {
67
78
  @Node
68
79
  *Pattern() {
69
- yield i`eat(<*Punctuator '/' balanced='/' balancedSpan='Pattern' /> 'openToken')`;
70
- yield i`eat(<Alternatives />)`;
71
- yield i`eat(<*Punctuator '/' balancer /> 'closeToken')`;
72
- yield i`eat(<Flags /> 'flags$')`;
80
+ yield eat(m`openToken: <*Punctuator '/' { balanced: '/', balancedSpan: 'Pattern' } />`);
81
+ yield eat(m`<_Alternatives />`);
82
+ yield eat(m`closeToken: <*Punctuator '/' { balancer: true } />`);
83
+ yield eat(m`flags$: <Flags />`);
73
84
  }
74
85
 
75
- @UnboundAttributes(Object.keys(flagCharacters))
86
+ @UndefinedAttributes(Object.keys(flagCharacters))
76
87
  @AllowEmpty
77
88
  @Node
78
89
  *Flags({ ctx }) {
79
- const flags = yield i`match(/[gimsuy]+/)`;
90
+ const flags = yield match(re`/[gimsuy]+/`);
80
91
 
81
92
  const flagsStr = ctx.sourceTextFor(flags) || '';
82
93
 
@@ -84,212 +95,216 @@ export const grammar = class RegexGrammar {
84
95
 
85
96
  for (const { 0: name, 1: chr } of Object.entries(flagCharacters)) {
86
97
  if (flagsStr.includes(chr)) {
87
- yield i`bindAttribute(${buildString(name)} true)`;
98
+ yield defineAttribute(name, true);
88
99
  } else {
89
- yield i`bindAttribute(${buildString(name)} false)`;
100
+ yield defineAttribute(name, false);
90
101
  }
91
102
  }
92
103
 
93
104
  for (const flagChr of flagsStr) {
94
- yield i`eat(<*Keyword ${buildString(flagChr)} /> 'tokens[]')`;
105
+ yield eat(m`tokens[]: <*Keyword ${buildString(flagChr)} />`);
95
106
  }
96
107
  }
97
108
 
98
109
  @AllowEmpty
99
110
  *Alternatives() {
100
111
  do {
101
- yield i`eat(<Alternative /> 'alternatives[]$')`;
102
- } while (yield i`eatMatch(<*Punctuator '|' /> 'separators[]')`);
112
+ yield eat(m`alternatives[]$: <Alternative />`);
113
+ } while (yield eatMatch(m`separatorTokens[]: <*Punctuator '|' />`));
103
114
  }
104
115
 
105
116
  @AllowEmpty
106
117
  @Node
107
118
  *Alternative() {
108
- yield i`eat(<Elements /> 'elements[]$')`;
119
+ yield eat(m`elements[]+$: <_Elements />`);
109
120
  }
110
121
 
111
122
  @AllowEmpty
112
123
  *Elements() {
113
- yield i`eat([])`;
114
- while (yield i`match(/[^|]/)`) {
115
- yield i`eat(<+Element />)`;
124
+ yield eat(m`.[]: []`);
125
+ while (yield match(re`/[^|]/`)) {
126
+ yield eat(m`.[]+: <__Element />`);
116
127
  }
117
128
  }
118
129
 
119
130
  *Element() {
120
- yield i`guard(<*Keyword /[*+?]/ />)`;
121
-
122
- yield i`eat(<Any /> null [
123
- <+CharacterClass '[' />
124
- <+Group '(?:' />
125
- <+Assertion /[$^]|\\b/i />
126
- <+Gap '\\g' />
127
- <+CharacterSet /\.|\\[dswp]/i />
128
- <*+Character />
129
- ])`;
130
-
131
- if (yield i`match(/[*+?{]/)`) {
132
- return i`holdForMatch(<Quantifier />)`;
131
+ yield guard(m`<*Keyword /[*+?]/ />`);
132
+
133
+ yield eat(m`<_Any />`, [
134
+ m`<CharacterClass '[' />`,
135
+ m`<Group '(?:' />`,
136
+ m`<__Assertion /[$^]|\\b/i />`,
137
+ m`<Gap '\\g' />`,
138
+ m`<__CharacterSet /\.|\\[dswp]/i />`,
139
+ m`<*Character />`,
140
+ ]);
141
+
142
+ if (yield match(re`/[*+?{]/`)) {
143
+ return holdForMatch(m`<Quantifier />`);
133
144
  }
134
145
  }
135
146
 
136
147
  @CoveredBy('Element')
137
148
  @Node
138
149
  *Group() {
139
- yield i`eat(<*Punctuator '(?:' balanced=')' /> 'openToken')`;
140
- yield i`eat(<Alternatives />)`;
141
- yield i`eat(<*Punctuator ')' balancer /> 'closeToken')`;
150
+ yield eat(m`openToken: <*Punctuator '(?:' { balanced: ')' } />`);
151
+ yield eat(m`<_Alternatives />`);
152
+ yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
142
153
  }
143
154
 
144
155
  @Node
145
156
  *CapturingGroup() {
146
- yield i`eat(<*Punctuator '(' balanced=')' /> 'openToken')`;
147
- yield i`eat(<Alternatives />)`;
148
- yield i`eat(<*Punctuator ')' balancer /> 'closeToken')`;
157
+ yield eat(m`openToken: <*Punctuator '(' { balanced: ')' } />`);
158
+ yield eat(m`<_Alternatives />`);
159
+ yield eat(m`closeToken: <*Punctuator ')' { balancer: true } />`);
149
160
  }
150
161
 
151
162
  @CoveredBy('Element')
152
163
  *Assertion() {
153
- yield i`eat(<Any /> null [
154
- <*StartOfInputAssertion '^' />
155
- <*EndOfInputAssertion '$' />
156
- <*@WordBoundaryAssertion /\\b/i />
157
- ])`;
164
+ yield eat(m`<_Any />`, [
165
+ m`<*StartOfInputAssertion '^' />`,
166
+ m`<*EndOfInputAssertion '$' />`,
167
+ m`<*WordBoundaryAssertion /\\b/i />`,
168
+ ]);
158
169
  }
159
170
 
160
171
  @CoveredBy('Assertion')
161
172
  @Node
162
173
  *StartOfInputAssertion() {
163
- yield i`eat(<*Keyword '^' /> 'sigilToken')`;
174
+ yield eat(m`sigilToken: <*Keyword '^' />`);
164
175
  }
165
176
 
166
177
  @CoveredBy('Assertion')
167
178
  @Node
168
179
  *EndOfInputAssertion() {
169
- yield i`eatMatch(<*Keyword '$' /> 'sigilToken')`;
180
+ yield eatMatch(m`sigilToken: <*Keyword '$' />`);
170
181
  }
171
182
 
172
- @UnboundAttributes(['negate'])
183
+ @UndefinedAttributes(['negate'])
173
184
  @CoveredBy('Assertion')
174
185
  @Node
175
186
  *WordBoundaryAssertion({ ctx }) {
176
- yield i`eatMatch(<*Punctuator '\\' /> 'escapeToken')`;
177
- const m = yield i`eat(<*Keyword /b/i /> 'value')`;
178
- yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(m) === 'B')})`;
187
+ yield eatMatch(m`escapeToken: <*Punctuator '\\' />`);
188
+ const m_ = yield eat(m`value: <*Keyword /b/i />`);
189
+ yield defineAttribute('negate', buildBoolean(ctx.sourceTextFor(m_) === 'B'));
179
190
  }
180
191
 
181
192
  @CoveredBy('Assertion')
182
193
  @Node
183
194
  *Gap() {
184
- yield i`eatMatch(<*Punctuator '\\' /> 'escapeToken')`;
185
- yield i`eat(<*Keyword 'g' /> 'value')`;
195
+ yield eatMatch(m`escapeToken: <*Punctuator '\\' />`);
196
+ yield eat(m`value: <*Keyword 'g' />`);
186
197
  }
187
198
 
188
199
  @CoveredBy('Element')
189
200
  @CoveredBy('CharacterClassElement')
190
201
  @Node
191
202
  *Character() {
192
- if (yield i`match('\\')`) {
193
- yield i`eat(<@EscapeSequence /> null)`;
203
+ if (yield match('\\')) {
204
+ yield eat(m`@: <EscapeSequence />`);
194
205
  } else {
195
- yield i`eat(/[^\r\n\t]/)`;
206
+ yield eat(re`/[^\r\n\t]/`);
196
207
  }
197
208
  }
198
209
 
199
- @UnboundAttributes(['negate'])
210
+ @UndefinedAttributes(['negate'])
200
211
  @CoveredBy('Element')
201
212
  @Node
202
213
  *CharacterClass() {
203
- yield i`eat(<*Punctuator '[' balancedSpan='CharacterClass' balanced=']' /> 'openToken')`;
214
+ yield eat(m`openToken: <*Punctuator '[' { balancedSpan: 'CharacterClass', balanced: ']' } />`);
204
215
 
205
- let neg = yield i`eatMatch(<*Keyword '^' /> 'negateToken')`;
216
+ let negate = yield eatMatch(m`negateToken: <*Keyword '^' />`, null, o({ bind: true }));
206
217
 
207
- yield i`bindAttribute('negate' ${buildBoolean(neg)})`;
218
+ yield defineAttribute('negate', !!negate);
208
219
 
209
- while (yield i`match(/./s)`) {
210
- yield i`eat(<+CharacterClassElement /> 'elements[]$')`;
220
+ while (yield match(re`/./s`)) {
221
+ yield eat(m`elements[]+$: <__CharacterClassElement />`);
211
222
  }
212
223
 
213
- yield i`eat(<*Punctuator ']' balancer /> 'closeToken')`;
224
+ yield eat(m`closeToken: <*Punctuator ']' { balancer: true } />`);
214
225
  }
215
226
 
216
227
  *CharacterClassElement() {
217
- yield i`eat(<Any /> null [
218
- <CharacterSet /\\[dswp]/i />
219
- <Gap '\\g' />
220
- <*+Character />
221
- ])`;
222
-
223
- if (yield i`match('-')`) {
224
- return i`holdForMatch(<+CharacterClassRange />)`;
228
+ yield eat(m`<_Any />`, [
229
+ m`<__CharacterSet /\\[dswp]/i />`,
230
+ m`<Gap '\\g' />`,
231
+ m`<*Character />`,
232
+ ]);
233
+
234
+ if (yield match('-')) {
235
+ return holdForMatch(m`<CharacterClassRange />`);
225
236
  }
226
237
  }
227
238
 
228
239
  @CoveredBy('CharacterClassElement')
229
240
  @Node
230
241
  *CharacterClassRange() {
231
- yield i`eat(<*+Character /> 'min$')`;
232
- yield i`eat(<*Punctuator '-' /> 'sigilToken')`;
233
- yield i`eat(<*+Character /> 'max$')`;
242
+ yield eat(m`min+$: <*Character />`);
243
+ yield eat(m`sigilToken: <*Punctuator '-' />`);
244
+ yield eat(m`max+$: <*Character />`);
234
245
  }
235
246
 
236
247
  @CoveredBy('Element')
237
248
  *CharacterSet() {
238
- yield i`eat(<Any /> null [
239
- <+AnyCharacterSet '.' />
240
- <+DigitCharacterSet /\\[dD]/ />
241
- <+SpaceCharacterSet /\\[sS]/ />
242
- <+WordCharacterSet /\\[wW]/ />
243
- ])`;
249
+ yield eat(m`<_Any />`, [
250
+ m`<AnyCharacterSet '.' />`,
251
+ m`<DigitCharacterSet /\\[dD]/ />`,
252
+ m`<SpaceCharacterSet /\\[sS]/ />`,
253
+ m`<WordCharacterSet /\\[wW]/ />`,
254
+ ]);
244
255
  }
245
256
 
257
+ @CoveredBy('Element')
246
258
  @CoveredBy('CharacterSet')
247
259
  @Node
248
260
  *AnyCharacterSet() {
249
- yield i`eat(<*Keyword '.' /> 'sigilToken')`;
261
+ yield eat(m`sigilToken: <*Keyword '.' />`);
250
262
  }
251
263
 
252
- @UnboundAttributes(['negate'])
264
+ @UndefinedAttributes(['negate'])
265
+ @CoveredBy('Element')
253
266
  @CoveredBy('CharacterSet')
254
267
  @Node
255
268
  *DigitCharacterSet({ ctx }) {
256
- yield i`eat(<*Punctuator '\\' /> 'escapeToken')`;
269
+ yield eat(m`escapeToken: <*Punctuator '\\' />`);
257
270
 
258
- let code = yield i`eat(<*Keyword /[dD]/ /> 'value')`;
271
+ let code = yield eat(m`value: <*Keyword /[dD]/ />`);
259
272
 
260
- yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'D')})`;
273
+ yield defineAttribute('negate', ctx.sourceTextFor(code) === 'D');
261
274
  }
262
275
 
263
- @UnboundAttributes(['negate'])
276
+ @UndefinedAttributes(['negate'])
277
+ @CoveredBy('Element')
264
278
  @CoveredBy('CharacterSet')
265
279
  @Node
266
280
  *SpaceCharacterSet({ ctx }) {
267
- yield i`eat(<*Punctuator '\\' /> 'escapeToken')`;
281
+ yield eat(m`escapeToken: <*Punctuator '\\' />`);
268
282
 
269
- let code = yield i`eat(<*Keyword /[sS]/ /> 'value')`;
283
+ let code = yield eat(m`value: <*Keyword /[sS]/ />`);
270
284
 
271
- yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'S')})`;
285
+ yield defineAttribute('negate', ctx.sourceTextFor(code) === 'S');
272
286
  }
273
287
 
274
- @UnboundAttributes(['negate'])
288
+ @UndefinedAttributes(['negate'])
289
+ @CoveredBy('Element')
275
290
  @CoveredBy('CharacterSet')
276
291
  @Node
277
292
  *WordCharacterSet({ ctx }) {
278
- yield i`eat(<*Punctuator '\\' /> 'escapeToken')`;
293
+ yield eat(m`escapeToken: <*Punctuator '\\' />`);
279
294
 
280
- let code = yield i`eat(<*Keyword /[wW]/ /> 'value')`;
295
+ let code = yield eat(m`value: <*Keyword /[wW]/ />`);
281
296
 
282
- yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'W')})`;
297
+ yield defineAttribute('negate', ctx.sourceTextFor(code) === 'W');
283
298
  }
284
299
 
285
- @UnboundAttributes(['min', 'max'])
300
+ @UndefinedAttributes(['min', 'max'])
286
301
  @Node
287
302
  *Quantifier({ ctx }) {
288
- yield i`eat(<+Element /> 'element$')`;
303
+ yield eat(m`element+$: <__Element />`);
289
304
 
290
305
  let attrs, sigil;
291
306
 
292
- if ((sigil = yield i`eatMatch(<*Keyword /[*+?]/ /> 'sigilToken')`)) {
307
+ if ((sigil = yield eatMatch(m`sigilToken: <*Keyword /[*+?]/ />`))) {
293
308
  switch (ctx.sourceTextFor(sigil)) {
294
309
  case '*':
295
310
  attrs = { min: 0, max: Infinity };
@@ -301,12 +316,12 @@ export const grammar = class RegexGrammar {
301
316
  attrs = { min: 0, max: 1 };
302
317
  break;
303
318
  }
304
- } else if (yield i`eat(<*Punctuator '{' balanced='}' /> 'openToken')`) {
319
+ } else if (yield eat(m`openToken: <*Punctuator '{' { balanced: '}' } />`)) {
305
320
  let max;
306
- let min = yield i`eat(<*UnsignedInteger /> 'min$')`;
321
+ let min = yield eat(m`min$: <*UnsignedInteger />`);
307
322
 
308
- if (yield i`eatMatch(<*Punctuator ',' /> 'separator')`) {
309
- max = yield i`eatMatch(<*UnsignedInteger /> 'max$')`;
323
+ if (yield eatMatch(m`separator: <*Punctuator ',' />`)) {
324
+ max = yield eatMatch(m`max$: <*UnsignedInteger />`);
310
325
  }
311
326
 
312
327
  min = min && ctx.sourceTextFor(min);
@@ -317,74 +332,79 @@ export const grammar = class RegexGrammar {
317
332
 
318
333
  attrs = { min, max };
319
334
 
320
- yield i`eat(<*Punctuator '}' balancer /> 'closeToken')`;
335
+ yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
321
336
  }
322
337
 
323
- yield i`bindAttribute('min' ${attrs.min ? buildNumber(attrs.min) : buildNullTag()})`;
324
- yield i`bindAttribute('max' ${attrs.max ? buildNumber(attrs.max) : buildNullTag()})`;
338
+ yield defineAttribute('min', attrs.min);
339
+ yield defineAttribute('max', attrs.max);
325
340
  }
326
341
 
327
342
  @Node
328
343
  *UnsignedInteger() {
329
- yield i`eat(/\d+/)`;
344
+ yield eat(re`/\d+/`);
345
+ }
346
+
347
+ @Node
348
+ *UnsignedHexInteger() {
349
+ yield eat(re`/[\da-fA-F]+/`);
330
350
  }
331
351
 
332
352
  @Node
333
- *EscapeSequence({ state, ctx, value: props }) {
353
+ *EscapeSequence({ state, ctx }) {
334
354
  const parentSpan = state.span;
335
355
 
336
- yield i`eat(<*Punctuator '\\' openSpan='Escape' /> 'escape')`;
356
+ yield eat(m`escape: <*Punctuator '\\' { openSpan: 'Escape' } />`);
337
357
 
338
- let match;
358
+ let m_;
339
359
 
340
- if ((match = yield i`match(/[\\/nrt0]/)`)) {
341
- const match_ = ctx.sourceTextFor(match);
342
- yield i`eat(<*Keyword ${buildString(match_)} closeSpan='Escape' /> 'code')`;
343
- } else if (
344
- (match = yield i`match(${getSpecialPattern(parentSpan, ctx.reifyExpression(props))})`)
345
- ) {
346
- const match_ = ctx.sourceTextFor(match);
347
- yield i`eat(<*Keyword ${buildString(match_)} closeSpan='Escape' /> 'code')`;
348
- } else if (yield i`match(/[ux]/)`) {
349
- yield i`eat(<EscapeCode closeSpan='Escape' /> 'code')`;
360
+ if ((m_ = yield match(re`/[\\/nrt0]/`))) {
361
+ const match_ = ctx.sourceTextFor(m_);
362
+ yield eat(m`code: <*Keyword ${buildString(match_)} { closeSpan: 'Escape' } />`);
363
+ } else if ((m_ = yield match(getSpecialPattern(parentSpan)))) {
364
+ const match_ = ctx.sourceTextFor(m_);
365
+ yield eat(m`code: <*Keyword ${buildString(match_)} { closeSpan: 'Escape' } />`);
366
+ } else if (yield match(re`/[ux]/`)) {
367
+ yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
350
368
  } else {
351
- yield i`fail()`;
369
+ yield fail();
352
370
  }
353
371
  }
354
372
 
355
373
  @Node
356
374
  *EscapeCode() {
357
- if (yield i`eatMatch(<*Keyword 'u' /> 'type')`) {
358
- if (yield i`eatMatch(<*Punctuator '{' /> 'openToken')`) {
359
- yield i`eatMatch(<*UnsignedInteger /> 'value$')`;
360
- yield i`eat(<*Punctuator '}' /> 'closeToken')`;
375
+ if (yield eatMatch(m`type: <*Keyword 'u' />`)) {
376
+ if (yield eatMatch(m`openToken: <*Punctuator '{' />`)) {
377
+ yield eatMatch(m`value$: <*UnsignedHexInteger />`);
378
+ yield eat(m`closeToken: <*Punctuator '}' />`);
361
379
  } else {
362
- yield i`eat(<*UnsignedInteger /\d{4}/ /> 'value$')`;
363
- yield i`eat(null 'closeToken')`;
380
+ yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{4}/ />`);
381
+ yield eat(m`closeToken: null`);
364
382
  }
365
- } else if (yield i`eatMatch(<*Keyword 'x' /> 'type')`) {
366
- yield i`eat(null 'openToken')`;
367
- yield i`eat(<*UnsignedInteger /\d{2}/ /> 'value$')`;
368
- yield i`eat(null 'closeToken')`;
383
+ } else if (yield eatMatch(m`type: <*Keyword 'x' />`)) {
384
+ yield eat(m`openToken: null`);
385
+ yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{2}/ />`);
386
+ yield eat(m`closeToken: null`);
369
387
  }
370
388
  }
371
389
 
372
390
  *Digits() {
373
- while (yield i`eatMatch(<*Digit />)`);
391
+ while (yield eatMatch(m`<*Digit />`));
374
392
  }
375
393
 
376
394
  @Node
377
395
  *Digit() {
378
- yield i`eat(/\d/)`;
396
+ yield eat(re`/\d/`);
379
397
  }
380
398
 
381
399
  @InjectFrom(Shared)
382
400
  *Any() {}
383
401
 
402
+ @Literal
384
403
  @Node
385
404
  @InjectFrom(Shared)
386
405
  *Keyword() {}
387
406
 
407
+ @Literal
388
408
  @Node
389
409
  @InjectFrom(Shared)
390
410
  *Punctuator() {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/language-en-regex-vm-pattern",
3
- "version": "0.7.1",
3
+ "version": "0.9.0",
4
4
  "description": "A BABLR language for nonbacktracking JS-style regexes",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -10,7 +10,9 @@
10
10
  ".": "./lib/grammar.js",
11
11
  "./package.json": "./package.json"
12
12
  },
13
- "files": ["lib/**/*.js"],
13
+ "files": [
14
+ "lib/**/*.js"
15
+ ],
14
16
  "sideEffects": false,
15
17
  "scripts": {
16
18
  "build": "macrome build",
@@ -20,18 +22,18 @@
20
22
  },
21
23
  "dependencies": {
22
24
  "@babel/runtime": "^7.23.2",
23
- "@bablr/helpers": "^0.20.0",
24
- "@bablr/agast-helpers": "^0.5.0",
25
- "@bablr/agast-vm-helpers": "^0.5.0",
26
- "iter-tools-es": "^7.5.3"
25
+ "@bablr/boot": "0.8.1",
26
+ "@bablr/helpers": "0.22.1",
27
+ "@bablr/agast-helpers": "0.7.1",
28
+ "@bablr/agast-vm-helpers": "0.7.1",
29
+ "iter-tools-es": "7.5.3"
27
30
  },
28
31
  "devDependencies": {
29
- "@bablr/boot": "^0.6.0",
30
32
  "@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
31
33
  "@bablr/macrome": "^0.1.3",
32
34
  "@bablr/macrome-generator-bablr": "^0.3.2",
33
35
  "@qnighy/dedent": "0.1.1",
34
- "bablr": "^0.6.0",
36
+ "bablr": "^0.7.0",
35
37
  "enhanced-resolve": "^5.12.0",
36
38
  "eslint": "^8.47.0",
37
39
  "eslint-import-resolver-enhanced-resolve": "^1.0.5",
@@ -40,7 +42,12 @@
40
42
  "mocha": "^10.4.0",
41
43
  "prettier": "^2.0.5"
42
44
  },
43
- "keywords": ["bablr-language", "grammar", "english", "regex"],
45
+ "keywords": [
46
+ "bablr-language",
47
+ "grammar",
48
+ "english",
49
+ "regex"
50
+ ],
44
51
  "repository": "git@github.com:bablr-lang/language-en-regex-vm-pattern.git",
45
52
  "homepage": "https://github.com/bablr-lang/language-en-regex-vm-pattern",
46
53
  "author": "Conrad Buck <conartist6@gmail.com>",