@bablr/boot 0.3.0 → 0.5.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.
@@ -1,7 +1,7 @@
1
1
  const objectEntries = require('iter-tools/methods/object-entries');
2
2
 
3
3
  const { buildCovers } = require('../utils.js');
4
- const sym = require('../symbols.js');
4
+ const sym = require('@bablr/boot-helpers/symbols');
5
5
 
6
6
  const _ = /\s+/y;
7
7
  const PN = 'Punctuator';
@@ -62,15 +62,15 @@ const covers = buildCovers({
62
62
  'DoctypeTag',
63
63
  'Attribute',
64
64
  'Property',
65
- 'Reference',
65
+ 'ReferenceTag',
66
66
  'TagType',
67
- 'Null',
68
- 'Gap',
67
+ 'NullTag',
68
+ 'GapTag',
69
69
  'Node',
70
70
  'IdentifierPath',
71
71
  'OpenNodeTag',
72
72
  'CloseNodeTag',
73
- 'Terminal',
73
+ 'Tag',
74
74
  'Number',
75
75
  'Digit',
76
76
  'String',
@@ -82,9 +82,9 @@ const covers = buildCovers({
82
82
  Attribute: ['MappingAttribute', 'BooleanAttribute'],
83
83
  AttributeValue: ['String', 'Number'],
84
84
  TagType: ['Identifier', 'GlobalIdentifier'],
85
- Terminal: ['Literal', 'Trivia'],
86
- PropertyValue: ['Gap', 'Node', 'Null'],
87
- EmbeddedTerminal: ['Literal'],
85
+ Tag: ['LiteralTag', 'Trivia'],
86
+ PropertyValue: ['GapTag', 'Node', 'NullTag'],
87
+ EmbeddedTag: ['LiteralTag'],
88
88
  Number: ['Integer', 'Infinity'],
89
89
  });
90
90
 
@@ -92,6 +92,7 @@ const grammar = class CSTMLMiniparserGrammar {
92
92
  // @Node
93
93
  Document(p) {
94
94
  p.eatProduction('DoctypeTag', { path: 'doctype' });
95
+ p.eatMatchTrivia(_);
95
96
  p.eatProduction('Node', { path: 'tree' });
96
97
  }
97
98
 
@@ -113,12 +114,12 @@ const grammar = class CSTMLMiniparserGrammar {
113
114
  }
114
115
 
115
116
  // @Node
116
- Null(p) {
117
+ NullTag(p) {
117
118
  p.eat('null', KW, { path: 'sigilToken' });
118
119
  }
119
120
 
120
121
  // @Node
121
- Gap(p) {
122
+ GapTag(p) {
122
123
  p.eat('<//>', PN, { path: 'sigilToken' });
123
124
  }
124
125
 
@@ -131,14 +132,16 @@ const grammar = class CSTMLMiniparserGrammar {
131
132
  if (open.properties.flags?.token) {
132
133
  p.eatProduction('NodeChild', { path: 'children[]' }, { token: true });
133
134
  p.eatMatchTrivia(_);
134
- } else {
135
- while (!p.match('</')) {
135
+ } else if (!open.properties.selfClosingTagToken) {
136
+ while (!(p.match('</') || p.done)) {
136
137
  p.eatProduction('NodeChild', { path: 'children[]' });
137
138
  p.eatMatchTrivia(_);
138
139
  }
139
140
  }
140
141
 
141
- p.eatProduction('CloseNodeTag', { path: 'close' });
142
+ if (!open.properties.selfClosingTagToken) {
143
+ p.eatProduction('CloseNodeTag', { path: 'close' });
144
+ }
142
145
  }
143
146
 
144
147
  NodeChild(p, _, props) {
@@ -148,7 +151,7 @@ const grammar = class CSTMLMiniparserGrammar {
148
151
  if (p.match(/<\*?@/y)) {
149
152
  p.eatProduction('Node');
150
153
  } else {
151
- p.eatProduction('Literal');
154
+ p.eatProduction('LiteralTag');
152
155
  }
153
156
  } else {
154
157
  if (p.match(/<\*?#/y)) {
@@ -156,23 +159,23 @@ const grammar = class CSTMLMiniparserGrammar {
156
159
  } else if (p.match(/[a-zA-Z]/y)) {
157
160
  p.eatProduction('Property');
158
161
  } else if (p.match(/['"]/y)) {
159
- p.eatProduction('Literal');
162
+ p.eatProduction('LiteralTag');
160
163
  }
161
164
  }
162
165
  }
163
166
 
164
167
  // @Node
165
168
  Property(p) {
166
- p.eatProduction('Reference', { path: 'reference' });
169
+ p.eatProduction('ReferenceTag', { path: 'reference' });
167
170
  p.eatMatchTrivia(_);
168
171
  p.eatProduction('PropertyValue', { path: 'value' });
169
172
  }
170
173
 
171
174
  PropertyValue(p) {
172
175
  if (p.match('null')) {
173
- p.eatProduction('Null');
176
+ p.eatProduction('NullTag');
174
177
  } else if (p.match('<//>')) {
175
- p.eatProduction('Gap');
178
+ p.eatProduction('GapTag');
176
179
  } else {
177
180
  p.eatProduction('Node');
178
181
  }
@@ -198,13 +201,17 @@ const grammar = class CSTMLMiniparserGrammar {
198
201
  flags = p.eatProduction('Flags', { path: 'flags' });
199
202
  }
200
203
 
204
+ if (p.done) {
205
+ p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
206
+ return;
207
+ }
208
+
201
209
  p.eatProduction('TagType', { path: 'type' });
202
210
 
203
211
  let sp = p.eatMatchTrivia(_);
204
212
 
205
- let iv;
206
213
  if (flags.properties.intrinsic && sp && (p.match(/['"/]/y) || p.atExpression)) {
207
- iv = p.eatProduction('String', { path: 'intrinsicValue' });
214
+ p.eatProduction('String', { path: 'intrinsicValue' });
208
215
 
209
216
  sp = p.eatMatchTrivia(_);
210
217
  }
@@ -215,9 +222,7 @@ const grammar = class CSTMLMiniparserGrammar {
215
222
  }
216
223
 
217
224
  p.eatMatchTrivia(_);
218
- if (iv) {
219
- p.eat('/', PN, { path: 'selfClosingTagToken' });
220
- }
225
+ p.eatMatch('/', PN, { path: 'selfClosingTagToken' });
221
226
  p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
222
227
  }
223
228
 
@@ -305,20 +310,20 @@ const grammar = class CSTMLMiniparserGrammar {
305
310
 
306
311
  // @Node
307
312
  Identifier(p) {
308
- p.eatLiteral(/[a-zA-Z][[a-zA-Z]-_]*/y);
313
+ p.eatLiteral(/[a-zA-Z][a-zA-Z-_]*/y);
309
314
  }
310
315
 
311
316
  // @Cover
312
- Terminal(p) {
317
+ Tag(p) {
313
318
  if (p.match(/['"]/y)) {
314
- p.eatProduction('Literal');
319
+ p.eatProduction('LiteralTag');
315
320
  } else {
316
321
  throw new Error();
317
322
  }
318
323
  }
319
324
 
320
325
  // @Node
321
- Reference(p) {
326
+ ReferenceTag(p) {
322
327
  p.eatProduction('Identifier', { path: 'name' });
323
328
  p.eatMatchTrivia(_);
324
329
  p.eatMatch('[]', PN, { path: 'arrayToken' });
@@ -327,11 +332,11 @@ const grammar = class CSTMLMiniparserGrammar {
327
332
  }
328
333
 
329
334
  // @Cover
330
- EmbeddedTerminal(p) {
335
+ EmbeddedTag(p) {
331
336
  if (p.match(/!['"]/y)) {
332
337
  p.eatProduction('Escape');
333
338
  } else if (p.match(/['"]/y)) {
334
- p.eatProduction('Literal');
339
+ p.eatProduction('LiteralTag');
335
340
  } else {
336
341
  throw new Error();
337
342
  }
@@ -1,7 +1,7 @@
1
1
  const Spamex = require('./spamex.js');
2
2
  const CSTML = require('./cstml.js');
3
3
  const Regex = require('./regex.js');
4
- const { node } = require('../symbols.js');
4
+ const { node } = require('@bablr/boot-helpers/symbols');
5
5
  const { buildCovers } = require('../utils.js');
6
6
 
7
7
  const _ = /\s+/y;
@@ -1,7 +1,7 @@
1
1
  const when = require('iter-tools/methods/when');
2
2
  const { escapables } = require('./cstml.js');
3
3
  const { buildCovers } = require('../utils.js');
4
- const { node } = require('../symbols.js');
4
+ const { node } = require('@bablr/boot-helpers/symbols');
5
5
 
6
6
  const name = 'Regex';
7
7
 
@@ -65,7 +65,7 @@ const unique = (flags) => flags.length === new Set(flags).size;
65
65
  const getSpecialPattern = (span) => {
66
66
  const { type } = span;
67
67
  if (type === 'Bare') {
68
- return /[*+{}\[\]()\.^$|\\\n\/]/y;
68
+ return /[*+{}\[\]()\.^$|\\\n\/><]/y;
69
69
  } else if (type === 'CharacterClass') {
70
70
  return /[\]\\]/y;
71
71
  } else if (type === 'CharacterClass:First') {
@@ -1,12 +1,11 @@
1
1
  const Regex = require('./regex.js');
2
2
  const CSTML = require('./cstml.js');
3
3
  const { buildCovers } = require('../utils.js');
4
- const sym = require('../symbols.js');
4
+ const sym = require('@bablr/boot-helpers/symbols');
5
5
 
6
6
  const _ = /\s+/y;
7
7
  const PN = 'Punctuator';
8
8
  const ID = 'Identifier';
9
- const LIT = 'Literal';
10
9
 
11
10
  const name = 'Spamex';
12
11
 
@@ -15,14 +14,18 @@ const canonicalURL = 'https://bablr.org/languages/core/en/spamex';
15
14
  const dependencies = { CSTML, Regex };
16
15
 
17
16
  const covers = buildCovers({
18
- [sym.node]: ['Attribute', 'Identifier', 'Matcher', 'Literal', 'CSTML:Flags'],
17
+ [sym.node]: ['Attribute', 'Identifier', 'Pattern', 'Matcher', 'Literal', 'CSTML:Flags'],
19
18
  Attribute: ['MappingAttribute', 'BooleanAttribute'],
20
19
  AttributeValue: ['CSTML:String', 'CSTML:Number'],
21
- Matcher: ['NodeMatcher', 'StringMatcher'],
20
+ Matcher: ['NodeMatcher', 'OpenNodeMatcher', 'CloseNodeMatcher', 'StringMatcher'],
22
21
  StringMatcher: ['CSTML:String', 'Regex:Pattern'],
23
22
  });
24
23
 
25
24
  const grammar = class SpamexMiniparserGrammar {
25
+ Pattern(p) {
26
+ p.eatProduction('Matcher', { path: 'matcher' });
27
+ }
28
+
26
29
  // @Cover
27
30
  Matcher(p) {
28
31
  if (p.match(/<[^!/]/y)) {
@@ -36,8 +39,28 @@ const grammar = class SpamexMiniparserGrammar {
36
39
  }
37
40
  }
38
41
 
39
- // @Node
40
42
  NodeMatcher(p) {
43
+ let open = p.eatProduction('OpenNodeMatcher', { path: 'open' });
44
+
45
+ if (!open.properties.selfClosingTagToken) {
46
+ p.eatMatchTrivia(_);
47
+
48
+ if (open.properties.flags?.token) {
49
+ // p.eatProduction('NodeChild', { path: 'children[]' }, { token: true });
50
+ // p.eatMatchTrivia(_);
51
+ } else {
52
+ // while (!(p.match('</') || p.done)) {
53
+ // p.eatProduction('NodeChild', { path: 'children[]' });
54
+ // p.eatMatchTrivia(_);
55
+ // }
56
+ }
57
+
58
+ p.eatProduction('CloseNodeMatcher', { path: 'close' });
59
+ }
60
+ }
61
+
62
+ // @Node
63
+ OpenNodeMatcher(p) {
41
64
  p.eat('<', PN, { path: 'openToken', startSpan: 'Tag', balanced: '>' });
42
65
 
43
66
  if (!p.atExpression) {
@@ -48,6 +71,10 @@ const grammar = class SpamexMiniparserGrammar {
48
71
  p.eat(/[a-zA-Z]+/y, ID, { path: 'language' });
49
72
  p.eat(':', PN, { path: 'namespaceSeparatorToken' });
50
73
  p.eat(/[a-zA-Z]+/y, ID, { path: 'type' });
74
+ } else if (p.match('?')) {
75
+ p.eat('?', PN, { path: 'type' });
76
+ } else if (p.match(' ')) {
77
+ p.eatMatchTrivia(_);
51
78
  } else {
52
79
  if (p.atExpression) {
53
80
  p.eatProduction('Identifier', { path: 'type' });
@@ -58,7 +85,7 @@ const grammar = class SpamexMiniparserGrammar {
58
85
 
59
86
  let sp = p.eatMatchTrivia(_);
60
87
 
61
- if (sp && (p.match(/['"/]/y) || p.atExpression)) {
88
+ if (sp && ((p.match(/['"/]/y) && !p.match('/>')) || p.atExpression)) {
62
89
  p.eatProduction('StringMatcher', { path: 'intrinsicValue' });
63
90
 
64
91
  sp = p.eatMatchTrivia(_);
@@ -70,6 +97,12 @@ const grammar = class SpamexMiniparserGrammar {
70
97
  }
71
98
 
72
99
  p.eatMatchTrivia(_);
100
+ p.eatMatch('/', PN, { path: 'selfClosingTagToken' });
101
+ p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
102
+ }
103
+
104
+ CloseNodeMatcher(p) {
105
+ p.eat('</', PN, { path: 'openToken', startSpan: 'Tag', balanced: '>' });
73
106
  p.eat('>', PN, { path: 'closeToken', endSpan: 'Tag', balancer: true });
74
107
  }
75
108
 
@@ -94,12 +127,12 @@ const grammar = class SpamexMiniparserGrammar {
94
127
 
95
128
  // @Node
96
129
  BooleanAttribute(p) {
97
- p.eat(/[a-zA-Z]+/y, LIT, { path: 'key' });
130
+ p.eat(/[a-zA-Z]+/y, ID, { path: 'key' });
98
131
  }
99
132
 
100
133
  // @Node
101
134
  MappingAttribute(p) {
102
- p.eat(/[a-zA-Z]+/y, LIT, { path: 'key' });
135
+ p.eat(/[a-zA-Z]+/y, ID, { path: 'key' });
103
136
  p.eatMatchTrivia(_);
104
137
  p.eat('=', PN, { path: 'mapToken' });
105
138
  p.eatMatchTrivia(_);
package/lib/match.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const { Path, buildNode } = require('./path.js');
2
2
  const { resolveDependentLanguage } = require('./utils.js');
3
- const sym = require('./symbols.js');
3
+ const sym = require('@bablr/boot-helpers/symbols');
4
4
 
5
5
  class Match {
6
6
  constructor(parent, resolvedLanguage, id, attributes, path) {
package/lib/miniparser.js CHANGED
@@ -3,10 +3,11 @@ const escapeRegex = require('escape-string-regexp');
3
3
  const arrayLast = require('iter-tools/methods/array-last');
4
4
  const isString = require('iter-tools/methods/is-string');
5
5
  const isObject = require('iter-tools/methods/is-object');
6
- const sym = require('./symbols.js');
6
+ const sym = require('@bablr/boot-helpers/symbols');
7
7
  const { Match } = require('./match.js');
8
8
  const { parsePath } = require('./path.js');
9
9
  const { set, isRegex, isArray, getPrototypeOf, buildNode } = require('./utils.js');
10
+ const { ReferenceTag, LiteralTag, Escape } = require('@bablr/boot-helpers/symbols');
10
11
 
11
12
  class TemplateParser {
12
13
  constructor(rootLanguage, quasis, expressions) {
@@ -210,11 +211,11 @@ class TemplateParser {
210
211
  this.m = this.m.parent;
211
212
 
212
213
  if (this.path?.node) {
213
- const isTerminal = (child) => ['Literal', 'Escape'].includes(child.type);
214
+ const isTag = (child) => [LiteralTag, Escape].includes(child.type);
214
215
 
215
216
  const { children } = this.path.node;
216
217
 
217
- if (children.find(isTerminal) && !children.every(isTerminal)) {
218
+ if (children.find(isTag) && !children.every(isTag)) {
218
219
  throw new Error('strings must be wrapped in nodes');
219
220
  }
220
221
  }
@@ -280,7 +281,7 @@ class TemplateParser {
280
281
 
281
282
  const lastChild = arrayLast(children);
282
283
 
283
- if (lastChild.type !== 'Reference') {
284
+ if (lastChild.type !== ReferenceTag) {
284
285
  throw new Error();
285
286
  }
286
287