spex-parser 0.1.5 → 0.6.2
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/README.md +320 -9
- package/dist/ast.d.ts +71 -2
- package/dist/ast.d.ts.map +1 -1
- package/dist/constants.d.ts +20 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +32 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lexer.d.ts +17 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +159 -5
- package/dist/lexer.js.map +1 -1
- package/dist/parser.d.ts +9 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +105 -7
- package/dist/parser.js.map +1 -1
- package/dist/visitor.d.ts +11 -2
- package/dist/visitor.d.ts.map +1 -1
- package/dist/visitor.js +182 -8
- package/dist/visitor.js.map +1 -1
- package/package.json +1 -1
- package/src/ast.ts +94 -0
- package/src/constants.ts +40 -0
- package/src/index.ts +20 -3
- package/src/lexer.ts +150 -6
- package/src/parser.ts +130 -7
- package/src/visitor.ts +196 -11
- package/tests/constants.test.ts +102 -0
- package/tests/e2e.test.ts +15 -3
- package/tests/lexer.test.ts +230 -9
- package/tests/parser.test.ts +455 -10
- package/tests/props/express_todo_web.spex +108 -0
- package/tests/props/express_web_env.spex +16 -0
- package/tests/props/flask_todo_web.spex +111 -0
- package/tests/props/flask_web_env.spex +16 -0
- package/tests/props/python_cli_env.spex +16 -0
- package/tests/props/python_todo_cli.spex +70 -0
- package/tests/props/todo.spex +99 -68
- package/tests/props/typescript_cli_env.spex +16 -0
- package/tests/props/typescript_todo_cli.spex +70 -0
- package/tests/visitor.test.ts +905 -6
package/src/lexer.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createToken, Lexer } from 'chevrotain'
|
|
1
|
+
import { createToken, Lexer, type CustomPatternMatcherReturn } from 'chevrotain'
|
|
2
2
|
|
|
3
3
|
export const WhiteSpace = createToken({
|
|
4
4
|
name: 'WhiteSpace',
|
|
@@ -59,9 +59,42 @@ export const ModuleTok = createToken({
|
|
|
59
59
|
name: 'ModuleTok',
|
|
60
60
|
pattern: /module\b/i,
|
|
61
61
|
})
|
|
62
|
+
export const EnumTok = createToken({
|
|
63
|
+
name: 'EnumTok',
|
|
64
|
+
pattern: /enum\b/i,
|
|
65
|
+
})
|
|
66
|
+
export const UnionTok = createToken({
|
|
67
|
+
name: 'UnionTok',
|
|
68
|
+
pattern: /union\b/i,
|
|
69
|
+
})
|
|
70
|
+
export const IntersectTok = createToken({
|
|
71
|
+
name: 'IntersectTok',
|
|
72
|
+
pattern: /intersect\b/i,
|
|
73
|
+
})
|
|
74
|
+
export const ExceptTok = createToken({
|
|
75
|
+
name: 'ExceptTok',
|
|
76
|
+
pattern: /except\b/i,
|
|
77
|
+
})
|
|
78
|
+
export const RealizeTok = createToken({
|
|
79
|
+
name: 'RealizeTok',
|
|
80
|
+
pattern: /realize\b/i,
|
|
81
|
+
})
|
|
82
|
+
export const InTok = createToken({
|
|
83
|
+
name: 'InTok',
|
|
84
|
+
pattern: /in\b/i,
|
|
85
|
+
})
|
|
86
|
+
export const IncludeTok = createToken({
|
|
87
|
+
name: 'IncludeTok',
|
|
88
|
+
pattern: /include\b/i,
|
|
89
|
+
})
|
|
90
|
+
export const LambdaTok = createToken({
|
|
91
|
+
name: 'LambdaTok',
|
|
92
|
+
pattern: /lambda\b/i,
|
|
93
|
+
})
|
|
62
94
|
|
|
63
95
|
// Symbols
|
|
64
96
|
export const ArrowTok = createToken({ name: 'ArrowTok', pattern: /->/ })
|
|
97
|
+
export const PipeTok = createToken({ name: 'PipeTok', pattern: /\|/ })
|
|
65
98
|
export const LCurly = createToken({ name: 'LCurly', pattern: /{/ })
|
|
66
99
|
export const RCurly = createToken({ name: 'RCurly', pattern: /}/ })
|
|
67
100
|
export const LBracket = createToken({ name: 'LBracket', pattern: /\[/ })
|
|
@@ -76,13 +109,100 @@ export const Dot = createToken({ name: 'Dot', pattern: /\./ })
|
|
|
76
109
|
// Brace text block (for SELECT { ... })
|
|
77
110
|
export const SelectBlock = createToken({
|
|
78
111
|
name: 'SelectBlock',
|
|
79
|
-
|
|
112
|
+
line_breaks: true,
|
|
113
|
+
pattern: (text: string, startOffset: number): CustomPatternMatcherReturn | null => {
|
|
114
|
+
let i = startOffset
|
|
115
|
+
if (text[i] !== '{') return null
|
|
116
|
+
for (i++; i < text.length; i++) {
|
|
117
|
+
if (text[i] === '\\') {
|
|
118
|
+
i++
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
if (text[i] === '}') {
|
|
122
|
+
return [text.slice(startOffset, i + 1)]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return null
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Regex literal (JS-style): /pattern/flags
|
|
130
|
+
export const PatternLiteral = createToken({
|
|
131
|
+
name: 'PatternLiteral',
|
|
132
|
+
line_breaks: true,
|
|
133
|
+
pattern: (text: string, startOffset: number): CustomPatternMatcherReturn | null => {
|
|
134
|
+
if (text[startOffset] !== '/') return null
|
|
135
|
+
let inClass = false
|
|
136
|
+
let i = startOffset + 1
|
|
137
|
+
while (i < text.length) {
|
|
138
|
+
const ch = text[i]
|
|
139
|
+
if (ch === '\\') {
|
|
140
|
+
i += 2
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
if (inClass) {
|
|
144
|
+
if (ch === ']') inClass = false
|
|
145
|
+
} else if (ch === '[') {
|
|
146
|
+
inClass = true
|
|
147
|
+
} else if (ch === '/') {
|
|
148
|
+
let j = i + 1
|
|
149
|
+
while (j < text.length && /[a-z]/.test(text[j] ?? '')) j++
|
|
150
|
+
return [text.slice(startOffset, j)]
|
|
151
|
+
}
|
|
152
|
+
i++
|
|
153
|
+
}
|
|
154
|
+
return null
|
|
155
|
+
},
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
// Code block: ```language\n...content...```
|
|
159
|
+
export const CodeBlock = createToken({
|
|
160
|
+
name: 'CodeBlock',
|
|
161
|
+
line_breaks: true,
|
|
162
|
+
pattern: (text: string, startOffset: number): CustomPatternMatcherReturn | null => {
|
|
163
|
+
if (text[startOffset] !== '`' || text[startOffset + 1] !== '`' || text[startOffset + 2] !== '`')
|
|
164
|
+
return null
|
|
165
|
+
let i = startOffset + 3
|
|
166
|
+
// require at least one language identifier character
|
|
167
|
+
if (i >= text.length || !/[a-zA-Z0-9_]/.test(text[i]!)) return null
|
|
168
|
+
const langStart = i
|
|
169
|
+
while (i < text.length && text[i] !== '\n' && text[i] !== '\r') i++
|
|
170
|
+
if (i === langStart) return null // no language identifier
|
|
171
|
+
if (i >= text.length) return null
|
|
172
|
+
// skip line ending
|
|
173
|
+
if (text[i] === '\r' && text[i + 1] === '\n') i += 2
|
|
174
|
+
else i++
|
|
175
|
+
// find closing ```
|
|
176
|
+
while (i < text.length - 2) {
|
|
177
|
+
if (text[i] === '\\') {
|
|
178
|
+
i += 2
|
|
179
|
+
continue
|
|
180
|
+
}
|
|
181
|
+
if (text[i] === '`' && text[i + 1] === '`' && text[i + 2] === '`') {
|
|
182
|
+
return [text.slice(startOffset, i + 3)]
|
|
183
|
+
}
|
|
184
|
+
i++
|
|
185
|
+
}
|
|
186
|
+
return null
|
|
187
|
+
},
|
|
80
188
|
})
|
|
81
189
|
|
|
82
190
|
// Literals
|
|
83
|
-
export const
|
|
84
|
-
name: '
|
|
85
|
-
pattern: /"([^"\\]|\\.)*"/,
|
|
191
|
+
export const StringLiteral = createToken({
|
|
192
|
+
name: 'StringLiteral',
|
|
193
|
+
pattern: /'([^'\\]|\\.)*'|"([^"\\]|\\.)*"/,
|
|
194
|
+
})
|
|
195
|
+
export const NumberLiteral = createToken({
|
|
196
|
+
name: 'NumberLiteral',
|
|
197
|
+
pattern: /\d+(\.\d+)?/,
|
|
198
|
+
})
|
|
199
|
+
export const TrueTok = createToken({
|
|
200
|
+
name: 'TrueTok',
|
|
201
|
+
pattern: /true\b/i,
|
|
202
|
+
})
|
|
203
|
+
export const FalseTok = createToken({
|
|
204
|
+
name: 'FalseTok',
|
|
205
|
+
pattern: /false\b/i,
|
|
86
206
|
})
|
|
87
207
|
|
|
88
208
|
// Basic objects (native types)
|
|
@@ -102,6 +222,14 @@ export const UnitTok = createToken({
|
|
|
102
222
|
name: 'UnitTok',
|
|
103
223
|
pattern: /unit\b/i,
|
|
104
224
|
})
|
|
225
|
+
export const ConceptTok = createToken({
|
|
226
|
+
name: 'ConceptTok',
|
|
227
|
+
pattern: /concept\b/i,
|
|
228
|
+
})
|
|
229
|
+
export const EnvironmentTok = createToken({
|
|
230
|
+
name: 'EnvironmentTok',
|
|
231
|
+
pattern: /environment\b/i,
|
|
232
|
+
})
|
|
105
233
|
|
|
106
234
|
// Identifiers
|
|
107
235
|
export const Identifier = createToken({
|
|
@@ -124,8 +252,17 @@ export const allTokens = [
|
|
|
124
252
|
PackageTok,
|
|
125
253
|
ExecutableTok,
|
|
126
254
|
ModuleTok,
|
|
255
|
+
EnumTok,
|
|
256
|
+
UnionTok,
|
|
257
|
+
IntersectTok,
|
|
258
|
+
ExceptTok,
|
|
259
|
+
RealizeTok,
|
|
260
|
+
InTok,
|
|
261
|
+
IncludeTok,
|
|
262
|
+
LambdaTok,
|
|
127
263
|
|
|
128
264
|
ArrowTok,
|
|
265
|
+
PipeTok,
|
|
129
266
|
SelectBlock,
|
|
130
267
|
LCurly,
|
|
131
268
|
RCurly,
|
|
@@ -137,12 +274,19 @@ export const allTokens = [
|
|
|
137
274
|
Comma,
|
|
138
275
|
Semicolon,
|
|
139
276
|
Dot,
|
|
140
|
-
|
|
277
|
+
StringLiteral,
|
|
278
|
+
NumberLiteral,
|
|
279
|
+
TrueTok,
|
|
280
|
+
FalseTok,
|
|
281
|
+
PatternLiteral,
|
|
282
|
+
CodeBlock,
|
|
141
283
|
|
|
142
284
|
StringTok,
|
|
143
285
|
NumberTok,
|
|
144
286
|
BoolTok,
|
|
145
287
|
UnitTok,
|
|
288
|
+
ConceptTok,
|
|
289
|
+
EnvironmentTok,
|
|
146
290
|
|
|
147
291
|
Identifier,
|
|
148
292
|
]
|
package/src/parser.ts
CHANGED
|
@@ -11,8 +11,18 @@ import {
|
|
|
11
11
|
PackageTok,
|
|
12
12
|
ExecutableTok,
|
|
13
13
|
ModuleTok,
|
|
14
|
+
EnumTok,
|
|
15
|
+
UnionTok,
|
|
16
|
+
IntersectTok,
|
|
17
|
+
ExceptTok,
|
|
18
|
+
RealizeTok,
|
|
19
|
+
InTok,
|
|
20
|
+
IncludeTok,
|
|
21
|
+
LambdaTok,
|
|
14
22
|
ArrowTok,
|
|
23
|
+
PipeTok,
|
|
15
24
|
SelectBlock,
|
|
25
|
+
CodeBlock,
|
|
16
26
|
LBracket,
|
|
17
27
|
RBracket,
|
|
18
28
|
LParen,
|
|
@@ -22,11 +32,17 @@ import {
|
|
|
22
32
|
Semicolon,
|
|
23
33
|
Dot,
|
|
24
34
|
Identifier,
|
|
25
|
-
|
|
35
|
+
StringLiteral,
|
|
36
|
+
NumberLiteral,
|
|
37
|
+
TrueTok,
|
|
38
|
+
FalseTok,
|
|
39
|
+
PatternLiteral,
|
|
26
40
|
StringTok,
|
|
27
41
|
NumberTok,
|
|
28
42
|
BoolTok,
|
|
29
43
|
UnitTok,
|
|
44
|
+
ConceptTok,
|
|
45
|
+
EnvironmentTok,
|
|
30
46
|
} from './lexer.js'
|
|
31
47
|
|
|
32
48
|
export class SpexParser extends CstParser {
|
|
@@ -43,6 +59,10 @@ export class SpexParser extends CstParser {
|
|
|
43
59
|
|
|
44
60
|
private declaration = this.RULE('declaration', () => {
|
|
45
61
|
this.OR([
|
|
62
|
+
{
|
|
63
|
+
GATE: this.BACKTRACK(this.realizeDeclaration),
|
|
64
|
+
ALT: () => this.SUBRULE(this.realizeDeclaration),
|
|
65
|
+
},
|
|
46
66
|
{
|
|
47
67
|
GATE: this.BACKTRACK(this.packageDeclaration),
|
|
48
68
|
ALT: () => this.SUBRULE(this.packageDeclaration),
|
|
@@ -59,6 +79,10 @@ export class SpexParser extends CstParser {
|
|
|
59
79
|
GATE: this.BACKTRACK(this.exportDeclaration),
|
|
60
80
|
ALT: () => this.SUBRULE(this.exportDeclaration),
|
|
61
81
|
},
|
|
82
|
+
{
|
|
83
|
+
GATE: this.BACKTRACK(this.includeDeclaration),
|
|
84
|
+
ALT: () => this.SUBRULE(this.includeDeclaration),
|
|
85
|
+
},
|
|
62
86
|
{
|
|
63
87
|
ALT: () => this.SUBRULE(this.generateDeclaration),
|
|
64
88
|
},
|
|
@@ -69,10 +93,50 @@ export class SpexParser extends CstParser {
|
|
|
69
93
|
this.CONSUME(CreateTok)
|
|
70
94
|
this.CONSUME(Identifier)
|
|
71
95
|
this.CONSUME(AsTok)
|
|
72
|
-
this.SUBRULE(this.
|
|
96
|
+
this.SUBRULE(this.setObject)
|
|
73
97
|
this.CONSUME(Semicolon)
|
|
74
98
|
})
|
|
75
99
|
|
|
100
|
+
private setObject = this.RULE('setObject', () => {
|
|
101
|
+
this.SUBRULE(this.coproductObject)
|
|
102
|
+
this.MANY(() => {
|
|
103
|
+
this.OR([
|
|
104
|
+
{ ALT: () => this.CONSUME(UnionTok, { LABEL: 'op' }) },
|
|
105
|
+
{ ALT: () => this.CONSUME(IntersectTok, { LABEL: 'op' }) },
|
|
106
|
+
{ ALT: () => this.CONSUME(ExceptTok, { LABEL: 'op' }) },
|
|
107
|
+
])
|
|
108
|
+
this.SUBRULE2(this.coproductObject)
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
private coproductObject = this.RULE('coproductObject', () => {
|
|
113
|
+
this.SUBRULE(this.objectExpression)
|
|
114
|
+
this.MANY(() => {
|
|
115
|
+
this.CONSUME(PipeTok, { LABEL: 'op' })
|
|
116
|
+
this.SUBRULE2(this.objectExpression)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
private enumObject = this.RULE('enumObject', () => {
|
|
121
|
+
this.CONSUME(EnumTok)
|
|
122
|
+
this.CONSUME(LParen)
|
|
123
|
+
this.CONSUME(StringLiteral)
|
|
124
|
+
this.MANY(() => {
|
|
125
|
+
this.CONSUME(Comma)
|
|
126
|
+
this.CONSUME2(StringLiteral)
|
|
127
|
+
})
|
|
128
|
+
this.CONSUME(RParen)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
private literalObject = this.RULE('literalObject', () => {
|
|
132
|
+
this.OR([
|
|
133
|
+
{ ALT: () => this.CONSUME(StringLiteral) },
|
|
134
|
+
{ ALT: () => this.CONSUME(NumberLiteral) },
|
|
135
|
+
{ ALT: () => this.CONSUME(TrueTok) },
|
|
136
|
+
{ ALT: () => this.CONSUME(FalseTok) },
|
|
137
|
+
])
|
|
138
|
+
})
|
|
139
|
+
|
|
76
140
|
private objectExpression = this.RULE('objectExpression', () => {
|
|
77
141
|
this.SUBRULE(this.objectOperand, { LABEL: 'base' })
|
|
78
142
|
this.OPTION(() => {
|
|
@@ -83,10 +147,27 @@ export class SpexParser extends CstParser {
|
|
|
83
147
|
|
|
84
148
|
private objectOperand = this.RULE('objectOperand', () => {
|
|
85
149
|
this.OR([
|
|
150
|
+
{
|
|
151
|
+
ALT: () => this.SUBRULE(this.literalObject),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
ALT: () => this.SUBRULE(this.enumObject),
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
ALT: () => this.SUBRULE(this.patternObject),
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
GATE: this.BACKTRACK(this.lambdaObject),
|
|
161
|
+
ALT: () => this.SUBRULE(this.lambdaObject),
|
|
162
|
+
},
|
|
86
163
|
{
|
|
87
164
|
GATE: this.BACKTRACK(this.subObject),
|
|
88
165
|
ALT: () => this.SUBRULE(this.subObject),
|
|
89
166
|
},
|
|
167
|
+
{
|
|
168
|
+
GATE: this.BACKTRACK(this.parenthesizedObject),
|
|
169
|
+
ALT: () => this.SUBRULE(this.parenthesizedObject),
|
|
170
|
+
},
|
|
90
171
|
{
|
|
91
172
|
GATE: this.BACKTRACK(this.productObject),
|
|
92
173
|
ALT: () => this.SUBRULE(this.productObject),
|
|
@@ -101,6 +182,16 @@ export class SpexParser extends CstParser {
|
|
|
101
182
|
})
|
|
102
183
|
})
|
|
103
184
|
|
|
185
|
+
private parenthesizedObject = this.RULE('parenthesizedObject', () => {
|
|
186
|
+
this.CONSUME(LParen)
|
|
187
|
+
this.SUBRULE(this.setObject)
|
|
188
|
+
this.CONSUME(RParen)
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
private patternObject = this.RULE('patternObject', () => {
|
|
192
|
+
this.CONSUME(PatternLiteral)
|
|
193
|
+
})
|
|
194
|
+
|
|
104
195
|
private namedObject = this.RULE('namedObject', () => {
|
|
105
196
|
this.OR([
|
|
106
197
|
{ ALT: () => this.CONSUME(Identifier) },
|
|
@@ -108,6 +199,8 @@ export class SpexParser extends CstParser {
|
|
|
108
199
|
{ ALT: () => this.CONSUME(NumberTok) },
|
|
109
200
|
{ ALT: () => this.CONSUME(BoolTok) },
|
|
110
201
|
{ ALT: () => this.CONSUME(UnitTok) },
|
|
202
|
+
{ ALT: () => this.CONSUME(ConceptTok) },
|
|
203
|
+
{ ALT: () => this.CONSUME(EnvironmentTok) },
|
|
111
204
|
])
|
|
112
205
|
this.MANY(() => {
|
|
113
206
|
this.CONSUME(Dot)
|
|
@@ -120,7 +213,7 @@ export class SpexParser extends CstParser {
|
|
|
120
213
|
this.MANY(() => {
|
|
121
214
|
this.CONSUME(Identifier)
|
|
122
215
|
this.CONSUME(Colon)
|
|
123
|
-
this.SUBRULE(this.
|
|
216
|
+
this.SUBRULE(this.setObject)
|
|
124
217
|
this.OPTION(() => this.CONSUME(Comma))
|
|
125
218
|
})
|
|
126
219
|
this.CONSUME(RParen)
|
|
@@ -128,7 +221,7 @@ export class SpexParser extends CstParser {
|
|
|
128
221
|
|
|
129
222
|
private subObject = this.RULE('subObject', () => {
|
|
130
223
|
this.CONSUME(FromTok)
|
|
131
|
-
this.SUBRULE(this.
|
|
224
|
+
this.SUBRULE(this.setObject, { LABEL: 'base' })
|
|
132
225
|
this.CONSUME(SelectTok)
|
|
133
226
|
this.CONSUME(SelectBlock)
|
|
134
227
|
})
|
|
@@ -150,7 +243,7 @@ export class SpexParser extends CstParser {
|
|
|
150
243
|
private namedImport = this.RULE('namedImport', () => {
|
|
151
244
|
this.CONSUME(Identifier)
|
|
152
245
|
this.CONSUME(FromTok)
|
|
153
|
-
this.CONSUME(
|
|
246
|
+
this.CONSUME(StringLiteral)
|
|
154
247
|
this.OPTION(() => {
|
|
155
248
|
this.CONSUME(AsTok)
|
|
156
249
|
this.CONSUME2(Identifier)
|
|
@@ -158,7 +251,7 @@ export class SpexParser extends CstParser {
|
|
|
158
251
|
})
|
|
159
252
|
|
|
160
253
|
private moduleImport = this.RULE('moduleImport', () => {
|
|
161
|
-
this.CONSUME(
|
|
254
|
+
this.CONSUME(StringLiteral)
|
|
162
255
|
this.CONSUME(AsTok)
|
|
163
256
|
this.CONSUME(Identifier)
|
|
164
257
|
})
|
|
@@ -180,7 +273,37 @@ export class SpexParser extends CstParser {
|
|
|
180
273
|
this.OR([{ ALT: () => this.CONSUME(ExecutableTok) }, { ALT: () => this.CONSUME(ModuleTok) }])
|
|
181
274
|
this.CONSUME(Identifier)
|
|
182
275
|
this.CONSUME(AsTok)
|
|
183
|
-
this.SUBRULE(this.
|
|
276
|
+
this.SUBRULE(this.setObject)
|
|
277
|
+
this.CONSUME(InTok)
|
|
278
|
+
this.SUBRULE2(this.setObject, { LABEL: 'environment' })
|
|
184
279
|
this.CONSUME(Semicolon)
|
|
185
280
|
})
|
|
281
|
+
|
|
282
|
+
private realizeDeclaration = this.RULE('realizeDeclaration', () => {
|
|
283
|
+
this.CONSUME(RealizeTok)
|
|
284
|
+
this.SUBRULE(this.setObject, { LABEL: 'object' })
|
|
285
|
+
this.CONSUME(AsTok)
|
|
286
|
+
this.SUBRULE2(this.setObject, { LABEL: 'target' })
|
|
287
|
+
this.OPTION(() => {
|
|
288
|
+
this.CONSUME(InTok)
|
|
289
|
+
this.SUBRULE3(this.setObject, { LABEL: 'environment' })
|
|
290
|
+
})
|
|
291
|
+
this.CONSUME(Semicolon)
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
private includeDeclaration = this.RULE('includeDeclaration', () => {
|
|
295
|
+
this.CONSUME(IncludeTok)
|
|
296
|
+
this.CONSUME(StringLiteral)
|
|
297
|
+
this.CONSUME(AsTok)
|
|
298
|
+
this.CONSUME(Identifier)
|
|
299
|
+
this.CONSUME(Semicolon)
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
private lambdaObject = this.RULE('lambdaObject', () => {
|
|
303
|
+
this.CONSUME(LambdaTok)
|
|
304
|
+
this.SUBRULE(this.objectOperand, { LABEL: 'base' })
|
|
305
|
+
this.CONSUME(ArrowTok)
|
|
306
|
+
this.SUBRULE(this.setObject, { LABEL: 'exponent' })
|
|
307
|
+
this.CONSUME(CodeBlock)
|
|
308
|
+
})
|
|
186
309
|
}
|