@bablr/language-en-json 0.5.4 → 0.7.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 +907 -792
- package/lib/grammar.macro.js +74 -52
- package/package.json +10 -10
package/lib/grammar.macro.js
CHANGED
|
@@ -2,7 +2,13 @@ import { i } from '@bablr/boot/shorthand.macro';
|
|
|
2
2
|
import { triviaEnhancer } from '@bablr/helpers/trivia';
|
|
3
3
|
import * as productions from '@bablr/helpers/productions';
|
|
4
4
|
import { buildString, buildBoolean } from '@bablr/agast-vm-helpers';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
Node,
|
|
7
|
+
CoveredBy,
|
|
8
|
+
AllowEmpty,
|
|
9
|
+
InjectFrom,
|
|
10
|
+
UnboundAttributes,
|
|
11
|
+
} from '@bablr/helpers/decorators';
|
|
6
12
|
import * as Space from '@bablr/language-en-blank-space';
|
|
7
13
|
|
|
8
14
|
export const dependencies = { Space };
|
|
@@ -21,69 +27,93 @@ export const escapables = new Map(
|
|
|
21
27
|
}),
|
|
22
28
|
);
|
|
23
29
|
|
|
30
|
+
export const getCooked = (escapeNode, span, ctx) => {
|
|
31
|
+
let cooked;
|
|
32
|
+
const codeNode = escapeNode.get('code');
|
|
33
|
+
const type = ctx.sourceTextFor(codeNode.get('typeToken'));
|
|
34
|
+
const value = ctx.sourceTextFor(codeNode.get('value'));
|
|
35
|
+
|
|
36
|
+
if (!span.startsWith('String')) {
|
|
37
|
+
throw new Error('not implemented');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!type) {
|
|
41
|
+
const match_ = ctx.sourceTextFor(codeNode);
|
|
42
|
+
|
|
43
|
+
cooked = escapables.get(match_) || match_;
|
|
44
|
+
} else if (type === 'u') {
|
|
45
|
+
cooked = parseInt(value, 16);
|
|
46
|
+
} else {
|
|
47
|
+
throw new Error();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return cooked.toString(10);
|
|
51
|
+
};
|
|
52
|
+
|
|
24
53
|
export const grammar = triviaEnhancer(
|
|
25
54
|
{
|
|
26
55
|
triviaIsAllowed: (s) => s.span === 'Bare',
|
|
27
56
|
*eatMatchTrivia() {
|
|
28
57
|
if (yield i`match(/[ \n\r\t]/)`) {
|
|
29
|
-
yield i`eat(<#*Space:Space
|
|
58
|
+
yield i`eat(<#*Space:Space />)`;
|
|
30
59
|
}
|
|
31
60
|
},
|
|
32
61
|
},
|
|
33
62
|
class JSONGrammar {
|
|
34
63
|
*[Symbol.for('@bablr/fragment')]() {
|
|
35
|
-
|
|
64
|
+
// needed for the trivia plugin
|
|
65
|
+
yield i`eat(< />)`;
|
|
36
66
|
}
|
|
37
67
|
|
|
38
68
|
@CoveredBy('Element')
|
|
39
69
|
*Expression() {
|
|
40
|
-
yield i`eat(<Any
|
|
41
|
-
<Array '['
|
|
42
|
-
<Object '{'
|
|
43
|
-
<String '"'
|
|
44
|
-
<Number /-?\d/ span='Number'
|
|
45
|
-
<Null 'null'
|
|
46
|
-
<Boolean /true|false/>
|
|
70
|
+
yield i`eat(<Any /> null [
|
|
71
|
+
<Array '[' />
|
|
72
|
+
<Object '{' />
|
|
73
|
+
<String '"' />
|
|
74
|
+
<Number /-?\d/ span='Number' />
|
|
75
|
+
<Null 'null' />
|
|
76
|
+
<Boolean /true|false/ />
|
|
47
77
|
])`;
|
|
48
78
|
}
|
|
49
79
|
|
|
50
80
|
@CoveredBy('Expression')
|
|
51
81
|
@Node
|
|
52
82
|
*Array() {
|
|
53
|
-
yield i`eat(
|
|
54
|
-
yield i`eat(<List
|
|
55
|
-
element: <Expression
|
|
56
|
-
separator:
|
|
83
|
+
yield i`eat(<*Punctuator '[' balanced=']' /> 'openToken')`;
|
|
84
|
+
yield i`eat(<List /> 'elements[]$' {
|
|
85
|
+
element: <Expression />
|
|
86
|
+
separator: <*Punctuator ',' />
|
|
57
87
|
allowTrailingSeparator: false
|
|
58
88
|
})`;
|
|
59
|
-
yield i`eat(
|
|
89
|
+
yield i`eat(<*Punctuator ']' balancer /> 'closeToken')`;
|
|
60
90
|
}
|
|
61
91
|
|
|
62
92
|
@CoveredBy('Expression')
|
|
63
93
|
@Node
|
|
64
94
|
*Object() {
|
|
65
|
-
yield i`eat(
|
|
66
|
-
yield i`eat(<List
|
|
67
|
-
element: <Property
|
|
68
|
-
separator:
|
|
95
|
+
yield i`eat(<*Punctuator '{' balanced='}' /> 'openToken')`;
|
|
96
|
+
yield i`eat(<List /> 'properties[]$' {
|
|
97
|
+
element: <Property />
|
|
98
|
+
separator: <*Punctuator ',' />
|
|
69
99
|
allowTrailingSeparator: false
|
|
70
100
|
})`;
|
|
71
|
-
yield i`eat(
|
|
101
|
+
yield i`eat(<*Punctuator '}' balancer /> 'closeToken')`;
|
|
72
102
|
}
|
|
73
103
|
|
|
74
104
|
@Node
|
|
75
105
|
*Property() {
|
|
76
|
-
yield i`eat(<String
|
|
77
|
-
yield i`eat(
|
|
78
|
-
yield i`eat(<Expression
|
|
106
|
+
yield i`eat(<String /> 'key$')`;
|
|
107
|
+
yield i`eat(<*Punctuator ':' /> 'sigilToken')`;
|
|
108
|
+
yield i`eat(<Expression /> 'value$')`;
|
|
79
109
|
}
|
|
80
110
|
|
|
81
111
|
@CoveredBy('Language')
|
|
82
112
|
@Node
|
|
83
113
|
*String() {
|
|
84
|
-
yield i`eat(
|
|
85
|
-
yield i`eat(<*StringContent
|
|
86
|
-
yield i`eat(
|
|
114
|
+
yield i`eat(<*Punctuator '"' balanced='"' balancedSpan='String' /> 'openToken')`;
|
|
115
|
+
yield i`eat(<*StringContent /> 'content')`;
|
|
116
|
+
yield i`eat(<*Punctuator '"' balancer /> 'closeToken')`;
|
|
87
117
|
}
|
|
88
118
|
|
|
89
119
|
@AllowEmpty
|
|
@@ -91,62 +121,54 @@ export const grammar = triviaEnhancer(
|
|
|
91
121
|
*StringContent() {
|
|
92
122
|
let esc, lit;
|
|
93
123
|
do {
|
|
94
|
-
esc = (yield i`match('\\')`) && (yield i`eat(<@EscapeSequence
|
|
95
|
-
lit = yield i`eatMatch(/[^\r\n\\"]+/)`;
|
|
124
|
+
esc = (yield i`match('\\')`) && (yield i`eat(<@EscapeSequence />)`);
|
|
125
|
+
lit = yield i`eatMatch(/[^\r\n\\"\g]+/)`;
|
|
96
126
|
} while (esc || lit);
|
|
97
127
|
}
|
|
98
128
|
|
|
99
|
-
@Attributes(['cooked'])
|
|
100
129
|
@Node
|
|
101
130
|
*EscapeSequence({ state: { span }, ctx }) {
|
|
102
131
|
if (!span.startsWith('String')) {
|
|
103
132
|
yield i`fail()`;
|
|
104
133
|
}
|
|
105
134
|
|
|
106
|
-
yield i`eat(
|
|
135
|
+
yield i`eat(<*Punctuator '\\' openSpan='Escape' /> 'sigilToken')`;
|
|
107
136
|
|
|
108
|
-
let match
|
|
137
|
+
let match;
|
|
109
138
|
|
|
110
139
|
if ((match = yield i`match(/[\\/bfnrt"]/)`)) {
|
|
111
140
|
const match_ = ctx.sourceTextFor(match);
|
|
112
|
-
yield i`eat(
|
|
113
|
-
cooked = escapables.get(match_) || match_;
|
|
141
|
+
yield i`eat(<*Keyword ${buildString(match_)} closeSpan='Escape' /> 'code')`;
|
|
114
142
|
} else if (yield i`match('u')`) {
|
|
115
|
-
|
|
116
|
-
cooked = parseInt(
|
|
117
|
-
codeNode.properties.digits.map((digit) => ctx.sourceTextFor(digit)).join(''),
|
|
118
|
-
16,
|
|
119
|
-
);
|
|
143
|
+
yield i`eat(<EscapeCode closeSpan='Escape' /> 'code')`;
|
|
120
144
|
} else {
|
|
121
145
|
yield i`fail()`;
|
|
122
146
|
}
|
|
123
|
-
|
|
124
|
-
yield i`bindAttribute(cooked ${buildString(cooked.toString(10))})`;
|
|
125
147
|
}
|
|
126
148
|
|
|
127
149
|
@Node
|
|
128
150
|
*EscapeCode() {
|
|
129
|
-
yield i`eat(
|
|
130
|
-
yield i`eat(
|
|
151
|
+
yield i`eat(<*Keyword 'u' /> 'typeToken')`;
|
|
152
|
+
yield i`eat(<*UnsignedInteger /> 'value$')`;
|
|
131
153
|
}
|
|
132
154
|
|
|
133
155
|
@CoveredBy('Expression')
|
|
134
156
|
@Node
|
|
135
157
|
*Number() {
|
|
136
|
-
yield i`eat(<Integer
|
|
158
|
+
yield i`eat(<Integer /> 'wholePart' { noDoubleZero: true matchSign: '-' })`;
|
|
137
159
|
|
|
138
|
-
let fs = yield i`eatMatch(
|
|
160
|
+
let fs = yield i`eatMatch(<*Punctuator '.' /> 'fractionalSeparatorToken')`;
|
|
139
161
|
|
|
140
162
|
if (fs) {
|
|
141
|
-
yield i`eat(<Integer
|
|
163
|
+
yield i`eat(<Integer /> 'fractionalPart')`;
|
|
142
164
|
} else {
|
|
143
165
|
yield i`eat(null 'fractionalPart')`;
|
|
144
166
|
}
|
|
145
167
|
|
|
146
|
-
let es = yield i`eatMatch(
|
|
168
|
+
let es = yield i`eatMatch(<*Punctuator /[eE]/ /> 'exponentSeparatorToken')`;
|
|
147
169
|
|
|
148
170
|
if (es) {
|
|
149
|
-
yield i`eat(<Integer
|
|
171
|
+
yield i`eat(<Integer /> 'exponentPart' { matchSign: /[+-]/ })`;
|
|
150
172
|
} else {
|
|
151
173
|
yield i`eat(null 'exponentPart')`;
|
|
152
174
|
}
|
|
@@ -157,19 +179,19 @@ export const grammar = triviaEnhancer(
|
|
|
157
179
|
const { matchSign = null, noDoubleZero = false } = (props && ctx.unbox(props)) || {};
|
|
158
180
|
|
|
159
181
|
if (matchSign) {
|
|
160
|
-
yield i`eatMatch(
|
|
182
|
+
yield i`eatMatch(<*Punctuator ${matchSign} /> 'signToken')`;
|
|
161
183
|
} else {
|
|
162
184
|
yield i`eat(null 'signToken')`;
|
|
163
185
|
}
|
|
164
186
|
|
|
165
|
-
yield i`eat(<*UnsignedInteger noDoubleZero=${buildBoolean(noDoubleZero)}
|
|
187
|
+
yield i`eat(<*UnsignedInteger noDoubleZero=${buildBoolean(noDoubleZero)} /> 'value')`;
|
|
166
188
|
}
|
|
167
189
|
|
|
168
190
|
@Node
|
|
169
191
|
*UnsignedInteger({ value: props, ctx }) {
|
|
170
192
|
const { noDoubleZero = false } = (props && ctx.unbox(props)) || {};
|
|
171
193
|
|
|
172
|
-
let [firstDigit] = ctx.
|
|
194
|
+
let [firstDigit] = ctx.allTagsFor(yield i`eat(/\d/)`);
|
|
173
195
|
|
|
174
196
|
if (!noDoubleZero || firstDigit.value !== '0') {
|
|
175
197
|
yield i`eatMatch(/\d+/)`;
|
|
@@ -179,13 +201,13 @@ export const grammar = triviaEnhancer(
|
|
|
179
201
|
@CoveredBy('Expression')
|
|
180
202
|
@Node
|
|
181
203
|
*Boolean() {
|
|
182
|
-
yield i`eat(
|
|
204
|
+
yield i`eat(<*Keyword /true|false/ /> 'sigilToken')`;
|
|
183
205
|
}
|
|
184
206
|
|
|
185
207
|
@CoveredBy('Expression')
|
|
186
208
|
@Node
|
|
187
209
|
*Null() {
|
|
188
|
-
yield i`eat(
|
|
210
|
+
yield i`eat(<*Keyword 'null' /> 'sigilToken')`;
|
|
189
211
|
}
|
|
190
212
|
|
|
191
213
|
@Node
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bablr/language-en-json",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "A BABLR language for JSON",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=12.0.0"
|
|
@@ -21,26 +21,26 @@
|
|
|
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.5.0",
|
|
25
|
+
"@bablr/agast-vm-helpers": "^0.5.0",
|
|
26
|
+
"@bablr/boot": "^0.6.0",
|
|
27
|
+
"@bablr/helpers": "^0.20.0",
|
|
28
|
+
"@bablr/language-en-blank-space": "^0.5.0",
|
|
29
29
|
"@babel/runtime": "^7.22.15"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@bablr/eslint-config-base": "github:bablr-lang/eslint-config-base#49f5952efed27f94ee9b94340eb1563c440bf64e",
|
|
33
|
-
"@bablr/macrome": "0.1.3",
|
|
34
|
-
"@bablr/macrome-generator-bablr": "0.3.
|
|
33
|
+
"@bablr/macrome": "^0.1.3",
|
|
34
|
+
"@bablr/macrome-generator-bablr": "^0.3.2",
|
|
35
35
|
"@qnighy/dedent": "0.1.1",
|
|
36
|
-
"bablr": "0.
|
|
36
|
+
"bablr": "^0.6.0",
|
|
37
37
|
"enhanced-resolve": "^5.12.0",
|
|
38
38
|
"eslint": "^7.32.0",
|
|
39
39
|
"eslint-import-resolver-enhanced-resolve": "^1.0.5",
|
|
40
40
|
"eslint-plugin-import": "^2.27.5",
|
|
41
41
|
"expect": "29.7.0",
|
|
42
42
|
"iter-tools-es": "^7.5.3",
|
|
43
|
-
"mocha": "10.4.0",
|
|
43
|
+
"mocha": "^10.4.0",
|
|
44
44
|
"prettier": "^2.0.5"
|
|
45
45
|
},
|
|
46
46
|
"keywords": [
|