spex-parser 0.1.4 → 0.6.1
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 +312 -1
- package/dist/ast.d.ts +70 -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 +19 -1
- package/dist/lexer.d.ts.map +1 -1
- package/dist/lexer.js +172 -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 +103 -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 +181 -8
- package/dist/visitor.js.map +1 -1
- package/package.json +1 -1
- package/src/ast.ts +93 -0
- package/src/constants.ts +40 -0
- package/src/index.ts +20 -3
- package/src/lexer.ts +164 -6
- package/src/parser.ts +128 -7
- package/src/visitor.ts +195 -11
- package/tests/constants.test.ts +102 -0
- package/tests/e2e.test.ts +15 -3
- package/tests/lexer.test.ts +291 -9
- package/tests/parser.test.ts +489 -0
- 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 +100 -60
- package/tests/props/typescript_cli_env.spex +16 -0
- package/tests/props/typescript_todo_cli.spex +70 -0
- package/tests/visitor.test.ts +892 -0
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',
|
|
@@ -6,6 +6,18 @@ export const WhiteSpace = createToken({
|
|
|
6
6
|
group: Lexer.SKIPPED,
|
|
7
7
|
})
|
|
8
8
|
|
|
9
|
+
// Comments (SQL-style)
|
|
10
|
+
export const LineComment = createToken({
|
|
11
|
+
name: 'LineComment',
|
|
12
|
+
pattern: /--[^\r\n]*/,
|
|
13
|
+
group: Lexer.SKIPPED,
|
|
14
|
+
})
|
|
15
|
+
export const BlockComment = createToken({
|
|
16
|
+
name: 'BlockComment',
|
|
17
|
+
pattern: /\/\*[\s\S]*?\*\//,
|
|
18
|
+
group: Lexer.SKIPPED,
|
|
19
|
+
})
|
|
20
|
+
|
|
9
21
|
// Keywords (case-insensitive)
|
|
10
22
|
export const CreateTok = createToken({
|
|
11
23
|
name: 'CreateTok',
|
|
@@ -47,9 +59,42 @@ export const ModuleTok = createToken({
|
|
|
47
59
|
name: 'ModuleTok',
|
|
48
60
|
pattern: /module\b/i,
|
|
49
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
|
+
})
|
|
50
94
|
|
|
51
95
|
// Symbols
|
|
52
96
|
export const ArrowTok = createToken({ name: 'ArrowTok', pattern: /->/ })
|
|
97
|
+
export const PipeTok = createToken({ name: 'PipeTok', pattern: /\|/ })
|
|
53
98
|
export const LCurly = createToken({ name: 'LCurly', pattern: /{/ })
|
|
54
99
|
export const RCurly = createToken({ name: 'RCurly', pattern: /}/ })
|
|
55
100
|
export const LBracket = createToken({ name: 'LBracket', pattern: /\[/ })
|
|
@@ -64,13 +109,100 @@ export const Dot = createToken({ name: 'Dot', pattern: /\./ })
|
|
|
64
109
|
// Brace text block (for SELECT { ... })
|
|
65
110
|
export const SelectBlock = createToken({
|
|
66
111
|
name: 'SelectBlock',
|
|
67
|
-
|
|
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
|
+
},
|
|
68
188
|
})
|
|
69
189
|
|
|
70
190
|
// Literals
|
|
71
|
-
export const
|
|
72
|
-
name: '
|
|
73
|
-
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,
|
|
74
206
|
})
|
|
75
207
|
|
|
76
208
|
// Basic objects (native types)
|
|
@@ -90,6 +222,14 @@ export const UnitTok = createToken({
|
|
|
90
222
|
name: 'UnitTok',
|
|
91
223
|
pattern: /unit\b/i,
|
|
92
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
|
+
})
|
|
93
233
|
|
|
94
234
|
// Identifiers
|
|
95
235
|
export const Identifier = createToken({
|
|
@@ -99,6 +239,8 @@ export const Identifier = createToken({
|
|
|
99
239
|
|
|
100
240
|
export const allTokens = [
|
|
101
241
|
WhiteSpace,
|
|
242
|
+
LineComment,
|
|
243
|
+
BlockComment,
|
|
102
244
|
|
|
103
245
|
CreateTok,
|
|
104
246
|
AsTok,
|
|
@@ -110,8 +252,17 @@ export const allTokens = [
|
|
|
110
252
|
PackageTok,
|
|
111
253
|
ExecutableTok,
|
|
112
254
|
ModuleTok,
|
|
255
|
+
EnumTok,
|
|
256
|
+
UnionTok,
|
|
257
|
+
IntersectTok,
|
|
258
|
+
ExceptTok,
|
|
259
|
+
RealizeTok,
|
|
260
|
+
InTok,
|
|
261
|
+
IncludeTok,
|
|
262
|
+
LambdaTok,
|
|
113
263
|
|
|
114
264
|
ArrowTok,
|
|
265
|
+
PipeTok,
|
|
115
266
|
SelectBlock,
|
|
116
267
|
LCurly,
|
|
117
268
|
RCurly,
|
|
@@ -123,12 +274,19 @@ export const allTokens = [
|
|
|
123
274
|
Comma,
|
|
124
275
|
Semicolon,
|
|
125
276
|
Dot,
|
|
126
|
-
|
|
277
|
+
StringLiteral,
|
|
278
|
+
NumberLiteral,
|
|
279
|
+
TrueTok,
|
|
280
|
+
FalseTok,
|
|
281
|
+
PatternLiteral,
|
|
282
|
+
CodeBlock,
|
|
127
283
|
|
|
128
284
|
StringTok,
|
|
129
285
|
NumberTok,
|
|
130
286
|
BoolTok,
|
|
131
287
|
UnitTok,
|
|
288
|
+
ConceptTok,
|
|
289
|
+
EnvironmentTok,
|
|
132
290
|
|
|
133
291
|
Identifier,
|
|
134
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,35 @@ 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)
|
|
184
277
|
this.CONSUME(Semicolon)
|
|
185
278
|
})
|
|
279
|
+
|
|
280
|
+
private realizeDeclaration = this.RULE('realizeDeclaration', () => {
|
|
281
|
+
this.CONSUME(RealizeTok)
|
|
282
|
+
this.SUBRULE(this.setObject, { LABEL: 'object' })
|
|
283
|
+
this.CONSUME(AsTok)
|
|
284
|
+
this.SUBRULE2(this.setObject, { LABEL: 'target' })
|
|
285
|
+
this.OPTION(() => {
|
|
286
|
+
this.CONSUME(InTok)
|
|
287
|
+
this.SUBRULE3(this.setObject, { LABEL: 'environment' })
|
|
288
|
+
})
|
|
289
|
+
this.CONSUME(Semicolon)
|
|
290
|
+
})
|
|
291
|
+
|
|
292
|
+
private includeDeclaration = this.RULE('includeDeclaration', () => {
|
|
293
|
+
this.CONSUME(IncludeTok)
|
|
294
|
+
this.CONSUME(StringLiteral)
|
|
295
|
+
this.CONSUME(AsTok)
|
|
296
|
+
this.CONSUME(Identifier)
|
|
297
|
+
this.CONSUME(Semicolon)
|
|
298
|
+
})
|
|
299
|
+
|
|
300
|
+
private lambdaObject = this.RULE('lambdaObject', () => {
|
|
301
|
+
this.CONSUME(LambdaTok)
|
|
302
|
+
this.SUBRULE(this.objectOperand, { LABEL: 'base' })
|
|
303
|
+
this.CONSUME(ArrowTok)
|
|
304
|
+
this.SUBRULE(this.setObject, { LABEL: 'exponent' })
|
|
305
|
+
this.CONSUME(CodeBlock)
|
|
306
|
+
})
|
|
186
307
|
}
|