@bablr/language-en-json 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 +74 -83
- package/lib/grammar.macro.js +84 -92
- package/package.json +8 -8
package/lib/grammar.js
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/* @macrome
|
|
2
2
|
* @generatedby @bablr/macrome-generator-bablr
|
|
3
|
-
* @generatedfrom ./grammar.macro.js#
|
|
3
|
+
* @generatedfrom ./grammar.macro.js#dd06bed2bba53b9dde1ae7cf33f8696edb684bd6
|
|
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
|
*/
|
|
7
7
|
import _applyDecs from "@babel/runtime/helpers/applyDecs2305";
|
|
8
|
-
let _initProto, _ExpressionDecs, _ArrayDecs, _ObjectDecs, _NumberDecs, _InfinityDecs, _BooleanDecs, _NullDecs, _KeywordDecs, _PunctuatorDecs, _ListDecs, _AnyDecs, _AllDecs;
|
|
8
|
+
let _initProto, _ExpressionDecs, _ArrayDecs, _ObjectDecs, _StringDecs, _NumberDecs, _InfinityDecs, _BooleanDecs, _NullDecs, _KeywordDecs, _PunctuatorDecs, _ListDecs, _AnyDecs, _AllDecs;
|
|
9
9
|
import { re, spam as m } from '@bablr/boot';
|
|
10
|
-
import {
|
|
10
|
+
import { basicTriviaEnhancer } from '@bablr/helpers/trivia';
|
|
11
11
|
import * as productions from '@bablr/helpers/productions';
|
|
12
|
-
import { o, eat, eatMatch, match, fail } from '@bablr/helpers/grammar';
|
|
13
|
-
import { buildString
|
|
14
|
-
import { Node, CoveredBy, AllowEmpty, InjectFrom } from '@bablr/helpers/decorators';
|
|
12
|
+
import { o, eat, eatMatch, match, fail, defineAttribute } from '@bablr/helpers/grammar';
|
|
13
|
+
import { buildString } from '@bablr/helpers/builders';
|
|
14
|
+
import { Node, CoveredBy, AllowEmpty, InjectFrom, Literal } from '@bablr/helpers/decorators';
|
|
15
15
|
import * as Space from '@bablr/language-en-blank-space';
|
|
16
|
-
import { getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
|
|
17
16
|
export const dependencies = {
|
|
18
17
|
Space
|
|
19
18
|
};
|
|
@@ -31,53 +30,31 @@ const escapables = new Map(Object.entries({
|
|
|
31
30
|
function first(iter) {
|
|
32
31
|
for (let value of iter) return value;
|
|
33
32
|
}
|
|
34
|
-
export const
|
|
35
|
-
let cooked;
|
|
36
|
-
const codeNode = escapeNode.get('code');
|
|
37
|
-
if (first(codeNode.children)?.value.flags.token) {
|
|
38
|
-
const match_ = ctx.sourceTextFor(codeNode);
|
|
39
|
-
cooked = escapables.get(match_) || match_;
|
|
40
|
-
} else {
|
|
41
|
-
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
42
|
-
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
43
|
-
if (!span.startsWith('String')) {
|
|
44
|
-
throw new Error('not implemented');
|
|
45
|
-
}
|
|
46
|
-
if (type === 'u') {
|
|
47
|
-
cooked = parseInt(value, 16);
|
|
48
|
-
} else {
|
|
49
|
-
throw new Error();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return cooked.toString(10);
|
|
53
|
-
};
|
|
54
|
-
export const grammar = triviaEnhancer({
|
|
33
|
+
export const grammar = basicTriviaEnhancer({
|
|
55
34
|
triviaIsAllowed: s => s.span === 'Bare',
|
|
56
|
-
|
|
57
|
-
if (yield match(re`/[ \n\r\t]/`)) {
|
|
58
|
-
yield eat(m`#: <*Space:Space />`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
35
|
+
triviaMatcher: m`#: :Space: <*Space /[ \n\r\t]/ />`
|
|
61
36
|
}, class JSONGrammar {
|
|
62
37
|
static {
|
|
63
|
-
[_initProto] = _applyDecs(this, [[_ExpressionDecs, 2, "Expression"], [_ArrayDecs, 2, "Array"], [_ObjectDecs, 2, "Object"], [Node, 2, "Property"], [
|
|
38
|
+
[_initProto] = _applyDecs(this, [[_ExpressionDecs, 2, "Expression"], [_ArrayDecs, 2, "Array"], [_ObjectDecs, 2, "Object"], [Node, 2, "Property"], [_StringDecs, 2, "String"], [[AllowEmpty, Node], 2, "StringContent"], [Node, 2, "EscapeSequence"], [Node, 2, "EscapeCode"], [_NumberDecs, 2, "Number"], [Node, 2, "Integer"], [Node, 2, "UnsignedInteger"], [Node, 2, "UnsignedHexInteger"], [_InfinityDecs, 2, "Infinity"], [_BooleanDecs, 2, "Boolean"], [_NullDecs, 2, "Null"], [_KeywordDecs, 2, "Keyword"], [_PunctuatorDecs, 2, "Punctuator"], [_ListDecs, 2, "List"], [_AnyDecs, 2, "Any"], [_AllDecs, 2, "All"]], []).e;
|
|
64
39
|
}
|
|
65
40
|
constructor() {
|
|
66
41
|
_initProto(this);
|
|
67
42
|
}
|
|
68
|
-
*[(_ExpressionDecs = CoveredBy('Element'), _ArrayDecs = [CoveredBy('Expression'), Node], _ObjectDecs = [CoveredBy('Expression'), Node], _NumberDecs = [CoveredBy('Expression'), Node], _InfinityDecs = [CoveredBy('Expression'), Node], _BooleanDecs = [CoveredBy('Expression'), Node], _NullDecs = [CoveredBy('Expression'), Node], _KeywordDecs = [Node, InjectFrom(productions)], _PunctuatorDecs = [Node, InjectFrom(productions)], _ListDecs = [AllowEmpty, InjectFrom(productions)], _AnyDecs = InjectFrom(productions), _AllDecs = InjectFrom(productions), Symbol.for('@bablr/fragment'))]({
|
|
69
|
-
|
|
43
|
+
*[(_ExpressionDecs = CoveredBy('Element'), _ArrayDecs = [CoveredBy('Expression'), Node], _ObjectDecs = [CoveredBy('Expression'), Node], _StringDecs = [CoveredBy('Expression'), Node], _NumberDecs = [CoveredBy('Expression'), Node], _InfinityDecs = [CoveredBy('Expression'), Node], _BooleanDecs = [CoveredBy('Expression'), Node], _NullDecs = [CoveredBy('Expression'), Node], _KeywordDecs = [Literal, Node, InjectFrom(productions)], _PunctuatorDecs = [Literal, Node, InjectFrom(productions)], _ListDecs = [AllowEmpty, InjectFrom(productions)], _AnyDecs = InjectFrom(productions), _AllDecs = InjectFrom(productions), Symbol.for('@bablr/fragment'))]({
|
|
44
|
+
props: {
|
|
45
|
+
rootMatcher
|
|
46
|
+
}
|
|
70
47
|
}) {
|
|
71
48
|
// needed for the trivia plugin
|
|
72
|
-
yield eat(
|
|
49
|
+
yield eat(rootMatcher);
|
|
73
50
|
}
|
|
74
51
|
*Expression() {
|
|
75
|
-
yield eat(m`<
|
|
52
|
+
yield eat(m`<_Any />`, [m`<Array '[' />`, m`<Object '{' />`, m`<String /['"]/ />`, m`<Number /\d|-[\d\g]/ {span: 'Number'} />`, m`<Infinity /-?Infinity/ />`, m`<Null 'null' />`, m`<Boolean /true|false/ />`]);
|
|
76
53
|
}
|
|
77
54
|
*Array() {
|
|
78
55
|
yield eat(m`openToken: <*Punctuator '[' { balanced: ']' } />`);
|
|
79
|
-
yield eat(m`<
|
|
80
|
-
element: m`elements[]
|
|
56
|
+
yield eat(m`<_List />`, o({
|
|
57
|
+
element: m`elements[]+$: <__Expression />`,
|
|
81
58
|
separator: m`separatorTokens[]: <*Punctuator ',' />`,
|
|
82
59
|
allowTrailingSeparator: false
|
|
83
60
|
}));
|
|
@@ -89,7 +66,7 @@ export const grammar = triviaEnhancer({
|
|
|
89
66
|
yield eatMatch(m`separatorTokens[]: []`);
|
|
90
67
|
yield eatMatch(m`properties[]$: []`);
|
|
91
68
|
while (sep && (yield match(re`/.|\g/s`))) {
|
|
92
|
-
let suppressGap = !!(yield match(m`<
|
|
69
|
+
let suppressGap = !!(yield match(m`<_All />`, [m`key: <//>`, m`sigilToken: <*Punctuator ':' />`]));
|
|
93
70
|
yield eat(m`properties[]$: <Property />`, null, o({
|
|
94
71
|
suppressGap
|
|
95
72
|
}));
|
|
@@ -98,22 +75,14 @@ export const grammar = triviaEnhancer({
|
|
|
98
75
|
yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
|
|
99
76
|
}
|
|
100
77
|
*Property() {
|
|
101
|
-
yield eat(m`key$:
|
|
78
|
+
yield eat(m`key$: <String />`);
|
|
102
79
|
yield eat(m`sigilToken: <*Punctuator ':' />`);
|
|
103
|
-
yield eat(m`value
|
|
104
|
-
}
|
|
105
|
-
*Identifier() {
|
|
106
|
-
yield eat(re`/[a-zA-Z][a-zA-Z_-]*/`);
|
|
80
|
+
yield eat(m`value+$: <__Expression />`);
|
|
107
81
|
}
|
|
108
|
-
*String({
|
|
109
|
-
|
|
110
|
-
}) {
|
|
111
|
-
let q = yield match(re`/['"]/`);
|
|
112
|
-
if (!q) yield fail();
|
|
113
|
-
const q_ = ctx.sourceTextFor(q);
|
|
114
|
-
yield q_ === "'" ? eat(m`openToken: <*Punctuator "'" { balanced: "'", balancedSpan: 'String:Single' } />`) : eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
|
|
82
|
+
*String() {
|
|
83
|
+
yield eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
|
|
115
84
|
yield eat(m`content$: <*StringContent />`);
|
|
116
|
-
yield
|
|
85
|
+
yield eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
|
|
117
86
|
}
|
|
118
87
|
*StringContent({
|
|
119
88
|
state: {
|
|
@@ -137,22 +106,46 @@ export const grammar = triviaEnhancer({
|
|
|
137
106
|
}
|
|
138
107
|
yield eat(m`sigilToken: <*Punctuator '\\' { openSpan: 'Escape' } />`);
|
|
139
108
|
let match_;
|
|
109
|
+
let cooked;
|
|
140
110
|
if (match_ = span === 'String:Single' ? yield match(re`/[\\/nrt0']/`) : yield match(re`/[\\/nrt0"]/`)) {
|
|
141
111
|
const matchText = ctx.sourceTextFor(match_);
|
|
142
112
|
yield eat(m`code: <*Keyword ${buildString(matchText)} { closeSpan: 'Escape' } />`);
|
|
113
|
+
cooked = escapables.get(matchText) || matchText;
|
|
143
114
|
} else if (yield match('u')) {
|
|
144
|
-
yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
115
|
+
let codeNode = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
116
|
+
if (codeNode && first(codeNode.children)?.value.flags.token) {
|
|
117
|
+
const match_ = ctx.sourceTextFor(codeNode);
|
|
118
|
+
} else {
|
|
119
|
+
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
120
|
+
if (type) {
|
|
121
|
+
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
122
|
+
if (!span.startsWith('String')) {
|
|
123
|
+
throw new Error('not implemented');
|
|
124
|
+
}
|
|
125
|
+
if (type === 'u') {
|
|
126
|
+
cooked = String.fromCharCode(parseInt(value, 16));
|
|
127
|
+
} else {
|
|
128
|
+
throw new Error();
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
let value = ctx.sourceTextFor(codeNode);
|
|
132
|
+
cooked = escapables.get(value) || value;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
145
135
|
} else {
|
|
146
136
|
yield fail();
|
|
147
137
|
}
|
|
138
|
+
yield defineAttribute('cooked', cooked);
|
|
148
139
|
}
|
|
149
140
|
*EscapeCode() {
|
|
150
141
|
if (yield eatMatch(m`typeToken: <*Keyword 'u' />`)) {
|
|
151
|
-
if (yield eatMatch(m`openToken: <*Punctuator '{' { balanced: '}' }
|
|
152
|
-
|
|
142
|
+
if (yield eatMatch(m`openToken: <*Punctuator '{' { balanced: '}' } />`, null, o({
|
|
143
|
+
bind: true
|
|
144
|
+
}))) {
|
|
145
|
+
yield eat(m`value$: <*UnsignedHexInteger />`);
|
|
153
146
|
yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
|
|
154
147
|
} else {
|
|
155
|
-
yield eat(m`value$: <*
|
|
148
|
+
yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{4}/ />`);
|
|
156
149
|
yield eat(m`closeToken: null`);
|
|
157
150
|
}
|
|
158
151
|
}
|
|
@@ -162,13 +155,17 @@ export const grammar = triviaEnhancer({
|
|
|
162
155
|
noDoubleZero: true,
|
|
163
156
|
matchSign: '-'
|
|
164
157
|
}));
|
|
165
|
-
let fs = yield eatMatch(m`fractionalSeparatorToken: <*Punctuator '.'
|
|
158
|
+
let fs = yield eatMatch(m`fractionalSeparatorToken: <*Punctuator '.' />`, null, o({
|
|
159
|
+
bind: true
|
|
160
|
+
}));
|
|
166
161
|
if (fs) {
|
|
167
|
-
yield eat(m`fractionalPart$:
|
|
162
|
+
yield eat(m`fractionalPart$: <*UnsignedInteger />`);
|
|
168
163
|
} else {
|
|
169
164
|
yield eat(m`fractionalPart$: null`);
|
|
170
165
|
}
|
|
171
|
-
let es = yield eatMatch(m`exponentSeparatorToken: <*Punctuator /[eE]/
|
|
166
|
+
let es = yield eatMatch(m`exponentSeparatorToken: <*Punctuator /[eE]/ />`, null, o({
|
|
167
|
+
bind: true
|
|
168
|
+
}));
|
|
172
169
|
if (es) {
|
|
173
170
|
yield eat(m`exponentPart$: <Integer />`, {
|
|
174
171
|
matchSign: /[+-]/
|
|
@@ -178,14 +175,15 @@ export const grammar = triviaEnhancer({
|
|
|
178
175
|
}
|
|
179
176
|
}
|
|
180
177
|
*Integer({
|
|
181
|
-
|
|
182
|
-
}) {
|
|
183
|
-
const {
|
|
178
|
+
props: {
|
|
184
179
|
matchSign = null,
|
|
185
180
|
noDoubleZero = false
|
|
186
|
-
}
|
|
181
|
+
}
|
|
182
|
+
}) {
|
|
187
183
|
if (matchSign) {
|
|
188
|
-
yield eatMatch(m`signToken: <*Punctuator ${buildString(matchSign)}
|
|
184
|
+
yield eatMatch(m`signToken: <*Punctuator ${buildString(matchSign)} />`, null, o({
|
|
185
|
+
bind: true
|
|
186
|
+
}));
|
|
189
187
|
} else {
|
|
190
188
|
yield eat(m`signToken: null`);
|
|
191
189
|
}
|
|
@@ -194,19 +192,23 @@ export const grammar = triviaEnhancer({
|
|
|
194
192
|
}));
|
|
195
193
|
}
|
|
196
194
|
*UnsignedInteger({
|
|
197
|
-
|
|
195
|
+
props: {
|
|
196
|
+
noDoubleZero = false
|
|
197
|
+
},
|
|
198
198
|
ctx
|
|
199
199
|
}) {
|
|
200
|
-
const {
|
|
201
|
-
noDoubleZero = false
|
|
202
|
-
} = props || {};
|
|
203
200
|
let firstDigit = ctx.sourceTextFor(yield eat(re`/\d/`));
|
|
204
201
|
if (!noDoubleZero || firstDigit.value !== '0') {
|
|
205
202
|
yield eatMatch(re`/\d+/`);
|
|
206
203
|
}
|
|
207
204
|
}
|
|
205
|
+
*UnsignedHexInteger() {
|
|
206
|
+
yield eatMatch(re`/[\da-fA-F]+/`);
|
|
207
|
+
}
|
|
208
208
|
*Infinity() {
|
|
209
|
-
yield eatMatch(m`signToken: <*Punctuator '-'
|
|
209
|
+
yield eatMatch(m`signToken: <*Punctuator '-' />`, null, o({
|
|
210
|
+
bind: true
|
|
211
|
+
}));
|
|
210
212
|
yield eat(m`sigilToken: <*Keyword 'Infinity' />`);
|
|
211
213
|
}
|
|
212
214
|
*Boolean() {
|
|
@@ -220,15 +222,4 @@ export const grammar = triviaEnhancer({
|
|
|
220
222
|
*List() {}
|
|
221
223
|
*Any() {}
|
|
222
224
|
*All() {}
|
|
223
|
-
});
|
|
224
|
-
export const YJSON = self => {
|
|
225
|
-
return {
|
|
226
|
-
dependencies: {
|
|
227
|
-
...dependencies,
|
|
228
|
-
Y: self
|
|
229
|
-
},
|
|
230
|
-
canonicalURL,
|
|
231
|
-
getCooked,
|
|
232
|
-
grammar
|
|
233
|
-
};
|
|
234
|
-
};
|
|
225
|
+
});
|
package/lib/grammar.macro.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { re, spam as m } from '@bablr/boot';
|
|
2
|
-
import {
|
|
2
|
+
import { basicTriviaEnhancer } from '@bablr/helpers/trivia';
|
|
3
3
|
import * as productions from '@bablr/helpers/productions';
|
|
4
|
-
import { o, eat, eatMatch, match, fail } from '@bablr/helpers/grammar';
|
|
5
|
-
import { buildString
|
|
6
|
-
import { Node, CoveredBy, AllowEmpty, InjectFrom } from '@bablr/helpers/decorators';
|
|
4
|
+
import { o, eat, eatMatch, match, fail, defineAttribute } from '@bablr/helpers/grammar';
|
|
5
|
+
import { buildString } from '@bablr/helpers/builders';
|
|
6
|
+
import { Node, CoveredBy, AllowEmpty, InjectFrom, Literal } from '@bablr/helpers/decorators';
|
|
7
7
|
import * as Space from '@bablr/language-en-blank-space';
|
|
8
|
-
import { getEmbeddedObject } from '@bablr/agast-vm-helpers/deembed';
|
|
9
8
|
|
|
10
9
|
export const dependencies = { Space };
|
|
11
10
|
|
|
@@ -26,55 +25,25 @@ function first(iter) {
|
|
|
26
25
|
for (let value of iter) return value;
|
|
27
26
|
}
|
|
28
27
|
|
|
29
|
-
export const
|
|
30
|
-
let cooked;
|
|
31
|
-
const codeNode = escapeNode.get('code');
|
|
32
|
-
|
|
33
|
-
if (first(codeNode.children)?.value.flags.token) {
|
|
34
|
-
const match_ = ctx.sourceTextFor(codeNode);
|
|
35
|
-
|
|
36
|
-
cooked = escapables.get(match_) || match_;
|
|
37
|
-
} else {
|
|
38
|
-
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
39
|
-
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
40
|
-
|
|
41
|
-
if (!span.startsWith('String')) {
|
|
42
|
-
throw new Error('not implemented');
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (type === 'u') {
|
|
46
|
-
cooked = parseInt(value, 16);
|
|
47
|
-
} else {
|
|
48
|
-
throw new Error();
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return cooked.toString(10);
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
export const grammar = triviaEnhancer(
|
|
28
|
+
export const grammar = basicTriviaEnhancer(
|
|
56
29
|
{
|
|
57
30
|
triviaIsAllowed: (s) => s.span === 'Bare',
|
|
58
|
-
|
|
59
|
-
if (yield match(re`/[ \n\r\t]/`)) {
|
|
60
|
-
yield eat(m`#: <*Space:Space />`);
|
|
61
|
-
}
|
|
62
|
-
},
|
|
31
|
+
triviaMatcher: m`#: :Space: <*Space /[ \n\r\t]/ />`,
|
|
63
32
|
},
|
|
64
33
|
class JSONGrammar {
|
|
65
|
-
*[Symbol.for('@bablr/fragment')]({
|
|
34
|
+
*[Symbol.for('@bablr/fragment')]({ props: { rootMatcher } }) {
|
|
66
35
|
// needed for the trivia plugin
|
|
67
|
-
yield eat(
|
|
36
|
+
yield eat(rootMatcher);
|
|
68
37
|
}
|
|
69
38
|
|
|
70
39
|
@CoveredBy('Element')
|
|
71
40
|
*Expression() {
|
|
72
|
-
yield eat(m`<
|
|
41
|
+
yield eat(m`<_Any />`, [
|
|
73
42
|
m`<Array '[' />`,
|
|
74
43
|
m`<Object '{' />`,
|
|
75
44
|
m`<String /['"]/ />`,
|
|
76
|
-
m`<Number
|
|
77
|
-
m`<Infinity
|
|
45
|
+
m`<Number /\d|-[\d\g]/ {span: 'Number'} />`,
|
|
46
|
+
m`<Infinity /-?Infinity/ />`,
|
|
78
47
|
m`<Null 'null' />`,
|
|
79
48
|
m`<Boolean /true|false/ />`,
|
|
80
49
|
]);
|
|
@@ -85,9 +54,9 @@ export const grammar = triviaEnhancer(
|
|
|
85
54
|
*Array() {
|
|
86
55
|
yield eat(m`openToken: <*Punctuator '[' { balanced: ']' } />`);
|
|
87
56
|
yield eat(
|
|
88
|
-
m`<
|
|
57
|
+
m`<_List />`,
|
|
89
58
|
o({
|
|
90
|
-
element: m`elements[]
|
|
59
|
+
element: m`elements[]+$: <__Expression />`,
|
|
91
60
|
separator: m`separatorTokens[]: <*Punctuator ',' />`,
|
|
92
61
|
allowTrailingSeparator: false,
|
|
93
62
|
}),
|
|
@@ -105,7 +74,7 @@ export const grammar = triviaEnhancer(
|
|
|
105
74
|
yield eatMatch(m`properties[]$: []`);
|
|
106
75
|
|
|
107
76
|
while (sep && (yield match(re`/.|\g/s`))) {
|
|
108
|
-
let suppressGap = !!(yield match(m`<
|
|
77
|
+
let suppressGap = !!(yield match(m`<_All />`, [
|
|
109
78
|
m`key: <//>`,
|
|
110
79
|
m`sigilToken: <*Punctuator ':' />`,
|
|
111
80
|
]));
|
|
@@ -117,33 +86,19 @@ export const grammar = triviaEnhancer(
|
|
|
117
86
|
|
|
118
87
|
@Node
|
|
119
88
|
*Property() {
|
|
120
|
-
yield eat(m`key$:
|
|
89
|
+
yield eat(m`key$: <String />`);
|
|
121
90
|
yield eat(m`sigilToken: <*Punctuator ':' />`);
|
|
122
|
-
yield eat(m`value
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@Node
|
|
126
|
-
*Identifier() {
|
|
127
|
-
yield eat(re`/[a-zA-Z][a-zA-Z_-]*/`);
|
|
91
|
+
yield eat(m`value+$: <__Expression />`);
|
|
128
92
|
}
|
|
129
93
|
|
|
94
|
+
@CoveredBy('Expression')
|
|
130
95
|
@Node
|
|
131
|
-
*String(
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (!q) yield fail();
|
|
135
|
-
|
|
136
|
-
const q_ = ctx.sourceTextFor(q);
|
|
137
|
-
|
|
138
|
-
yield q_ === "'"
|
|
139
|
-
? eat(m`openToken: <*Punctuator "'" { balanced: "'", balancedSpan: 'String:Single' } />`)
|
|
140
|
-
: eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
|
|
96
|
+
*String() {
|
|
97
|
+
yield eat(m`openToken: <*Punctuator '"' { balanced: '"', balancedSpan: 'String:Double' } />`);
|
|
141
98
|
|
|
142
99
|
yield eat(m`content$: <*StringContent />`);
|
|
143
100
|
|
|
144
|
-
yield
|
|
145
|
-
? eat(m`closeToken: <*Punctuator "'" { balancer: true } />`)
|
|
146
|
-
: eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
|
|
101
|
+
yield eat(m`closeToken: <*Punctuator '"' { balancer: true } />`);
|
|
147
102
|
}
|
|
148
103
|
|
|
149
104
|
@AllowEmpty
|
|
@@ -168,6 +123,7 @@ export const grammar = triviaEnhancer(
|
|
|
168
123
|
yield eat(m`sigilToken: <*Punctuator '\\' { openSpan: 'Escape' } />`);
|
|
169
124
|
|
|
170
125
|
let match_;
|
|
126
|
+
let cooked;
|
|
171
127
|
|
|
172
128
|
if (
|
|
173
129
|
(match_ =
|
|
@@ -175,21 +131,54 @@ export const grammar = triviaEnhancer(
|
|
|
175
131
|
) {
|
|
176
132
|
const matchText = ctx.sourceTextFor(match_);
|
|
177
133
|
yield eat(m`code: <*Keyword ${buildString(matchText)} { closeSpan: 'Escape' } />`);
|
|
134
|
+
|
|
135
|
+
cooked = escapables.get(matchText) || matchText;
|
|
178
136
|
} else if (yield match('u')) {
|
|
179
|
-
yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
137
|
+
let codeNode = yield eat(m`code: <EscapeCode { closeSpan: 'Escape' } />`);
|
|
138
|
+
|
|
139
|
+
if (codeNode && first(codeNode.children)?.value.flags.token) {
|
|
140
|
+
const match_ = ctx.sourceTextFor(codeNode);
|
|
141
|
+
} else {
|
|
142
|
+
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
143
|
+
|
|
144
|
+
if (type) {
|
|
145
|
+
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
146
|
+
|
|
147
|
+
if (!span.startsWith('String')) {
|
|
148
|
+
throw new Error('not implemented');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (type === 'u') {
|
|
152
|
+
cooked = String.fromCharCode(parseInt(value, 16));
|
|
153
|
+
} else {
|
|
154
|
+
throw new Error();
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
let value = ctx.sourceTextFor(codeNode);
|
|
158
|
+
cooked = escapables.get(value) || value;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
180
161
|
} else {
|
|
181
162
|
yield fail();
|
|
182
163
|
}
|
|
164
|
+
|
|
165
|
+
yield defineAttribute('cooked', cooked);
|
|
183
166
|
}
|
|
184
167
|
|
|
185
168
|
@Node
|
|
186
169
|
*EscapeCode() {
|
|
187
170
|
if (yield eatMatch(m`typeToken: <*Keyword 'u' />`)) {
|
|
188
|
-
if (
|
|
189
|
-
yield
|
|
171
|
+
if (
|
|
172
|
+
yield eatMatch(
|
|
173
|
+
m`openToken: <*Punctuator '{' { balanced: '}' } />`,
|
|
174
|
+
null,
|
|
175
|
+
o({ bind: true }),
|
|
176
|
+
)
|
|
177
|
+
) {
|
|
178
|
+
yield eat(m`value$: <*UnsignedHexInteger />`);
|
|
190
179
|
yield eat(m`closeToken: <*Punctuator '}' { balancer: true } />`);
|
|
191
180
|
} else {
|
|
192
|
-
yield eat(m`value$: <*
|
|
181
|
+
yield eat(m`value$: <*UnsignedHexInteger /[\da-fA-F]{4}/ />`);
|
|
193
182
|
yield eat(m`closeToken: null`);
|
|
194
183
|
}
|
|
195
184
|
}
|
|
@@ -200,15 +189,23 @@ export const grammar = triviaEnhancer(
|
|
|
200
189
|
*Number() {
|
|
201
190
|
yield eat(m`wholePart$: <Integer />`, o({ noDoubleZero: true, matchSign: '-' }));
|
|
202
191
|
|
|
203
|
-
let fs = yield eatMatch(
|
|
192
|
+
let fs = yield eatMatch(
|
|
193
|
+
m`fractionalSeparatorToken: <*Punctuator '.' />`,
|
|
194
|
+
null,
|
|
195
|
+
o({ bind: true }),
|
|
196
|
+
);
|
|
204
197
|
|
|
205
198
|
if (fs) {
|
|
206
|
-
yield eat(m`fractionalPart$:
|
|
199
|
+
yield eat(m`fractionalPart$: <*UnsignedInteger />`);
|
|
207
200
|
} else {
|
|
208
201
|
yield eat(m`fractionalPart$: null`);
|
|
209
202
|
}
|
|
210
203
|
|
|
211
|
-
let es = yield eatMatch(
|
|
204
|
+
let es = yield eatMatch(
|
|
205
|
+
m`exponentSeparatorToken: <*Punctuator /[eE]/ />`,
|
|
206
|
+
null,
|
|
207
|
+
o({ bind: true }),
|
|
208
|
+
);
|
|
212
209
|
|
|
213
210
|
if (es) {
|
|
214
211
|
yield eat(m`exponentPart$: <Integer />`, { matchSign: /[+-]/ });
|
|
@@ -218,11 +215,13 @@ export const grammar = triviaEnhancer(
|
|
|
218
215
|
}
|
|
219
216
|
|
|
220
217
|
@Node
|
|
221
|
-
*Integer({
|
|
222
|
-
const { matchSign = null, noDoubleZero = false } = props ? getEmbeddedObject(props) : {};
|
|
223
|
-
|
|
218
|
+
*Integer({ props: { matchSign = null, noDoubleZero = false } }) {
|
|
224
219
|
if (matchSign) {
|
|
225
|
-
yield eatMatch(
|
|
220
|
+
yield eatMatch(
|
|
221
|
+
m`signToken: <*Punctuator ${buildString(matchSign)} />`,
|
|
222
|
+
null,
|
|
223
|
+
o({ bind: true }),
|
|
224
|
+
);
|
|
226
225
|
} else {
|
|
227
226
|
yield eat(m`signToken: null`);
|
|
228
227
|
}
|
|
@@ -231,9 +230,7 @@ export const grammar = triviaEnhancer(
|
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
@Node
|
|
234
|
-
*UnsignedInteger({
|
|
235
|
-
const { noDoubleZero = false } = props || {};
|
|
236
|
-
|
|
233
|
+
*UnsignedInteger({ props: { noDoubleZero = false }, ctx }) {
|
|
237
234
|
let firstDigit = ctx.sourceTextFor(yield eat(re`/\d/`));
|
|
238
235
|
|
|
239
236
|
if (!noDoubleZero || firstDigit.value !== '0') {
|
|
@@ -241,10 +238,15 @@ export const grammar = triviaEnhancer(
|
|
|
241
238
|
}
|
|
242
239
|
}
|
|
243
240
|
|
|
241
|
+
@Node
|
|
242
|
+
*UnsignedHexInteger() {
|
|
243
|
+
yield eatMatch(re`/[\da-fA-F]+/`);
|
|
244
|
+
}
|
|
245
|
+
|
|
244
246
|
@CoveredBy('Expression')
|
|
245
247
|
@Node
|
|
246
248
|
*Infinity() {
|
|
247
|
-
yield eatMatch(m`signToken: <*Punctuator '-'
|
|
249
|
+
yield eatMatch(m`signToken: <*Punctuator '-' />`, null, o({ bind: true }));
|
|
248
250
|
yield eat(m`sigilToken: <*Keyword 'Infinity' />`);
|
|
249
251
|
}
|
|
250
252
|
|
|
@@ -260,10 +262,12 @@ export const grammar = triviaEnhancer(
|
|
|
260
262
|
yield eat(m`sigilToken: <*Keyword 'null' />`);
|
|
261
263
|
}
|
|
262
264
|
|
|
265
|
+
@Literal
|
|
263
266
|
@Node
|
|
264
267
|
@InjectFrom(productions)
|
|
265
268
|
*Keyword() {}
|
|
266
269
|
|
|
270
|
+
@Literal
|
|
267
271
|
@Node
|
|
268
272
|
@InjectFrom(productions)
|
|
269
273
|
*Punctuator() {}
|
|
@@ -279,15 +283,3 @@ export const grammar = triviaEnhancer(
|
|
|
279
283
|
*All() {}
|
|
280
284
|
},
|
|
281
285
|
);
|
|
282
|
-
|
|
283
|
-
export const YJSON = (self) => {
|
|
284
|
-
return {
|
|
285
|
-
dependencies: {
|
|
286
|
-
...dependencies,
|
|
287
|
-
Y: self,
|
|
288
|
-
},
|
|
289
|
-
canonicalURL,
|
|
290
|
-
getCooked,
|
|
291
|
-
grammar,
|
|
292
|
-
};
|
|
293
|
-
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/language-en-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "A BABLR language for JSON",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=12.0.0"
|
|
@@ -21,19 +21,19 @@
|
|
|
21
21
|
},
|
|
22
22
|
"sideEffects": false,
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@bablr/agast-helpers": "0.
|
|
25
|
-
"@bablr/agast-vm-helpers": "0.
|
|
26
|
-
"@bablr/boot": "0.
|
|
27
|
-
"@bablr/helpers": "0.
|
|
28
|
-
"@bablr/language-en-blank-space": "0.
|
|
24
|
+
"@bablr/agast-helpers": "0.8.0",
|
|
25
|
+
"@bablr/agast-vm-helpers": "0.8.0",
|
|
26
|
+
"@bablr/boot": "0.9.0",
|
|
27
|
+
"@bablr/helpers": "0.23.0",
|
|
28
|
+
"@bablr/language-en-blank-space": "0.8.0",
|
|
29
29
|
"@babel/runtime": "^7.22.15"
|
|
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.7.0",
|
|
37
37
|
"enhanced-resolve": "^5.12.0",
|
|
38
38
|
"eslint": "^7.32.0",
|
|
39
39
|
"eslint-import-resolver-enhanced-resolve": "^1.0.5",
|