@bablr/helpers 0.25.3 → 0.25.5

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/builders.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { re } from '@bablr/boot';
1
2
  import { interpolateFragment, buildFilledGapFunction } from '@bablr/agast-helpers/template';
2
3
  import { get, isEmpty, treeFromStreamSync as treeFromStream } from '@bablr/agast-helpers/tree';
3
4
  import { buildLiteralTag as agastBuildLiteralTag } from '@bablr/agast-helpers/builders';
@@ -5,7 +6,7 @@ import * as t from '@bablr/agast-helpers/shorthand';
5
6
  import * as Tags from '@bablr/agast-helpers/tags';
6
7
  import * as l from '@bablr/agast-vm-helpers/languages';
7
8
  import { concat } from '@bablr/agast-vm-helpers/iterable';
8
- import { buildNullNode } from '@bablr/agast-helpers/path';
9
+ import { buildNullNode, getRoot } from '@bablr/agast-helpers/path';
9
10
 
10
11
  const { freeze } = Object;
11
12
  const { isArray } = Array;
@@ -1115,3 +1116,37 @@ export const buildRegexString = (content) => {
1115
1116
  export const buildGapNodeMatcher = () => {
1116
1117
  return buildToken('GapNodeMatcher', '<//>');
1117
1118
  };
1119
+
1120
+ // problem: the concrete syntax is only right in some contexts (spans)
1121
+ const escaped = {
1122
+ '\\': re.Character`\\`,
1123
+ '/': re.Character`\/`,
1124
+ '(': re.Character`\(`,
1125
+ ')': re.Character`\)`,
1126
+ '[': re.Character`\[`,
1127
+ ']': re.Character`\]`,
1128
+ '{': re.Character`\{`,
1129
+ '}': re.Character`\}`,
1130
+ '+': re.Character`\+`,
1131
+ '*': re.Character`\*`,
1132
+ '<': re.Character`\<`,
1133
+ '>': re.Character`\>`,
1134
+ '^': re.Character`\^`,
1135
+ '|': re.Character`\|`,
1136
+ };
1137
+
1138
+ export const buildLiteralElements = (chrs) => {
1139
+ return buildElements(
1140
+ [...chrs].map((chr) => {
1141
+ if ('\\/(){}[]+*^$?|<>'.includes(chr)) {
1142
+ return getRoot(escaped[chr]);
1143
+ } else {
1144
+ return getRoot(
1145
+ re.Character({
1146
+ raw: [chr],
1147
+ }),
1148
+ );
1149
+ }
1150
+ }),
1151
+ );
1152
+ };
package/lib/grammar.js CHANGED
@@ -135,7 +135,7 @@ const __buildDependentLanguages = (language, languages = new Map()) => {
135
135
  languages.has(dependentLanguage.canonicalURL) &&
136
136
  languages.get(dependentLanguage.canonicalURL) !== dependentLanguage
137
137
  ) {
138
- throw new Error('url clash');
138
+ throw new Error('url clash: ' + dependentLanguage.canonicalURL);
139
139
  }
140
140
 
141
141
  __buildDependentLanguages(dependentLanguage, languages);
@@ -368,6 +368,10 @@ export const startSpan = (name, guard, props = {}) => {
368
368
  return __buildCall('startSpan', name, guard, o(props));
369
369
  };
370
370
 
371
+ export const startSubspan = (name, guard, props = {}) => {
372
+ return __buildCall('startSubspan', name, guard, o(props));
373
+ };
374
+
371
375
  export const endSpan = () => {
372
376
  return __buildCall('endSpan');
373
377
  };
package/lib/trivia.js CHANGED
@@ -23,11 +23,11 @@ import {
23
23
  import { reifyExpression } from '@bablr/agast-vm-helpers';
24
24
 
25
25
  export const triviaEnhancer = (
26
- { triviaIsAllowed, triviaIsRequired = () => false, triviaMatcher },
26
+ { triviaIsAllowed, triviaIsRequired = () => false, triviaMatcher, Trivia },
27
27
  grammar,
28
28
  ) => {
29
- let Trivia_ = 'Trivia';
30
- let Literal_ = 'Literal';
29
+ let Trivia_ = 'Trivia_';
30
+ let Literal_ = 'Literal_';
31
31
 
32
32
  while (grammar.prototype[Trivia_]) Trivia_ += '_';
33
33
  while (grammar.prototype[Literal_]) Literal_ += '_';
@@ -35,9 +35,13 @@ export const triviaEnhancer = (
35
35
  let tmi = eatMatch(triviaMatcher);
36
36
  let literalMatcher = get(['nodeMatcher', 'open', 'literalValue'], triviaMatcher.value);
37
37
 
38
+ function* DefaultTrivia() {
39
+ yield tmi;
40
+ }
41
+
38
42
  let resultGrammar = mapProductions((production) => {
39
43
  return function* (props) {
40
- let co = new Coroutine(production(props));
44
+ let co = new Coroutine(production.call(this, props));
41
45
  let outerProps = props;
42
46
  let { type, getState, s, flags, isCover, isCoverBoundary: thisIsCoverBoundary } = props;
43
47
  let isRootFragment = type === Symbol.for('__') && !s().depths.path;
@@ -62,6 +66,7 @@ export const triviaEnhancer = (
62
66
  case 'guard': {
63
67
  let { 0: matcher, 1: props, 2: options } = args;
64
68
  let s = getState();
69
+ let isShift = verb === 'shiftMatch';
65
70
 
66
71
  let isCoverBoundary = co.done
67
72
  ? thisIsCoverBoundary
@@ -72,7 +77,7 @@ export const triviaEnhancer = (
72
77
  !isCover);
73
78
 
74
79
  if (matcher.type === Regex || typeof matcher === 'string') {
75
- if (triviaIsAllowed(s) && !flags.token) {
80
+ if (triviaIsAllowed(s, matcher, props) && !flags.token) {
76
81
  if (literalMatcher) {
77
82
  let literalResult = yield buildCall(
78
83
  'match',
@@ -104,6 +109,7 @@ export const triviaEnhancer = (
104
109
  matchTrailing: false,
105
110
  }),
106
111
  o({
112
+ allowEmpty: true,
107
113
  suppressGap: true,
108
114
  }),
109
115
  );
@@ -121,8 +127,8 @@ export const triviaEnhancer = (
121
127
  getCooked(get(['refMatcher', 'type'], matcher.value)) !== '#')
122
128
  ) {
123
129
  if (
124
- triviaIsAllowed(s) &&
125
- !(getState().holding || co.done) &&
130
+ triviaIsAllowed(s, matcher, props) &&
131
+ !(getState().holding || co.done || isShift) &&
126
132
  get(['valueMatcher', 'nodeMatcher'], matcher.value).value.name?.description ===
127
133
  'TreeNodeMatcher'
128
134
  ) {
@@ -162,9 +168,11 @@ export const triviaEnhancer = (
162
168
  o({
163
169
  matcher,
164
170
  props,
165
- matchTrailing: isRootFragment,
166
171
  }),
167
- ...(options ? [options] : []),
172
+ o({
173
+ suppressGap: true,
174
+ ...options?.value,
175
+ }),
168
176
  );
169
177
  }
170
178
  }
@@ -225,7 +233,11 @@ export const triviaEnhancer = (
225
233
  return grammar;
226
234
  }
227
235
 
228
- *[Trivia_]({ props: { matchTrailing, matcher, props, options } }) {
236
+ Trivia(args) {
237
+ return Trivia ? Trivia(args) : DefaultTrivia(args);
238
+ }
239
+
240
+ *[Trivia_]({ props: { matcher, props, options } }) {
229
241
  yield tmi;
230
242
  let returnValue = yield eat(
231
243
  // TODO fixme binding tag
@@ -240,9 +252,8 @@ export const triviaEnhancer = (
240
252
  props,
241
253
  buildEmbeddedObject({ ...(options?.value || {}), shift: false }),
242
254
  );
243
- if (matchTrailing || returnValue.value?.shift) {
244
- yield tmi;
245
- }
255
+ yield tmi;
256
+
246
257
  return returnValue.value;
247
258
  }
248
259
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bablr/helpers",
3
3
  "description": "Command helpers for use in writing BABLR grammars",
4
- "version": "0.25.3",
4
+ "version": "0.25.5",
5
5
  "author": "Conrad Buck<conartist6@gmail.com>",
6
6
  "type": "module",
7
7
  "files": [
@@ -24,12 +24,12 @@
24
24
  },
25
25
  "sideEffects": false,
26
26
  "dependencies": {
27
- "@bablr/language_enhancer-debug-log": "0.12.3",
28
- "@bablr/strategy_enhancer-debug-log": "0.11.2",
27
+ "@bablr/language_enhancer-debug-log": "0.12.4",
28
+ "@bablr/strategy_enhancer-debug-log": "0.11.3",
29
29
  "@bablr/stream-iterator": "2.0.0",
30
- "@bablr/agast-helpers": "0.10.4",
31
- "@bablr/agast-vm-helpers": "0.10.4",
32
- "@bablr/boot": "0.11.3",
30
+ "@bablr/agast-helpers": "0.10.10",
31
+ "@bablr/agast-vm-helpers": "0.10.5",
32
+ "@bablr/boot": "0.11.4",
33
33
  "@bablr/coroutine": "0.1.0",
34
34
  "iter-tools-es": "^7.5.3"
35
35
  },