@bablr/language-en-regex-vm-pattern 0.5.0 → 0.6.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.
@@ -2,7 +2,7 @@ import { i, re } from '@bablr/boot/shorthand.macro';
2
2
  import { Node, CoveredBy, InjectFrom, Attributes, AllowEmpty } from '@bablr/helpers/decorators';
3
3
  import objectEntries from 'iter-tools-es/methods/object-entries';
4
4
  import * as Shared from '@bablr/helpers/productions';
5
- import { buildString, buildBoolean, buildNumber, buildNull } from '@bablr/agast-vm-helpers';
5
+ import { buildString, buildBoolean, buildNumber, buildNullTag } from '@bablr/agast-vm-helpers';
6
6
 
7
7
  export const canonicalURL = 'https://bablr.org/languages/core/en/bablr-regex-pattern';
8
8
 
@@ -30,7 +30,7 @@ const unique = (flags) => flags.length === new Set(flags).size;
30
30
 
31
31
  const getSpecialPattern = (span) => {
32
32
  if (span === 'Pattern') {
33
- return re`/[*+{}[\]().^$|\n\\]/`;
33
+ return re`/[*+{}[\]().^$|\n\\<>]/`;
34
34
  } else if (span === 'CharacterClass') {
35
35
  return re`/[\]\\]/`;
36
36
  } else {
@@ -41,10 +41,10 @@ const getSpecialPattern = (span) => {
41
41
  export const grammar = class RegexGrammar {
42
42
  @Node
43
43
  *Pattern() {
44
- yield i`eat(<~*Punctuator '/' balanced='/' balancedSpan='Pattern'> 'openToken')`;
45
- yield i`eat(<Alternatives>)`;
46
- yield i`eat(<~*Punctuator '/' balancer> 'closeToken')`;
47
- yield i`eat(<Flags> 'flags')`;
44
+ yield i`eat(<~*Punctuator '/' balanced='/' balancedSpan='Pattern' /> 'openToken')`;
45
+ yield i`eat(<Alternatives />)`;
46
+ yield i`eat(<~*Punctuator '/' balancer /> 'closeToken')`;
47
+ yield i`eat(<Flags /> 'flags')`;
48
48
  }
49
49
 
50
50
  @Attributes(Object.keys(flagCharacters))
@@ -66,21 +66,21 @@ export const grammar = class RegexGrammar {
66
66
  }
67
67
 
68
68
  for (const flagChr of flagsStr) {
69
- yield i`eat(<*Keyword ${buildString(flagChr)}> 'tokens[]')`;
69
+ yield i`eat(<*Keyword ${buildString(flagChr)} /> 'tokens[]')`;
70
70
  }
71
71
  }
72
72
 
73
73
  @AllowEmpty
74
74
  *Alternatives() {
75
75
  do {
76
- yield i`eat(<Alternative> 'alternatives[]')`;
77
- } while (yield i`eatMatch(<~*Punctuator '|'> 'separators[]')`);
76
+ yield i`eat(<Alternative /> 'alternatives[]')`;
77
+ } while (yield i`eatMatch(<~*Punctuator '|' /> 'separators[]')`);
78
78
  }
79
79
 
80
80
  @AllowEmpty
81
81
  @Node
82
82
  *Alternative() {
83
- yield i`eat(<Elements>)`;
83
+ yield i`eat(<Elements />)`;
84
84
  }
85
85
 
86
86
  @AllowEmpty
@@ -88,78 +88,78 @@ export const grammar = class RegexGrammar {
88
88
  let matched = false;
89
89
  while (yield i`match(/[^|]/)`) {
90
90
  matched = true;
91
- yield i`eat(<+Element> 'elements[]')`;
91
+ yield i`eat(<+Element /> 'elements[]')`;
92
92
  }
93
93
  if (!matched) yield i`eat(null 'elements[]')`;
94
94
  }
95
95
 
96
96
  *Element() {
97
- yield i`guard(<~*Keyword /[*+?]/>)`;
98
-
99
- yield i`eat(<Any> null [
100
- <+CharacterClass '['>
101
- <+Group '(?:'>
102
- <+Assertion /[$^]|\\b/i>
103
- <+Gap '\\g'>
104
- <+CharacterSet /\.|\\[dswp]/i>
105
- <*+Character>
97
+ yield i`guard(<~*Keyword /[*+?]/ />)`;
98
+
99
+ yield i`eat(<Any /> null [
100
+ <+CharacterClass '[' />
101
+ <+Group '(?:' />
102
+ <+Assertion /[$^]|\\b/i />
103
+ <+Gap '\\g' />
104
+ <+CharacterSet /\.|\\[dswp]/i />
105
+ <*+Character />
106
106
  ])`;
107
107
 
108
108
  if (yield i`match(/[*+?{]/)`) {
109
- return i`holdForMatch(<Quantifier>)`;
109
+ return i`holdForMatch(<Quantifier />)`;
110
110
  }
111
111
  }
112
112
 
113
113
  @CoveredBy('Element')
114
114
  @Node
115
115
  *Group() {
116
- yield i`eat(<~*Punctuator '(?:' balanced=')'> 'openToken')`;
117
- yield i`eat(<Alternatives>)`;
118
- yield i`eat(<~*Punctuator ')' balancer> 'closeToken')`;
116
+ yield i`eat(<~*Punctuator '(?:' balanced=')' /> 'openToken')`;
117
+ yield i`eat(<Alternatives />)`;
118
+ yield i`eat(<~*Punctuator ')' balancer /> 'closeToken')`;
119
119
  }
120
120
 
121
121
  @Node
122
122
  *CapturingGroup() {
123
- yield i`eat(<~*Punctuator '(' balanced=')'> 'openToken')`;
124
- yield i`eat(<Alternatives>)`;
125
- yield i`eat(<~*Punctuator ')' balancer> 'closeToken')`;
123
+ yield i`eat(<~*Punctuator '(' balanced=')' /> 'openToken')`;
124
+ yield i`eat(<Alternatives />)`;
125
+ yield i`eat(<~*Punctuator ')' balancer /> 'closeToken')`;
126
126
  }
127
127
 
128
128
  @CoveredBy('Element')
129
129
  *Assertion() {
130
- yield i`eat(<Any> null [
131
- <*StartOfInputAssertion '^'>
132
- <*EndOfInputAssertion '$'>
133
- <*@WordBoundaryAssertion /\\b/i>
130
+ yield i`eat(<Any /> null [
131
+ <*StartOfInputAssertion '^' />
132
+ <*EndOfInputAssertion '$' />
133
+ <*@WordBoundaryAssertion /\\b/i />
134
134
  ])`;
135
135
  }
136
136
 
137
137
  @CoveredBy('Assertion')
138
138
  @Node
139
139
  *StartOfInputAssertion() {
140
- yield i`eat(<~*Keyword '^'> 'sigilToken')`;
140
+ yield i`eat(<~*Keyword '^' /> 'sigilToken')`;
141
141
  }
142
142
 
143
143
  @CoveredBy('Assertion')
144
144
  @Node
145
145
  *EndOfInputAssertion() {
146
- yield i`eatMatch(<~*Keyword '$'> 'sigilToken')`;
146
+ yield i`eatMatch(<~*Keyword '$' /> 'sigilToken')`;
147
147
  }
148
148
 
149
149
  @Attributes(['negate'])
150
150
  @CoveredBy('Assertion')
151
151
  @Node
152
152
  *WordBoundaryAssertion({ ctx }) {
153
- yield i`eatMatch(<~*Punctuator '\\'> 'escapeToken')`;
154
- const m = yield i`eat(<~*Keyword /b/i> 'value')`;
153
+ yield i`eatMatch(<~*Punctuator '\\' /> 'escapeToken')`;
154
+ const m = yield i`eat(<~*Keyword /b/i /> 'value')`;
155
155
  yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(m) === 'B')})`;
156
156
  }
157
157
 
158
158
  @CoveredBy('Assertion')
159
159
  @Node
160
160
  *Gap() {
161
- yield i`eatMatch(<~*Punctuator '\\'> 'escapeToken')`;
162
- yield i`eat(<~*Keyword 'g'> 'value')`;
161
+ yield i`eatMatch(<~*Punctuator '\\' /> 'escapeToken')`;
162
+ yield i`eat(<~*Keyword 'g' /> 'value')`;
163
163
  }
164
164
 
165
165
  @CoveredBy('Element')
@@ -167,7 +167,7 @@ export const grammar = class RegexGrammar {
167
167
  @Node
168
168
  *Character() {
169
169
  if (yield i`match('\\')`) {
170
- yield i`eat(<@EscapeSequence> null)`;
170
+ yield i`eat(<@EscapeSequence /> null)`;
171
171
  } else {
172
172
  yield i`eat(/[^\r\n\t]/)`;
173
173
  }
@@ -177,62 +177,62 @@ export const grammar = class RegexGrammar {
177
177
  @CoveredBy('Element')
178
178
  @Node
179
179
  *CharacterClass() {
180
- yield i`eat(<~*Punctuator '[' balancedSpan='CharacterClass' balanced=']'> 'openToken')`;
180
+ yield i`eat(<~*Punctuator '[' balancedSpan='CharacterClass' balanced=']' /> 'openToken')`;
181
181
 
182
- let neg = yield i`eatMatch(<~*Keyword '^'> 'negateToken')`;
182
+ let neg = yield i`eatMatch(<~*Keyword '^' /> 'negateToken')`;
183
183
 
184
184
  yield i`bindAttribute('negate' ${buildBoolean(neg)})`;
185
185
 
186
186
  while (yield i`match(/./s)`) {
187
- yield i`eat(<+CharacterClassElement> 'elements[]')`;
187
+ yield i`eat(<+CharacterClassElement /> 'elements[]')`;
188
188
  }
189
189
 
190
- yield i`eat(<~*Punctuator ']' balancer> 'closeToken')`;
190
+ yield i`eat(<~*Punctuator ']' balancer /> 'closeToken')`;
191
191
  }
192
192
 
193
193
  *CharacterClassElement() {
194
- yield i`eat(<Any> null [
195
- <CharacterSet /\\[dswp]/i>
196
- <Gap '\\g'>
197
- <*+Character>
194
+ yield i`eat(<Any /> null [
195
+ <CharacterSet /\\[dswp]/i />
196
+ <Gap '\\g' />
197
+ <*+Character />
198
198
  ])`;
199
199
 
200
200
  if (yield i`match('-')`) {
201
- return i`holdForMatch(<+CharacterClassRange>)`;
201
+ return i`holdForMatch(<+CharacterClassRange />)`;
202
202
  }
203
203
  }
204
204
 
205
205
  @CoveredBy('CharacterClassElement')
206
206
  @Node
207
207
  *CharacterClassRange() {
208
- yield i`eat(<*+Character> 'min')`;
209
- yield i`eat(<~*Punctuator '-'> 'sigilToken')`;
210
- yield i`eat(<*+Character> 'max')`;
208
+ yield i`eat(<*+Character /> 'min')`;
209
+ yield i`eat(<~*Punctuator '-' /> 'sigilToken')`;
210
+ yield i`eat(<*+Character /> 'max')`;
211
211
  }
212
212
 
213
213
  @CoveredBy('Element')
214
214
  *CharacterSet() {
215
- yield i`eat(<Any> null [
216
- <+AnyCharacterSet '.'>
217
- <+DigitCharacterSet /\\[dD]/>
218
- <+SpaceCharacterSet /\\[sS]/>
219
- <+WordCharacterSet /\\[wW]/>
215
+ yield i`eat(<Any /> null [
216
+ <+AnyCharacterSet '.' />
217
+ <+DigitCharacterSet /\\[dD]/ />
218
+ <+SpaceCharacterSet /\\[sS]/ />
219
+ <+WordCharacterSet /\\[wW]/ />
220
220
  ])`;
221
221
  }
222
222
 
223
223
  @CoveredBy('CharacterSet')
224
224
  @Node
225
225
  *AnyCharacterSet() {
226
- yield i`eat(<~*Keyword '.'> 'sigilToken')`;
226
+ yield i`eat(<~*Keyword '.' /> 'sigilToken')`;
227
227
  }
228
228
 
229
229
  @Attributes(['negate'])
230
230
  @CoveredBy('CharacterSet')
231
231
  @Node
232
232
  *DigitCharacterSet({ ctx }) {
233
- yield i`eat(<~*Punctuator '\\'> 'escapeToken')`;
233
+ yield i`eat(<~*Punctuator '\\' /> 'escapeToken')`;
234
234
 
235
- let code = yield i`eat(<~*Keyword /[dD]/> 'value')`;
235
+ let code = yield i`eat(<~*Keyword /[dD]/ /> 'value')`;
236
236
 
237
237
  yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'D')})`;
238
238
  }
@@ -241,9 +241,9 @@ export const grammar = class RegexGrammar {
241
241
  @CoveredBy('CharacterSet')
242
242
  @Node
243
243
  *SpaceCharacterSet({ ctx }) {
244
- yield i`eat(<~*Punctuator '\\'> 'escapeToken')`;
244
+ yield i`eat(<~*Punctuator '\\' /> 'escapeToken')`;
245
245
 
246
- let code = yield i`eat(<~*Keyword /[sS]/> 'value')`;
246
+ let code = yield i`eat(<~*Keyword /[sS]/ /> 'value')`;
247
247
 
248
248
  yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'S')})`;
249
249
  }
@@ -252,9 +252,9 @@ export const grammar = class RegexGrammar {
252
252
  @CoveredBy('CharacterSet')
253
253
  @Node
254
254
  *WordCharacterSet({ ctx }) {
255
- yield i`eat(<~*Punctuator '\\'> 'escapeToken')`;
255
+ yield i`eat(<~*Punctuator '\\' /> 'escapeToken')`;
256
256
 
257
- let code = yield i`eat(<~*Keyword /[wW]/> 'value')`;
257
+ let code = yield i`eat(<~*Keyword /[wW]/ /> 'value')`;
258
258
 
259
259
  yield i`bindAttribute('negate' ${buildBoolean(ctx.sourceTextFor(code) === 'W')})`;
260
260
  }
@@ -262,11 +262,11 @@ export const grammar = class RegexGrammar {
262
262
  @Attributes(['min', 'max'])
263
263
  @Node
264
264
  *Quantifier({ ctx }) {
265
- yield i`eat(<+Element> 'element')`;
265
+ yield i`eat(<+Element /> 'element')`;
266
266
 
267
267
  let attrs, sigil;
268
268
 
269
- if ((sigil = yield i`eatMatch(<~*Keyword /[*+?]/> 'sigilToken')`)) {
269
+ if ((sigil = yield i`eatMatch(<~*Keyword /[*+?]/ /> 'sigilToken')`)) {
270
270
  switch (ctx.sourceTextFor(sigil)) {
271
271
  case '*':
272
272
  attrs = { min: 0, max: Infinity };
@@ -278,12 +278,12 @@ export const grammar = class RegexGrammar {
278
278
  attrs = { min: 0, max: 1 };
279
279
  break;
280
280
  }
281
- } else if (yield i`eat(<~*Punctuator '{' balanced='}'> 'openToken')`) {
281
+ } else if (yield i`eat(<~*Punctuator '{' balanced='}' /> 'openToken')`) {
282
282
  let max;
283
- let min = yield i`eat(<*UnsignedInteger> 'min')`;
283
+ let min = yield i`eat(<*UnsignedInteger /> 'min')`;
284
284
 
285
- if (yield i`eatMatch(<~*Punctuator ','> 'separator')`) {
286
- max = yield i`eatMatch(<*UnsignedInteger> 'max')`;
285
+ if (yield i`eatMatch(<~*Punctuator ',' /> 'separator')`) {
286
+ max = yield i`eatMatch(<*UnsignedInteger /> 'max')`;
287
287
  }
288
288
 
289
289
  min = min && ctx.sourceTextFor(min);
@@ -294,11 +294,11 @@ export const grammar = class RegexGrammar {
294
294
 
295
295
  attrs = { min, max };
296
296
 
297
- yield i`eat(<~*Punctuator '}' balancer> 'closeToken')`;
297
+ yield i`eat(<~*Punctuator '}' balancer /> 'closeToken')`;
298
298
  }
299
299
 
300
- yield i`bindAttribute('min' ${attrs.min ? buildNumber(attrs.min) : buildNull()})`;
301
- yield i`bindAttribute('max' ${attrs.max ? buildNumber(attrs.max) : buildNull()})`;
300
+ yield i`bindAttribute('min' ${attrs.min ? buildNumber(attrs.min) : buildNullTag()})`;
301
+ yield i`bindAttribute('max' ${attrs.max ? buildNumber(attrs.max) : buildNullTag()})`;
302
302
  }
303
303
 
304
304
  @Node
@@ -311,22 +311,22 @@ export const grammar = class RegexGrammar {
311
311
  *EscapeSequence({ state, ctx, value: props }) {
312
312
  const parentSpan = state.span;
313
313
 
314
- yield i`eat(<~*Punctuator '\\' openSpan='Escape'> 'escape')`;
314
+ yield i`eat(<~*Punctuator '\\' openSpan='Escape' /> 'escape')`;
315
315
 
316
316
  let match, cooked;
317
317
 
318
318
  if ((match = yield i`match(/[\\/nrt0]/)`)) {
319
319
  const match_ = ctx.sourceTextFor(match);
320
- yield i`eat(<~*Keyword ${buildString(match_)} closeSpan='Escape'> 'value')`;
320
+ yield i`eat(<~*Keyword ${buildString(match_)} closeSpan='Escape' /> 'value')`;
321
321
  cooked = escapables.get(match_) || match_;
322
322
  } else if (
323
323
  (match = yield i`match(${getSpecialPattern(parentSpan, ctx.reifyExpression(props))})`)
324
324
  ) {
325
325
  const match_ = ctx.sourceTextFor(match);
326
- yield i`eat(<~*Keyword ${buildString(match_)} closeSpan='Escape'> 'value')`;
326
+ yield i`eat(<~*Keyword ${buildString(match_)} closeSpan='Escape' /> 'value')`;
327
327
  cooked = ctx.sourceTextFor(match);
328
328
  } else if (yield i`match(/[ux]/)`) {
329
- const codeNode = yield i`eat(<EscapeCode closeSpan='Escape'> 'value')`;
329
+ const codeNode = yield i`eat(<EscapeCode closeSpan='Escape' /> 'value')`;
330
330
  cooked = parseInt(
331
331
  codeNode.properties.digits.map((digit) => ctx.sourceTextFor(digit)).join(''),
332
332
  16,
@@ -340,23 +340,23 @@ export const grammar = class RegexGrammar {
340
340
 
341
341
  @Node
342
342
  *EscapeCode() {
343
- if (yield i`eatMatch(<~*Keyword 'u'> 'type')`) {
344
- if (yield i`eatMatch(<~*Punctuator '{'> 'openToken')`) {
345
- yield i`eatMatch(<Digits> 'value')`;
346
- yield i`eat(<~*Punctuator '}'> 'closeToken')`;
343
+ if (yield i`eatMatch(<~*Keyword 'u' /> 'type')`) {
344
+ if (yield i`eatMatch(<~*Punctuator '{' /> 'openToken')`) {
345
+ yield i`eatMatch(<Digits /> 'value')`;
346
+ yield i`eat(<~*Punctuator '}' /> 'closeToken')`;
347
347
  } else {
348
- yield i`eat(<Digits /\d{4}/> 'value')`;
348
+ yield i`eat(<Digits /\d{4}/ /> 'value')`;
349
349
  yield i`eat(null 'closeToken')`;
350
350
  }
351
- } else if (yield i`eatMatch(<~*Keyword 'x'> 'type')`) {
351
+ } else if (yield i`eatMatch(<~*Keyword 'x' /> 'type')`) {
352
352
  yield i`eat(null 'openToken')`;
353
- yield i`eat(<Digits /\d{2}/> 'value')`;
353
+ yield i`eat(<Digits /\d{2}/ /> 'value')`;
354
354
  yield i`eat(null 'closeToken')`;
355
355
  }
356
356
  }
357
357
 
358
358
  *Digits() {
359
- while (yield i`eatMatch(<*Digit>)`);
359
+ while (yield i`eatMatch(<*Digit />)`);
360
360
  }
361
361
 
362
362
  @Node
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bablr/language-en-regex-vm-pattern",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "A BABLR language for nonbacktracking JS-style regexes",
5
5
  "engines": {
6
6
  "node": ">=12.0.0"
@@ -22,18 +22,18 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@babel/runtime": "^7.23.2",
25
- "@bablr/helpers": "0.18.0",
26
- "@bablr/agast-vm-helpers": "0.3.0",
25
+ "@bablr/helpers": "0.19.0",
26
+ "@bablr/agast-helpers": "0.4.0",
27
+ "@bablr/agast-vm-helpers": "0.4.0",
27
28
  "iter-tools-es": "^7.5.3"
28
29
  },
29
30
  "devDependencies": {
30
- "@bablr/agast-helpers": "0.3.1",
31
- "@bablr/boot": "0.4.0",
31
+ "@bablr/boot": "0.5.0",
32
32
  "@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
33
33
  "@bablr/macrome": "0.1.3",
34
- "@bablr/macrome-generator-bablr": "0.3.1",
34
+ "@bablr/macrome-generator-bablr": "0.3.2",
35
35
  "@qnighy/dedent": "0.1.1",
36
- "bablr": "0.4.0",
36
+ "bablr": "^0.5.0",
37
37
  "enhanced-resolve": "^5.12.0",
38
38
  "eslint": "^8.47.0",
39
39
  "eslint-import-resolver-enhanced-resolve": "^1.0.5",