@sap/cds-compiler 2.15.2 → 3.0.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/CHANGELOG.md +66 -1590
- package/bin/cdsc.js +42 -46
- package/doc/CHANGELOG_ARCHIVE.md +1592 -0
- package/doc/CHANGELOG_BETA.md +3 -4
- package/doc/CHANGELOG_DEPRECATED.md +35 -1
- package/doc/{DeprecatedOptions.md → DeprecatedOptions_v2.md} +3 -1
- package/doc/Versioning.md +20 -1
- package/lib/api/.eslintrc.json +2 -2
- package/lib/api/main.js +312 -143
- package/lib/api/options.js +15 -85
- package/lib/api/validate.js +6 -10
- package/lib/base/keywords.js +280 -110
- package/lib/base/message-registry.js +80 -24
- package/lib/base/messages.js +103 -52
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +53 -21
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +1 -1
- package/lib/checks/cdsPersistence.js +1 -0
- package/lib/checks/elements.js +6 -6
- package/lib/checks/invalidTarget.js +1 -1
- package/lib/checks/nonexpandableStructured.js +1 -1
- package/lib/checks/queryNoDbArtifacts.js +2 -1
- package/lib/checks/selectItems.js +5 -1
- package/lib/checks/types.js +4 -2
- package/lib/checks/utils.js +2 -2
- package/lib/checks/validator.js +2 -1
- package/lib/compiler/assert-consistency.js +15 -10
- package/lib/compiler/builtins.js +127 -10
- package/lib/compiler/define.js +6 -4
- package/lib/compiler/extend.js +63 -12
- package/lib/compiler/finalize-parse-cdl.js +20 -9
- package/lib/compiler/index.js +25 -11
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +16 -14
- package/lib/compiler/propagator.js +3 -3
- package/lib/compiler/resolve.js +194 -222
- package/lib/compiler/shared.js +56 -76
- package/lib/compiler/tweak-assocs.js +9 -10
- package/lib/compiler/utils.js +7 -2
- package/lib/edm/annotations/genericTranslation.js +60 -6
- package/lib/edm/annotations/preprocessAnnotations.js +10 -11
- package/lib/edm/csn2edm.js +39 -41
- package/lib/edm/edm.js +22 -15
- package/lib/edm/edmPreprocessor.js +66 -69
- package/lib/edm/edmUtils.js +12 -62
- package/lib/gen/Dictionary.json +8 -6
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +8 -30
- package/lib/gen/language.tokens +105 -114
- package/lib/gen/languageLexer.interp +1 -34
- package/lib/gen/languageLexer.js +889 -1007
- package/lib/gen/languageLexer.tokens +95 -106
- package/lib/gen/languageParser.js +20717 -22376
- package/lib/json/from-csn.js +73 -68
- package/lib/json/to-csn.js +13 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +61 -38
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +333 -259
- package/lib/language/language.g4 +600 -645
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +27 -42
- package/lib/main.js +104 -81
- package/lib/model/csnRefs.js +2 -1
- package/lib/model/csnUtils.js +183 -285
- package/lib/model/revealInternalProperties.js +32 -9
- package/lib/model/sortViews.js +32 -31
- package/lib/optionProcessor.js +64 -57
- package/lib/render/.eslintrc.json +1 -1
- package/lib/render/DuplicateChecker.js +4 -7
- package/lib/render/manageConstraints.js +70 -2
- package/lib/render/toCdl.js +334 -339
- package/lib/render/toHdbcds.js +20 -16
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +60 -54
- package/lib/render/utils/common.js +15 -1
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +3 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +1 -1
- package/lib/transform/db/expansion.js +7 -6
- package/lib/transform/db/flattening.js +18 -19
- package/lib/transform/db/views.js +3 -3
- package/lib/transform/draft/.eslintrc.json +2 -2
- package/lib/transform/draft/db.js +6 -6
- package/lib/transform/draft/odata.js +6 -7
- package/lib/transform/forHanaNew.js +19 -22
- package/lib/transform/forOdataNew.js +13 -15
- package/lib/transform/localized.js +35 -25
- package/lib/transform/odata/toFinalBaseType.js +11 -9
- package/lib/transform/odata/typesExposure.js +3 -3
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +63 -77
- package/lib/transform/translateAssocsToJoins.js +6 -2
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +11 -6
- package/lib/transform/universalCsn/universalCsnEnricher.js +33 -5
- package/lib/utils/file.js +31 -21
- package/lib/utils/timetrace.js +20 -21
- package/package.json +34 -4
- package/share/messages/syntax-expected-integer.md +9 -8
- package/doc/ApiMigration.md +0 -237
- package/doc/CommandLineMigration.md +0 -58
- package/doc/ErrorMessages.md +0 -175
- package/doc/FioriAnnotations.md +0 -94
- package/doc/ODataTransformation.md +0 -273
- package/lib/backends.js +0 -529
- package/lib/fix_antlr4-8_warning.js +0 -56
package/lib/language/language.g4
CHANGED
|
@@ -125,14 +125,17 @@ tokens {
|
|
|
125
125
|
HelperToken1, // used with setLocalToken(), does not appear in messages
|
|
126
126
|
HelperToken2, // used with setLocalToken(), does not appear in messages
|
|
127
127
|
HideAlternatives, // hide alternative tokens (no token seq!)
|
|
128
|
-
|
|
128
|
+
GenericExpr, // via token rewriting according to specialFunctions
|
|
129
|
+
GenericSeparator, // via token rewriting according to specialFunctions
|
|
130
|
+
GenericIntro, // via token rewriting according to specialFunctions
|
|
129
131
|
DOTbeforeBRACE, // via token rewrite
|
|
130
132
|
COMPOSITIONofBRACE // via token rewrite in rule typeAssociationBase
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
// Top-Level -----------------------------------------------------------------
|
|
134
136
|
|
|
135
|
-
start returns [ source
|
|
137
|
+
start returns [ source ] locals [ _sync = 'recover' ]
|
|
138
|
+
@init{ $source = this.createSource(); }
|
|
136
139
|
:
|
|
137
140
|
usingDeclaration[$source]*
|
|
138
141
|
(
|
|
@@ -161,53 +164,46 @@ namespaceDeclaration[ source ] locals[ decl = {} ]
|
|
|
161
164
|
NAMESPACE simplePath[ $decl, 'Namespace' ] ';'
|
|
162
165
|
;
|
|
163
166
|
|
|
164
|
-
usingDeclaration[ source ] locals[ decl ]
|
|
165
|
-
@after {
|
|
167
|
+
usingDeclaration[ source ] locals[ decl = {} ]
|
|
168
|
+
@after { this.attachLocation($decl); }
|
|
166
169
|
:
|
|
170
|
+
{ $decl.location = this.startLocation(); }
|
|
167
171
|
USING
|
|
168
172
|
(
|
|
169
173
|
FROM str=String
|
|
170
|
-
{
|
|
171
|
-
if (!$source.dependencies) $source.dependencies = [];
|
|
172
|
-
$source.dependencies.push( this.quotedLiteral( $str, 'string' ) );
|
|
173
|
-
}
|
|
174
|
+
{ $source.dependencies.push( this.quotedLiteral( $str, 'string' ) ); }
|
|
174
175
|
|
|
|
175
176
|
path=externalPath
|
|
176
|
-
{
|
|
177
|
+
{ this.addItem( $decl, $source, 'usings', 'using' );; $decl.extern = $path.extern; }
|
|
177
178
|
( AS name=ident['Using'] { $decl.name = $name.id; }
|
|
178
179
|
| { this.classifyImplicitName( 'Using' ); }
|
|
179
180
|
)
|
|
180
181
|
( FROM str=String
|
|
181
|
-
{
|
|
182
|
-
if (!$source.dependencies) $source.dependencies = [];
|
|
183
|
-
$source.dependencies.push( $decl.fileDep = this.quotedLiteral( $str, 'string' ) );
|
|
184
|
-
}
|
|
182
|
+
{ $source.dependencies.push( $decl.fileDep = this.quotedLiteral( $str, 'string' ) ); }
|
|
185
183
|
)?
|
|
186
184
|
|
|
|
187
|
-
{
|
|
185
|
+
{ this.addItem( $decl, $source, 'usings', 'using' ); }
|
|
188
186
|
// We could just create "independent" USING declaration, but if we want
|
|
189
187
|
// to have some check in the future whether the external artifacts are
|
|
190
188
|
// really in the FROM source...
|
|
191
|
-
'{'
|
|
189
|
+
'{' { $decl.usings = this.createArray(); }
|
|
192
190
|
innerUsing[ $decl ]
|
|
193
191
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
194
192
|
innerUsing[ $decl ] )*
|
|
195
|
-
'}'
|
|
193
|
+
'}' { this.finalizeDictOrArray( $decl.usings ); }
|
|
196
194
|
( FROM str=String
|
|
197
|
-
{
|
|
198
|
-
if (!$source.dependencies) $source.dependencies = [];
|
|
199
|
-
$source.dependencies.push( $decl.fileDep = this.quotedLiteral( $str, 'string' ) );
|
|
200
|
-
}
|
|
195
|
+
{ $source.dependencies.push( $decl.fileDep = this.quotedLiteral( $str, 'string' ) ); }
|
|
201
196
|
)?
|
|
202
197
|
)
|
|
203
198
|
';'
|
|
204
199
|
;
|
|
205
200
|
|
|
206
|
-
innerUsing[ using ] locals[ decl ]
|
|
207
|
-
@after {
|
|
201
|
+
innerUsing[ using ] locals[ decl = {} ]
|
|
202
|
+
@after { this.attachLocation($decl); }
|
|
208
203
|
:
|
|
204
|
+
{ $decl.location = this.startLocation(); }
|
|
209
205
|
path=externalPath
|
|
210
|
-
{
|
|
206
|
+
{ this.addItem( $decl, $using, 'usings', 'using' );; $decl.extern = $path.extern; }
|
|
211
207
|
( AS name=ident['Using'] { $decl.name = $name.id; }
|
|
212
208
|
| { this.classifyImplicitName( 'Using' ); }
|
|
213
209
|
)
|
|
@@ -225,18 +221,18 @@ externalPath returns [ extern = {} ]
|
|
|
225
221
|
// @anno :p - x as x; // or: anno value true, select item :p-x
|
|
226
222
|
// }
|
|
227
223
|
|
|
228
|
-
annotationAssignment_1[
|
|
229
|
-
@after {
|
|
224
|
+
annotationAssignment_1[ art ] locals[ assignment = { name: {} } ]
|
|
225
|
+
@after { this.assignAnnotation( $art, $assignment ); }
|
|
230
226
|
:
|
|
231
227
|
annotationPath[ $assignment.name, 'anno' ]
|
|
232
228
|
annotationPathVariant[ $assignment.name ]?
|
|
233
229
|
(
|
|
234
230
|
':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
|
|
235
|
-
val=annoValue
|
|
231
|
+
val=annoValue[ $assignment ]
|
|
236
232
|
)?
|
|
237
233
|
;
|
|
238
234
|
|
|
239
|
-
annotationAssignment_paren[
|
|
235
|
+
annotationAssignment_paren[ art ]
|
|
240
236
|
:
|
|
241
237
|
'('
|
|
242
238
|
// allow completely useless `@()` with a warning, do not offer it for completion
|
|
@@ -251,28 +247,28 @@ annotationAssignment_paren[ annos ]
|
|
|
251
247
|
return $ctx;
|
|
252
248
|
}
|
|
253
249
|
}
|
|
254
|
-
annotationAssignment_1[ $
|
|
250
|
+
annotationAssignment_1[ $art ]
|
|
255
251
|
( ','
|
|
256
252
|
{
|
|
257
253
|
this.meltKeywordToIdentifier();
|
|
258
254
|
if (this.isStraightBefore(')')) break; // allow ',' before ')'
|
|
259
255
|
}
|
|
260
|
-
annotationAssignment_1[ $
|
|
256
|
+
annotationAssignment_1[ $art ]
|
|
261
257
|
)*
|
|
262
258
|
')'
|
|
263
259
|
;
|
|
264
260
|
|
|
265
|
-
annotationAssignment_fix[
|
|
261
|
+
annotationAssignment_fix[ art ] locals[ assignment ]
|
|
266
262
|
// value outside @(...)
|
|
267
263
|
@after {
|
|
268
264
|
if ($assignment) {
|
|
269
|
-
|
|
270
|
-
this.docComment( $
|
|
265
|
+
this.assignAnnotation( $art, $assignment );
|
|
266
|
+
this.docComment( $art );
|
|
271
267
|
}
|
|
272
268
|
} :
|
|
273
269
|
'@'
|
|
274
270
|
(
|
|
275
|
-
annotationAssignment_paren[
|
|
271
|
+
annotationAssignment_paren[ $art ]
|
|
276
272
|
|
|
|
277
273
|
{ $assignment = { name: {} }; }
|
|
278
274
|
annotationPath[ $assignment.name, 'anno' ]
|
|
@@ -287,38 +283,38 @@ annotationAssignment_fix[ annos ] locals[ assignment ]
|
|
|
287
283
|
)
|
|
288
284
|
;
|
|
289
285
|
|
|
290
|
-
annotationAssignment_ll1[
|
|
286
|
+
annotationAssignment_ll1[ art ] locals[ assignment ]
|
|
291
287
|
@after {
|
|
292
288
|
if ($assignment) {
|
|
293
|
-
|
|
294
|
-
this.docComment( $
|
|
289
|
+
this.assignAnnotation( $art, $assignment );
|
|
290
|
+
this.docComment( $art );
|
|
295
291
|
}
|
|
296
292
|
} :
|
|
297
293
|
'@'
|
|
298
294
|
(
|
|
299
|
-
annotationAssignment_paren[
|
|
295
|
+
annotationAssignment_paren[ $art ]
|
|
300
296
|
|
|
|
301
297
|
{ $assignment = { name: {} }; }
|
|
302
298
|
annotationPath[ $assignment.name, 'anno' ]
|
|
303
299
|
annotationPathVariant[ $assignment.name ]?
|
|
304
300
|
(
|
|
305
301
|
':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
|
|
306
|
-
val=annoValue
|
|
302
|
+
val=annoValue[ $assignment ]
|
|
307
303
|
)?
|
|
308
304
|
)
|
|
309
305
|
;
|
|
310
306
|
|
|
311
307
|
// Has previously used ATN, now via local token rewrite
|
|
312
|
-
annotationAssignment_atn[
|
|
308
|
+
annotationAssignment_atn[ art ] locals[ assignment ]
|
|
313
309
|
@after {
|
|
314
310
|
if ($assignment) {
|
|
315
|
-
|
|
316
|
-
this.docComment( $
|
|
311
|
+
this.assignAnnotation( $art, $assignment );
|
|
312
|
+
this.docComment( $art );
|
|
317
313
|
}
|
|
318
314
|
} :
|
|
319
315
|
'@'
|
|
320
316
|
(
|
|
321
|
-
annotationAssignment_paren[
|
|
317
|
+
annotationAssignment_paren[ $art ]
|
|
322
318
|
|
|
|
323
319
|
{ $assignment = { name: {} }; }
|
|
324
320
|
annotationPath[ $assignment.name, 'anno' ]
|
|
@@ -337,14 +333,13 @@ annotationAssignment_atn[ annos ] locals[ assignment ]
|
|
|
337
333
|
( HelperToken2 // ':'
|
|
338
334
|
{ this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
|
|
339
335
|
(
|
|
340
|
-
val=annoValueBase
|
|
336
|
+
val=annoValueBase[ $assignment ]
|
|
341
337
|
|
|
|
342
|
-
|
|
343
|
-
at='@'? annotationPath[ $assignment.value, 'ref', $at ]
|
|
338
|
+
at='@'? annotationPath[ $assignment, 'ref', $at ]
|
|
344
339
|
{ this.setLocalToken( '#', 'HelperToken1', null, true ); } // see above
|
|
345
340
|
(
|
|
346
341
|
HelperToken1 { this.meltKeywordToIdentifier(); }
|
|
347
|
-
variant=ident['variant'] { $assignment.
|
|
342
|
+
variant=ident['variant'] { $assignment.variant = $variant.id; }
|
|
348
343
|
)?
|
|
349
344
|
)
|
|
350
345
|
)?
|
|
@@ -364,97 +359,96 @@ optionalSemi
|
|
|
364
359
|
';'?
|
|
365
360
|
;
|
|
366
361
|
|
|
367
|
-
artifactDef[ outer, defOnly = false ] locals[
|
|
362
|
+
artifactDef[ outer, defOnly = false ] locals[ art = {} ] // cannot use `parent` as parameter name!
|
|
368
363
|
@after{ /* #ATN 1 */ }
|
|
369
364
|
:
|
|
370
|
-
{ this.docComment( $
|
|
371
|
-
annotationAssignment_ll1[ $
|
|
365
|
+
{ $art.location = this.startLocation(); this.docComment( $art ); }
|
|
366
|
+
annotationAssignment_ll1[ $art ]*
|
|
372
367
|
(
|
|
373
368
|
DEFINE?
|
|
374
|
-
( contextDef[ $
|
|
375
|
-
| entityDef[ $
|
|
376
|
-
| typeDef[ $
|
|
377
|
-
| aspectDef[ $
|
|
378
|
-
| annotationDef[ $
|
|
379
|
-
| viewDef[ $
|
|
380
|
-
| eventDef[ $
|
|
381
|
-
| actionFunctionMainDef[ $
|
|
369
|
+
( contextDef[ $art, $outer, defOnly ]
|
|
370
|
+
| entityDef[ $art, $outer ]
|
|
371
|
+
| typeDef[ $art, $outer ]
|
|
372
|
+
| aspectDef[ $art, $outer ]
|
|
373
|
+
| annotationDef[ $art, $outer ]
|
|
374
|
+
| viewDef[ $art, $outer ]
|
|
375
|
+
| eventDef[ $art, $outer ]
|
|
376
|
+
| actionFunctionMainDef[ $art, $outer ]
|
|
382
377
|
)
|
|
383
378
|
|
|
|
384
379
|
extend=EXTEND
|
|
385
|
-
{ if (defOnly)
|
|
386
|
-
// another way
|
|
380
|
+
{ if (defOnly)
|
|
387
381
|
this.error( 'syntax-extend-context', $extend,
|
|
388
382
|
{ code: 'EXTEND artifact', kind: defOnly },
|
|
389
|
-
'No $(CODE) within $(KIND) extensions' );
|
|
383
|
+
'No $(CODE) within $(KIND) extensions' );
|
|
384
|
+
if (!$outer.extensions) $outer.extensions = [];
|
|
385
|
+
}
|
|
390
386
|
// #ATN: EXTEND elem, while CONTEXT, ENTITY etc are not reserved
|
|
391
|
-
( extendContext[ $
|
|
392
|
-
| extendEntity[ $
|
|
393
|
-
| extendProjection[ $
|
|
394
|
-
| extendType[ $
|
|
395
|
-
| extendAspect[ $
|
|
387
|
+
( extendContext[ $art, $outer ]
|
|
388
|
+
| extendEntity[ $art, $outer ]
|
|
389
|
+
| extendProjection[ $art, $outer ]
|
|
390
|
+
| extendType[ $art, $outer ]
|
|
391
|
+
| extendAspect[ $art, $outer ]
|
|
396
392
|
// Streamlined Syntax
|
|
397
|
-
| extendArtifact[ $
|
|
393
|
+
| extendArtifact[ $art, $outer ]
|
|
398
394
|
)
|
|
399
395
|
|
|
|
400
396
|
annotate=ANNOTATE
|
|
401
|
-
{ if (defOnly)
|
|
402
|
-
// another way
|
|
397
|
+
{ if (defOnly)
|
|
403
398
|
this.error( 'syntax-extend-context', $annotate,
|
|
404
399
|
{ code: 'ANNOTATE artifact', kind: defOnly },
|
|
405
400
|
'No $(CODE) within $(KIND) extensions' );
|
|
401
|
+
if (!$outer.extensions) $outer.extensions = [];
|
|
406
402
|
this.meltKeywordToIdentifier();
|
|
407
403
|
}
|
|
408
|
-
annotateArtifact[ $
|
|
404
|
+
annotateArtifact[ $art, $outer ] // not kind-specific
|
|
409
405
|
)
|
|
410
406
|
;
|
|
411
407
|
|
|
412
|
-
contextDef[
|
|
413
|
-
@after { this.attachLocation($art); }
|
|
408
|
+
contextDef[ art, outer, defOnly = false ] locals[ name = {} ]
|
|
409
|
+
@after { this.attachLocation( $art ); }
|
|
414
410
|
:
|
|
415
411
|
( CONTEXT | service=SERVICE ) simplePath[ $name, $service ? 'Service' : 'Context' ]
|
|
416
|
-
{
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
annotationAssignment_fix[ $annos ]*
|
|
412
|
+
{ this.addDef( $art, $outer, 'artifacts', $service ? 'service' : 'context', $name );
|
|
413
|
+
this.docComment( $art ); }
|
|
414
|
+
annotationAssignment_fix[ $art ]*
|
|
420
415
|
(
|
|
421
|
-
'{' { $art.artifacts = this.createDict(); }
|
|
416
|
+
'{' { $art.artifacts = this.createDict(); $art.extensions = []; }
|
|
422
417
|
artifactDef[ $art, defOnly ]*
|
|
423
|
-
'}' { this.
|
|
418
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
424
419
|
optionalSemi
|
|
425
420
|
|
|
|
426
421
|
requiredSemi
|
|
427
422
|
)
|
|
428
423
|
;
|
|
429
424
|
|
|
430
|
-
extendContext[
|
|
431
|
-
@after { this.attachLocation($art); }
|
|
425
|
+
extendContext[ art, outer ] locals[ name = {} ]
|
|
426
|
+
@after { this.attachLocation( $art ); }
|
|
432
427
|
:
|
|
433
|
-
( CONTEXT
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
$loc ); }
|
|
428
|
+
( CONTEXT { $art.expectedKind = 'context'; } | service=SERVICE { $art.expectedKind = 'service'; })
|
|
429
|
+
simplePath[ $name, $service ? 'Service' : 'Context' ] // not 'Extend' here
|
|
430
|
+
{ $art.name = $name; this.addItem( $art, $outer, 'extensions', 'extend' ); }
|
|
437
431
|
( WITH { this.noSemicolonHere(); } )?
|
|
438
|
-
{ this.docComment( $
|
|
439
|
-
annotationAssignment_ll1[ $
|
|
432
|
+
{ this.docComment( $art ); }
|
|
433
|
+
annotationAssignment_ll1[ $art ]*
|
|
440
434
|
(
|
|
441
435
|
'{' { $art.artifacts = this.createDict(); }
|
|
442
436
|
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT' ]*
|
|
443
|
-
'}' { this.
|
|
437
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
444
438
|
optionalSemi
|
|
445
439
|
|
|
|
446
440
|
requiredSemi
|
|
447
441
|
)
|
|
448
442
|
;
|
|
449
443
|
|
|
450
|
-
entityDef[
|
|
451
|
-
@after { this.attachLocation($art); }
|
|
444
|
+
entityDef[ art, outer ] locals[ name = {} ]
|
|
445
|
+
@after { this.attachLocation( $art ); }
|
|
452
446
|
:
|
|
453
447
|
ENTITY simplePath[ $name, 'Entity' ]
|
|
454
|
-
{
|
|
455
|
-
this.docComment( $
|
|
456
|
-
annotationAssignment_fix[ $
|
|
457
|
-
|
|
448
|
+
{ this.addDef( $art, $outer, 'artifacts', 'entity', $name );
|
|
449
|
+
this.docComment( $art ); }
|
|
450
|
+
annotationAssignment_fix[ $art ]*
|
|
451
|
+
parameterListDef[ $art ]?
|
|
458
452
|
(
|
|
459
453
|
( ':'
|
|
460
454
|
includeRef[ $art ]
|
|
@@ -462,15 +456,14 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
462
456
|
includeRef[ $art ]
|
|
463
457
|
)*
|
|
464
458
|
)?
|
|
465
|
-
'{'
|
|
466
|
-
{ $art.elements = this.createDict(); } // better for include and annotate
|
|
459
|
+
'{' { $art.elements = this.createDict(); }
|
|
467
460
|
elementDef[ $art ]*
|
|
468
|
-
'}' { this.
|
|
461
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
469
462
|
// TODO: action definitions in a specific section?
|
|
470
463
|
(
|
|
471
464
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
472
465
|
actionFunctionDef[ $art ]*
|
|
473
|
-
'}' { this.
|
|
466
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
474
467
|
)?
|
|
475
468
|
optionalSemi
|
|
476
469
|
|
|
|
@@ -480,7 +473,7 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
480
473
|
(
|
|
481
474
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
482
475
|
actionFunctionDef[ $art ]*
|
|
483
|
-
'}' { this.
|
|
476
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
484
477
|
optionalSemi
|
|
485
478
|
| requiredSemi
|
|
486
479
|
)
|
|
@@ -490,7 +483,7 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
490
483
|
(
|
|
491
484
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
492
485
|
actionFunctionDef[ $art ]*
|
|
493
|
-
'}' { this.
|
|
486
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
494
487
|
)?
|
|
495
488
|
optionalSemi // TODO: not fully correct without columns or excluding
|
|
496
489
|
)
|
|
@@ -514,7 +507,7 @@ projectionSpec returns[ query ] locals[ src ]
|
|
|
514
507
|
( AS aliasName=ident['FromAlias'] { $src.name = $aliasName.id } )?
|
|
515
508
|
// ANTLR errors are better if we use ( A )? instead of ( A | ):
|
|
516
509
|
{ if (!$src.name) this.classifyImplicitName( $src.scope ? 'FromAlias' : 'Without' ); }
|
|
517
|
-
bracedSelectItemListDef[ $query ]?
|
|
510
|
+
bracedSelectItemListDef[ $query, 'columns' ]?
|
|
518
511
|
excludingClause[ $query ]?
|
|
519
512
|
;
|
|
520
513
|
|
|
@@ -541,25 +534,26 @@ excludingClause[ query ]
|
|
|
541
534
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
542
535
|
projectionExclusion[ $query ]
|
|
543
536
|
)*
|
|
544
|
-
'}' { this.
|
|
537
|
+
'}' { this.finalizeDictOrArray( $query.excludingDict ); }
|
|
545
538
|
;
|
|
546
539
|
|
|
547
|
-
projectionExclusion[ outer ] locals[ art ]
|
|
540
|
+
projectionExclusion[ outer ] locals[ art = {} ]
|
|
548
541
|
@after { this.attachLocation($art); }
|
|
549
542
|
:
|
|
550
543
|
name=ident['ref']
|
|
551
|
-
{
|
|
544
|
+
{ this.addDef( $art, $outer, 'excludingDict', '', $name.id ); }
|
|
552
545
|
;
|
|
553
546
|
|
|
554
|
-
extendEntity[
|
|
555
|
-
@after { /* #ATN 1 */ this.attachLocation($art); }
|
|
547
|
+
extendEntity[ art, outer ] locals[ name = {} ]
|
|
548
|
+
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
556
549
|
:
|
|
557
550
|
ENTITY simplePath[ $name, 'Extend' ]
|
|
558
|
-
{ $art =
|
|
559
|
-
|
|
551
|
+
{ $art.expectedKind = 'entity'; $art.name = $name;
|
|
552
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
553
|
+
}
|
|
560
554
|
(
|
|
561
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
562
|
-
annotationAssignment_ll1[ $
|
|
555
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
556
|
+
annotationAssignment_ll1[ $art ]*
|
|
563
557
|
// ATN: the ref can start with ACTIONS
|
|
564
558
|
(
|
|
565
559
|
includeRef[ $art ]
|
|
@@ -568,8 +562,8 @@ extendEntity[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
568
562
|
extendForEntity[ $art ]
|
|
569
563
|
)
|
|
570
564
|
|
|
|
571
|
-
{ this.docComment( $
|
|
572
|
-
annotationAssignment_ll1[ $
|
|
565
|
+
{ this.docComment( $art ); }
|
|
566
|
+
annotationAssignment_ll1[ $art ]*
|
|
573
567
|
extendForEntity[ $art ]
|
|
574
568
|
)
|
|
575
569
|
;
|
|
@@ -578,33 +572,32 @@ extendForEntity[ art ]
|
|
|
578
572
|
:
|
|
579
573
|
'{' { $art.elements = this.createDict(); }
|
|
580
574
|
elementDefOrExtend[ $art ]*
|
|
581
|
-
'}' { this.
|
|
575
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
582
576
|
(
|
|
583
577
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
584
578
|
actionFunctionDef[ $art ]*
|
|
585
|
-
'}' { this.
|
|
579
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
586
580
|
)?
|
|
587
581
|
optionalSemi
|
|
588
582
|
|
|
|
589
583
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
590
584
|
actionFunctionDef[ $art ]*
|
|
591
|
-
'}' { this.
|
|
585
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
592
586
|
optionalSemi
|
|
593
587
|
|
|
|
594
588
|
requiredSemi
|
|
595
589
|
;
|
|
596
590
|
|
|
597
|
-
extendProjection[
|
|
598
|
-
@after { this.attachLocation($art); }
|
|
591
|
+
extendProjection[ art, outer ] locals[ name = {} ]
|
|
592
|
+
@after { this.attachLocation( $art ); }
|
|
599
593
|
:
|
|
600
594
|
expected=PROJECTION simplePath[ $name, 'Extend' ]
|
|
601
|
-
{
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
$loc ); }
|
|
595
|
+
{ $art.expectedKind = 'entity'; $art.name = $name;
|
|
596
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
597
|
+
}
|
|
605
598
|
( WITH { this.noSemicolonHere(); } )?
|
|
606
|
-
{ this.docComment( $
|
|
607
|
-
annotationAssignment_ll1[ $
|
|
599
|
+
{ this.docComment( $art ); }
|
|
600
|
+
annotationAssignment_ll1[ $art ]*
|
|
608
601
|
(
|
|
609
602
|
'{' { $art.columns = []; }
|
|
610
603
|
(
|
|
@@ -617,13 +610,13 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
617
610
|
(
|
|
618
611
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
619
612
|
actionFunctionDef[ $art ]*
|
|
620
|
-
'}' { this.
|
|
613
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
621
614
|
)?
|
|
622
615
|
optionalSemi
|
|
623
616
|
|
|
|
624
617
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
625
618
|
actionFunctionDef[ $art ]*
|
|
626
|
-
'}' { this.
|
|
619
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
627
620
|
optionalSemi
|
|
628
621
|
|
|
|
629
622
|
requiredSemi
|
|
@@ -631,53 +624,53 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
631
624
|
;
|
|
632
625
|
|
|
633
626
|
// TODO: no action extension?
|
|
634
|
-
actionFunctionDef[ outer ] locals[ art
|
|
635
|
-
@after { this.attachLocation($art); }
|
|
627
|
+
actionFunctionDef[ outer ] locals[ art = {} ]
|
|
628
|
+
@after { this.attachLocation( $art ); }
|
|
636
629
|
:
|
|
637
|
-
{ this.docComment( $
|
|
638
|
-
annotationAssignment_ll1[ $
|
|
630
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
631
|
+
annotationAssignment_ll1[ $art ]*
|
|
639
632
|
(
|
|
640
633
|
ACTION name=ident['BoundAction']
|
|
641
|
-
{
|
|
642
|
-
this.docComment( $
|
|
643
|
-
annotationAssignment_fix[ $
|
|
634
|
+
{ this.addDef( $art, $outer, 'actions', 'action', $name.id );
|
|
635
|
+
this.docComment( $art ); }
|
|
636
|
+
annotationAssignment_fix[ $art ]*
|
|
644
637
|
parameterListDef[ $art ]
|
|
645
|
-
( returnTypeSpec[ $art
|
|
638
|
+
( returnTypeSpec[ $art ] | requiredSemi )
|
|
646
639
|
|
|
|
647
640
|
FUNCTION name=ident['BoundAction']
|
|
648
|
-
{
|
|
649
|
-
this.docComment( $
|
|
650
|
-
annotationAssignment_fix[ $
|
|
641
|
+
{ this.addDef( $art, $outer, 'actions', 'function', $name.id );
|
|
642
|
+
this.docComment( $art ); }
|
|
643
|
+
annotationAssignment_fix[ $art ]*
|
|
651
644
|
parameterListDef[ $art ]
|
|
652
|
-
returnTypeSpec[ $art
|
|
645
|
+
returnTypeSpec[ $art ]
|
|
653
646
|
)
|
|
654
647
|
;
|
|
655
648
|
|
|
656
|
-
actionFunctionMainDef[
|
|
657
|
-
@after { this.attachLocation($art); }
|
|
649
|
+
actionFunctionMainDef[ art, outer ] locals[ name = {} ]
|
|
650
|
+
@after { this.attachLocation( $art ); }
|
|
658
651
|
:
|
|
659
652
|
ACTION simplePath[ $name, 'Action' ]
|
|
660
|
-
{
|
|
661
|
-
this.docComment( $
|
|
662
|
-
annotationAssignment_fix[ $
|
|
653
|
+
{ this.addDef( $art, $outer, 'artifacts', 'action', $name );
|
|
654
|
+
this.docComment( $art ); }
|
|
655
|
+
annotationAssignment_fix[ $art ]*
|
|
663
656
|
parameterListDef[ $art ]
|
|
664
|
-
( returnTypeSpec[ $art
|
|
657
|
+
( returnTypeSpec[ $art ] | requiredSemi )
|
|
665
658
|
|
|
|
666
659
|
FUNCTION simplePath[ $name, 'Action' ]
|
|
667
|
-
{
|
|
668
|
-
this.docComment( $
|
|
669
|
-
annotationAssignment_fix[ $
|
|
660
|
+
{ this.addDef( $art, $outer, 'artifacts', 'function', $name );
|
|
661
|
+
this.docComment( $art ); }
|
|
662
|
+
annotationAssignment_fix[ $art ]*
|
|
670
663
|
parameterListDef[ $art ]
|
|
671
|
-
returnTypeSpec[ $art
|
|
664
|
+
returnTypeSpec[ $art ]
|
|
672
665
|
;
|
|
673
666
|
|
|
674
|
-
eventDef[
|
|
675
|
-
@after { /* #ATN 1 */ this.attachLocation($art); }
|
|
667
|
+
eventDef[ art, outer ] locals[ name = {} ]
|
|
668
|
+
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
676
669
|
:
|
|
677
670
|
EVENT simplePath[ $name, 'Event' ]
|
|
678
|
-
{
|
|
679
|
-
this.docComment( $
|
|
680
|
-
annotationAssignment_fix[ $
|
|
671
|
+
{ this.addDef( $art, $outer, 'artifacts', 'event', $name );
|
|
672
|
+
this.docComment( $art ); }
|
|
673
|
+
annotationAssignment_fix[ $art ]*
|
|
681
674
|
(
|
|
682
675
|
typeStruct[ $art ] optionalSemi
|
|
683
676
|
|
|
|
@@ -693,8 +686,8 @@ eventDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
693
686
|
)*
|
|
694
687
|
typeStruct[ $art ] optionalSemi
|
|
695
688
|
|
|
|
696
|
-
{ this.docComment( $
|
|
697
|
-
annotationAssignment_ll1[ $
|
|
689
|
+
{ this.docComment( $art ); }
|
|
690
|
+
annotationAssignment_ll1[ $art ]*
|
|
698
691
|
requiredSemi
|
|
699
692
|
)
|
|
700
693
|
|
|
|
@@ -708,18 +701,18 @@ eventDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
708
701
|
)
|
|
709
702
|
;
|
|
710
703
|
|
|
711
|
-
aspectDef[
|
|
712
|
-
@after { this.attachLocation($art); }
|
|
704
|
+
aspectDef[ art, outer ] locals[ name = {} ]
|
|
705
|
+
@after { this.attachLocation( $art ); }
|
|
713
706
|
:
|
|
714
707
|
( ASPECT | ( abs=ABSTRACT | HideAlternatives ) ent=ENTITY )
|
|
715
708
|
simplePath[ $name, 'Type' ]
|
|
716
|
-
{
|
|
709
|
+
{ this.addDef( $art, $outer, 'artifacts', 'aspect', $name );
|
|
717
710
|
// backends do not like ['$'+'syntax']: ($ent ? 'entity' : 'aspect')
|
|
718
711
|
if ($ent)
|
|
719
712
|
this.warning( 'syntax-deprecated-abstract', this.tokenLocation( $abs, $ent ), {},
|
|
720
713
|
'Abstract entity definitions are deprecated; use aspect definitions instead' );
|
|
721
|
-
this.docComment( $
|
|
722
|
-
annotationAssignment_fix[ $
|
|
714
|
+
this.docComment( $art ); }
|
|
715
|
+
annotationAssignment_fix[ $art ]*
|
|
723
716
|
( ':'
|
|
724
717
|
(
|
|
725
718
|
includeRef[ $art ]
|
|
@@ -730,99 +723,95 @@ aspectDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
730
723
|
)?
|
|
731
724
|
'{' { $art.elements = this.createDict(); }
|
|
732
725
|
( elementDef[ $art ]* )
|
|
733
|
-
'}' { this.
|
|
726
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
734
727
|
// TODO: action definitions in a specific section?
|
|
735
728
|
(
|
|
736
729
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
737
730
|
actionFunctionDef[ $art ]*
|
|
738
|
-
'}' { this.
|
|
731
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
739
732
|
)?
|
|
740
733
|
optionalSemi
|
|
741
734
|
;
|
|
742
735
|
|
|
743
|
-
typeDef[
|
|
744
|
-
@after { this.attachLocation($art); }
|
|
736
|
+
typeDef[ art, outer ] locals[ name = {} ]
|
|
737
|
+
@after { this.attachLocation( $art ); }
|
|
745
738
|
:
|
|
746
739
|
TYPE simplePath[ $name, 'Type' ]
|
|
747
|
-
{
|
|
748
|
-
this.docComment( $
|
|
749
|
-
annotationAssignment_fix[ $
|
|
750
|
-
typeSpecSemi[ $art
|
|
740
|
+
{ this.addDef( $art, $outer, 'artifacts', 'type', $name );
|
|
741
|
+
this.docComment( $art ); }
|
|
742
|
+
annotationAssignment_fix[ $art ]*
|
|
743
|
+
typeSpecSemi[ $art ]
|
|
751
744
|
;
|
|
752
745
|
|
|
753
|
-
extendType[
|
|
754
|
-
@after { this.attachLocation($art); }
|
|
746
|
+
extendType[ art, outer ] locals[ name = {} ]
|
|
747
|
+
@after { this.attachLocation( $art ); }
|
|
755
748
|
:
|
|
756
749
|
// aspects are types, i.e. kind is 'type' for aspects
|
|
757
750
|
TYPE simplePath[ $name, 'Extend' ]
|
|
758
|
-
{ $art =
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
extendWithOptElements[ $art, $
|
|
751
|
+
{ $art.expectedKind = 'type'; $art.name = $name;
|
|
752
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
753
|
+
}
|
|
754
|
+
extendWithOptElements[ $art, $art ]
|
|
762
755
|
;
|
|
763
756
|
|
|
764
|
-
extendAspect[
|
|
765
|
-
@after { this.attachLocation($art); }
|
|
757
|
+
extendAspect[ art, outer ] locals[ name = {} ]
|
|
758
|
+
@after { this.attachLocation( $art ); }
|
|
766
759
|
:
|
|
767
760
|
// aspects are types, i.e. kind is 'type' for aspects
|
|
768
761
|
ASPECT simplePath[ $name, 'Extend' ]
|
|
769
|
-
{ $art =
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
extendWithOptElements[ $art, $
|
|
762
|
+
{ $art.expectedKind = 'aspect'; $art.name = $name;
|
|
763
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
764
|
+
}
|
|
765
|
+
extendWithOptElements[ $art, $art ]
|
|
773
766
|
;
|
|
774
767
|
|
|
775
|
-
annotationDef[
|
|
776
|
-
@after { this.attachLocation($art); }
|
|
768
|
+
annotationDef[ art, outer ] locals[ name = {} ]
|
|
769
|
+
@after { this.attachLocation( $art ); }
|
|
777
770
|
:
|
|
778
771
|
annotation=ANNOTATION simplePath[ $name, 'AnnoDef' ]
|
|
779
772
|
{ if ($outer.kind !== 'source') { // this is a syntax restriction to avoid confusion
|
|
780
|
-
this.error( 'syntax-
|
|
781
|
-
'Annotation definitions can\'t be defined inside contexts or services' );
|
|
773
|
+
this.error( 'syntax-unexpected-vocabulary', $annotation, { '#': $outer.kind } );
|
|
782
774
|
$art = {}; }
|
|
783
|
-
else
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
775
|
+
else {
|
|
776
|
+
if (!$outer.vocabularies) $outer.vocabularies = Object.create(null);
|
|
777
|
+
this.addDef( $art, $outer, 'vocabularies', 'annotation', $name );
|
|
778
|
+
}
|
|
779
|
+
this.docComment( $art ); }
|
|
780
|
+
annotationAssignment_fix[ $art ]*
|
|
781
|
+
typeSpecSemi[ $art ] // also 'includes'...
|
|
788
782
|
;
|
|
789
783
|
|
|
790
|
-
extendArtifact[
|
|
791
|
-
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
784
|
+
extendArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
785
|
+
@after{ /* #ATN 1 */ this.attachLocation( $art ); }
|
|
792
786
|
:
|
|
793
787
|
simplePath[ $name, 'Extend' ]
|
|
788
|
+
( ':' simplePath[ $elemName, 'Element'] )?
|
|
789
|
+
{ this.addExtension( $art, $outer, 'extend', $name, $elemName.path ); }
|
|
794
790
|
(
|
|
795
|
-
{
|
|
796
|
-
|
|
797
|
-
':'
|
|
798
|
-
simplePath[ $elemName, 'ref']
|
|
799
|
-
{{
|
|
800
|
-
const def = this.addItem( $outer, 'extensions', 'extend', null, { name: $name }, $loc );
|
|
801
|
-
$art = this.artifactForElementAnnotateOrExtend( 'extend', def, $elemName.path, $annos, $loc );
|
|
802
|
-
}}
|
|
803
|
-
)
|
|
804
|
-
(
|
|
805
|
-
{ this.docComment( $annos ); }
|
|
806
|
-
annotationAssignment_ll1[ $annos ]*
|
|
791
|
+
{ this.docComment( $art ); }
|
|
792
|
+
annotationAssignment_ll1[ $art ]*
|
|
807
793
|
(
|
|
808
794
|
'{' { $art.elements = this.createDict(); }
|
|
809
795
|
elementDefOrExtend[ $art ]*
|
|
810
|
-
'}' { this.
|
|
796
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
797
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
811
798
|
optionalSemi
|
|
812
799
|
|
|
|
813
800
|
requiredSemi
|
|
814
801
|
)
|
|
815
802
|
|
|
|
816
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
817
|
-
annotationAssignment_ll1[ $
|
|
803
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
804
|
+
annotationAssignment_ll1[ $art ]*
|
|
818
805
|
// #ATN: DEFINITIONS, COLUMNS, ACTIONS etc are not reserved and could be identifiers (ref).
|
|
806
|
+
// TODO: exclude "expected" according to disallowElementExtension()
|
|
819
807
|
(
|
|
820
808
|
includeRef[ $art ]
|
|
821
809
|
requiredSemi
|
|
822
810
|
|
|
|
823
811
|
'{' { $art.elements = this.createDict(); }
|
|
824
812
|
elementDefOrExtend[ $art ]*
|
|
825
|
-
'}' { this.
|
|
813
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
814
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
826
815
|
optionalSemi
|
|
827
816
|
|
|
|
828
817
|
requiredSemi
|
|
@@ -831,7 +820,7 @@ extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
831
820
|
DEFINITIONS
|
|
832
821
|
'{' { $art.artifacts = this.createDict(); }
|
|
833
822
|
artifactDef[ $art, true ]*
|
|
834
|
-
'}' { this.
|
|
823
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
835
824
|
optionalSemi
|
|
836
825
|
|
|
|
837
826
|
{ this.disallowElementExtension( $elemName, $outer, 'columns' ); }
|
|
@@ -848,85 +837,82 @@ extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
848
837
|
|
|
|
849
838
|
{ this.disallowElementExtension( $elemName, $outer, 'actions' ); }
|
|
850
839
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
851
|
-
actionFunctionDef[ $art ]*
|
|
852
|
-
'}' { this.
|
|
840
|
+
actionFunctionDef[ $art ]* // TODO: no EXTEND in actions? (ok, would just allow annos)
|
|
841
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
853
842
|
optionalSemi
|
|
854
843
|
|
|
|
855
844
|
ELEMENTS '{' { $art.elements = this.createDict(); }
|
|
856
845
|
elementDefOrExtend[ $art ]*
|
|
857
|
-
'}' { this.
|
|
846
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
847
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
858
848
|
optionalSemi
|
|
859
849
|
|
|
|
860
850
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
861
|
-
enumSymbolDef[ $art ]*
|
|
862
|
-
'}' { this.
|
|
851
|
+
enumSymbolDef[ $art ]* // TODO: no EXTEND in enum? (ok, would just allow annos)
|
|
852
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
863
853
|
optionalSemi
|
|
864
854
|
)
|
|
865
855
|
)
|
|
866
856
|
;
|
|
867
857
|
|
|
868
|
-
extendWithOptElements[ art
|
|
858
|
+
extendWithOptElements[ art ]
|
|
869
859
|
:
|
|
870
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
871
|
-
annotationAssignment_ll1[ $
|
|
860
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
861
|
+
annotationAssignment_ll1[ $art ]*
|
|
872
862
|
(
|
|
873
863
|
includeRef[ $art ]
|
|
874
864
|
requiredSemi
|
|
875
865
|
|
|
|
876
866
|
'{' { $art.elements = this.createDict(); }
|
|
877
867
|
elementDefOrExtend[ $art ]*
|
|
878
|
-
'}' { this.
|
|
868
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
869
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
879
870
|
optionalSemi
|
|
880
871
|
|
|
|
881
872
|
requiredSemi
|
|
882
873
|
)
|
|
883
874
|
|
|
|
884
|
-
{ this.docComment( $
|
|
885
|
-
annotationAssignment_ll1[ $
|
|
875
|
+
{ this.docComment( $art ); }
|
|
876
|
+
annotationAssignment_ll1[ $art ]*
|
|
886
877
|
(
|
|
887
878
|
'{' { $art.elements = this.createDict(); }
|
|
888
879
|
elementDefOrExtend[ $art ]*
|
|
889
|
-
'}' { this.
|
|
880
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
881
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
890
882
|
optionalSemi
|
|
891
883
|
|
|
|
892
884
|
requiredSemi
|
|
893
885
|
)
|
|
894
886
|
;
|
|
895
887
|
|
|
896
|
-
annotateArtifact[
|
|
897
|
-
@after { this.attachLocation($art); }
|
|
888
|
+
annotateArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
889
|
+
@after { this.attachLocation( $art ); }
|
|
898
890
|
:
|
|
899
891
|
simplePath[ $name, 'Annotate' ]
|
|
900
|
-
(
|
|
901
|
-
|
|
902
|
-
|
|
|
903
|
-
':'
|
|
904
|
-
simplePath[ $elemName, 'ref']
|
|
905
|
-
{{
|
|
906
|
-
const def = this.addItem( $outer, 'extensions', 'annotate', null, { name: $name }, $loc );
|
|
907
|
-
$art = this.artifactForElementAnnotateOrExtend( 'annotate', def, $elemName.path, $annos, $loc );
|
|
908
|
-
}}
|
|
909
|
-
)
|
|
910
|
-
|
|
892
|
+
( ':' simplePath[ $elemName, 'Element'] )?
|
|
893
|
+
{ this.addExtension( $art, $outer, 'annotate', $name, $elemName.path ); }
|
|
911
894
|
( WITH { this.noSemicolonHere(); } )?
|
|
912
|
-
{ this.docComment( $
|
|
913
|
-
annotationAssignment_ll1[ $
|
|
895
|
+
{ this.docComment( $art ); }
|
|
896
|
+
annotationAssignment_ll1[ $art ]*
|
|
914
897
|
(
|
|
915
898
|
'{' { $art.elements = this.createDict(); }
|
|
916
899
|
annotateElement[ $art ]*
|
|
917
|
-
'}' { this.
|
|
900
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
901
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
918
902
|
(
|
|
919
903
|
ACTIONS
|
|
920
904
|
'{' { $art.actions = this.createDict(); }
|
|
921
905
|
annotateAction[ $art ]*
|
|
922
|
-
'}' { this.
|
|
906
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
907
|
+
{ this.checkExtensionDict( $art.actions ); }
|
|
923
908
|
)?
|
|
924
909
|
optionalSemi
|
|
925
910
|
|
|
|
926
911
|
ACTIONS
|
|
927
912
|
'{' { $art.actions = this.createDict(); }
|
|
928
913
|
annotateAction[ $art ]*
|
|
929
|
-
'}' { this.
|
|
914
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
915
|
+
{ this.checkExtensionDict( $art.actions ); }
|
|
930
916
|
optionalSemi
|
|
931
917
|
|
|
|
932
918
|
'(' { $art.params = this.createDict(); }
|
|
@@ -934,12 +920,14 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
934
920
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
935
921
|
annotateParam[ $art ]
|
|
936
922
|
)*
|
|
937
|
-
')' { this.
|
|
923
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
924
|
+
{ this.checkExtensionDict( $art.params ); }
|
|
938
925
|
(
|
|
939
926
|
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
940
927
|
'{' { $art.elements = this.createDict(); }
|
|
941
928
|
annotateElement[ $art ]*
|
|
942
|
-
'}' { this.
|
|
929
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
930
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
943
931
|
optionalSemi
|
|
944
932
|
|
|
|
945
933
|
requiredSemi
|
|
@@ -948,7 +936,8 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
948
936
|
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
949
937
|
'{' { $art.elements = this.createDict(); }
|
|
950
938
|
annotateElement[ $art ]*
|
|
951
|
-
'}' { this.
|
|
939
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
940
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
952
941
|
optionalSemi
|
|
953
942
|
|
|
954
943
|
|
|
|
@@ -956,74 +945,77 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
956
945
|
)
|
|
957
946
|
;
|
|
958
947
|
|
|
959
|
-
annotateElement[ outer ] locals[ art
|
|
960
|
-
@after{ this.attachLocation($art); }
|
|
948
|
+
annotateElement[ outer ] locals[ art = {} ]
|
|
949
|
+
@after{ this.attachLocation( $art ); }
|
|
961
950
|
:
|
|
962
|
-
{ this.docComment( $
|
|
963
|
-
annotationAssignment_ll1[ $
|
|
951
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
952
|
+
annotationAssignment_ll1[ $art ]*
|
|
964
953
|
name=ident['Element']
|
|
965
|
-
{
|
|
966
|
-
this.docComment( $
|
|
967
|
-
annotationAssignment_ll1[ $
|
|
954
|
+
{ this.addDef( $art, $outer, 'elements', 'annotate', $name.id );
|
|
955
|
+
this.docComment( $art ); }
|
|
956
|
+
annotationAssignment_ll1[ $art ]*
|
|
968
957
|
(
|
|
969
958
|
'{' { $art.elements = this.createDict(); }
|
|
970
959
|
annotateElement[ $art ]*
|
|
971
|
-
'}' { this.
|
|
960
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
961
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
972
962
|
optionalSemi
|
|
973
963
|
|
|
|
974
964
|
requiredSemi
|
|
975
965
|
)
|
|
976
966
|
;
|
|
977
967
|
|
|
978
|
-
annotateAction [ outer ] locals [ art
|
|
979
|
-
@after{ this.attachLocation($art); }
|
|
968
|
+
annotateAction [ outer ] locals [ art = {} ]
|
|
969
|
+
@after{ this.attachLocation( $art ); }
|
|
980
970
|
:
|
|
981
|
-
{ this.docComment( $
|
|
982
|
-
annotationAssignment_ll1[ $
|
|
971
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
972
|
+
annotationAssignment_ll1[ $art ]*
|
|
983
973
|
name=ident['BoundAction']
|
|
984
|
-
{
|
|
985
|
-
this.docComment( $
|
|
986
|
-
annotationAssignment_ll1[ $
|
|
974
|
+
{ this.addDef( $art, $outer, 'actions', 'annotate', $name.id );
|
|
975
|
+
this.docComment( $art ); }
|
|
976
|
+
annotationAssignment_ll1[ $art ]*
|
|
987
977
|
(
|
|
988
978
|
'(' { $art.params = this.createDict(); }
|
|
989
979
|
annotateParam[ $art ]
|
|
990
980
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
991
981
|
annotateParam[ $art ]
|
|
992
982
|
)*
|
|
993
|
-
')' { this.
|
|
983
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
984
|
+
{ this.checkExtensionDict( $art.params ); }
|
|
994
985
|
)?
|
|
995
986
|
(
|
|
996
987
|
RETURNS '{' { $art.elements = this.createDict(); }
|
|
997
988
|
annotateElement[ $art ]*
|
|
998
|
-
'}' { this.
|
|
989
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
990
|
+
{ this.checkExtensionDict( $art.elements ); }
|
|
999
991
|
optionalSemi
|
|
1000
992
|
|
|
|
1001
993
|
requiredSemi
|
|
1002
994
|
)
|
|
1003
995
|
;
|
|
1004
996
|
|
|
1005
|
-
annotateParam [ outer ] locals [ art
|
|
1006
|
-
@after{ this.attachLocation($art); }
|
|
997
|
+
annotateParam [ outer ] locals [ art = {} ]
|
|
998
|
+
@after{ this.attachLocation( $art ); }
|
|
1007
999
|
:
|
|
1008
|
-
{ this.docComment( $
|
|
1009
|
-
annotationAssignment_ll1[ $
|
|
1000
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1001
|
+
annotationAssignment_ll1[ $art ]*
|
|
1010
1002
|
param=ident['Param']
|
|
1011
|
-
{
|
|
1012
|
-
this.docComment( $
|
|
1013
|
-
annotationAssignment_ll1[ $
|
|
1003
|
+
{ this.addDef( $art, $outer, 'params', 'annotate', $param.id );
|
|
1004
|
+
this.docComment( $art ); }
|
|
1005
|
+
annotationAssignment_ll1[ $art ]*
|
|
1014
1006
|
;
|
|
1015
1007
|
|
|
1016
1008
|
// Element definition and its helpers ----------------------------------------
|
|
1017
1009
|
|
|
1018
|
-
enumSymbolDef[ outer ] locals[ art
|
|
1019
|
-
@after { this.attachLocation($art); }
|
|
1010
|
+
enumSymbolDef[ outer ] locals[ art = {} ]
|
|
1011
|
+
@after { this.attachLocation( $art ); }
|
|
1020
1012
|
:
|
|
1021
|
-
{ this.docComment( $
|
|
1022
|
-
annotationAssignment_ll1[ $
|
|
1013
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1014
|
+
annotationAssignment_ll1[ $art ]*
|
|
1023
1015
|
name=ident['Enum']
|
|
1024
|
-
{
|
|
1025
|
-
this.docComment( $
|
|
1026
|
-
annotationAssignment_ll1[ $
|
|
1016
|
+
{ this.addDef( $art, $outer, 'enum', 'enum', $name.id );
|
|
1017
|
+
this.docComment( $art ); }
|
|
1018
|
+
annotationAssignment_ll1[ $art ]*
|
|
1027
1019
|
( '='
|
|
1028
1020
|
{ this.excludeExpected( ['Boolean', 'QuotedLiteral', "'#'", 'NULL'] ); }
|
|
1029
1021
|
(
|
|
@@ -1033,8 +1025,8 @@ enumSymbolDef[ outer ] locals[ art, annos = [] ]
|
|
|
1033
1025
|
( plus='+' | min='-' ) num=Number
|
|
1034
1026
|
{ $art.value = this.numberLiteral( $num, $plus||$min ); }
|
|
1035
1027
|
)
|
|
1036
|
-
{ this.docComment( $
|
|
1037
|
-
annotationAssignment_ll1[ $
|
|
1028
|
+
{ this.docComment( $art ); }
|
|
1029
|
+
annotationAssignment_ll1[ $art ]*
|
|
1038
1030
|
)?
|
|
1039
1031
|
requiredSemi
|
|
1040
1032
|
;
|
|
@@ -1045,37 +1037,35 @@ defaultValue[ art ] locals[ elem, elements = {} ]
|
|
|
1045
1037
|
DEFAULT expr=expression { $art.default = $expr.expr; }
|
|
1046
1038
|
;
|
|
1047
1039
|
|
|
1048
|
-
elementDefOrExtend[ outer ] locals[
|
|
1049
|
-
@after { /* #ATN 1 */ if ($
|
|
1050
|
-
// tool complains if I test for ($art)
|
|
1040
|
+
elementDefOrExtend[ outer ] locals[ art = {} ]
|
|
1041
|
+
@after { /* #ATN 1 */ } // if ($art) this.attachLocation( $art ); }
|
|
1051
1042
|
:
|
|
1052
|
-
{ this.docComment( $
|
|
1053
|
-
annotationAssignment_ll1[ $
|
|
1043
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1044
|
+
annotationAssignment_ll1[ $art ]*
|
|
1054
1045
|
// #ATN: element name for definition can be EXTEND
|
|
1055
1046
|
(
|
|
1056
1047
|
EXTEND
|
|
1057
|
-
extendElement[ $
|
|
1048
|
+
extendElement[ $art, $outer ]
|
|
1058
1049
|
|
|
|
1059
|
-
|
|
1050
|
+
elementDefInner[ $art, $outer, true ]
|
|
1060
1051
|
)
|
|
1061
1052
|
;
|
|
1062
1053
|
|
|
1063
|
-
elementDef[ outer ] locals[
|
|
1064
|
-
@after { this.attachLocation($art.art); }
|
|
1054
|
+
elementDef[ outer ] locals[ $art = {} ]
|
|
1065
1055
|
:
|
|
1066
|
-
{ this.docComment( $
|
|
1067
|
-
annotationAssignment_ll1[ $
|
|
1068
|
-
|
|
1056
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1057
|
+
annotationAssignment_ll1[ $art ]*
|
|
1058
|
+
elementDefInner[ $art, $outer, false ]
|
|
1069
1059
|
;
|
|
1070
1060
|
|
|
1071
1061
|
// Actually, this is a subset if elementDefInner...
|
|
1072
1062
|
// TODO: the corresponding restrictions must also be checked in the core
|
|
1073
1063
|
// compiler, as the mixin element could come via CSN
|
|
1074
|
-
mixinElementDef[ outer ] locals[ art ]
|
|
1064
|
+
mixinElementDef[ outer ] locals[ art = {} ]
|
|
1075
1065
|
@after { /* #ATN 2 */ this.attachLocation($art); }
|
|
1076
1066
|
:
|
|
1077
1067
|
name=ident['Mixin']
|
|
1078
|
-
{
|
|
1068
|
+
{ this.addDef( $art, $outer, 'mixin', 'mixin', $name.id ); }
|
|
1079
1069
|
(
|
|
1080
1070
|
':'
|
|
1081
1071
|
// #ATN: referenced type name can be ASSOCIATION or COMPOSITION
|
|
@@ -1097,33 +1087,30 @@ mixinElementDef[ outer ] locals[ art ]
|
|
|
1097
1087
|
requiredSemi
|
|
1098
1088
|
;
|
|
1099
1089
|
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
// No docComment() here
|
|
1103
|
-
annotationAssignment_ll1[ $annos ]+
|
|
1104
|
-
{ if ($messageId) // issue specified in central registry
|
|
1105
|
-
this.message( messageId, this.tokenLocation( $ctx.start, this.getCurrentToken() ) );
|
|
1106
|
-
}
|
|
1107
|
-
;
|
|
1108
|
-
|
|
1109
|
-
elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
1110
|
-
@after{ /* #ATN 5 */ }
|
|
1090
|
+
elementDefInner[ art, outer, allowEq ]
|
|
1091
|
+
@after{ /* #ATN 5 */ this.attachLocation( $art ); }
|
|
1111
1092
|
:
|
|
1112
1093
|
// TODO: it would be excellent to remove ELEMENT...
|
|
1113
1094
|
// or have a special ident rule without the ELEMENT
|
|
1114
1095
|
// Reason: it would be good for error recovery to start a major block without LL1 ambiguity
|
|
1115
1096
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1116
1097
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^[:{@=}]$/ ); }
|
|
1117
|
-
virtual=VIRTUAL
|
|
1098
|
+
( virtual=VIRTUAL { $art.virtual = this.valueWithTokenLocation( true, $virtual ); } )?
|
|
1099
|
+
( key=KEY { $art.key = this.valueWithTokenLocation( true, $key ); } )?
|
|
1118
1100
|
// #ATN: element name can be MASKED or ELEMENT (2x)
|
|
1119
|
-
masked=MASKED
|
|
1101
|
+
( masked=MASKED
|
|
1102
|
+
{
|
|
1103
|
+
$art.masked = this.valueWithTokenLocation( true, $masked ) ;
|
|
1104
|
+
this.message( 'syntax-invalid-masked', $masked, { keyword: 'masked' },
|
|
1105
|
+
'Keyword $(KEYWORD) not supported' );
|
|
1106
|
+
}
|
|
1107
|
+
)?
|
|
1108
|
+
// TODO: order?
|
|
1120
1109
|
ELEMENT?
|
|
1121
1110
|
name=ident['Element']
|
|
1122
|
-
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
this.docComment( $annos ); }
|
|
1126
|
-
annotationAssignment_fix[ $annos ]*
|
|
1111
|
+
{ this.addDef( $art, $outer, 'elements', 'element', $name.id );
|
|
1112
|
+
this.docComment( $art ); }
|
|
1113
|
+
annotationAssignment_fix[ $art ]*
|
|
1127
1114
|
// TODO: we can think of making the typeSpec optional and do checks instead:
|
|
1128
1115
|
// type optional with '=', type required otherwise
|
|
1129
1116
|
(
|
|
@@ -1138,7 +1125,6 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1138
1125
|
(
|
|
1139
1126
|
typeStruct[ $art ]
|
|
1140
1127
|
nullability[ $art ]?
|
|
1141
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-struct' ]?
|
|
1142
1128
|
requiredSemi
|
|
1143
1129
|
|
|
|
1144
1130
|
typeAssociationBase[ $art, true ]
|
|
@@ -1155,11 +1141,11 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1155
1141
|
typeCompoStruct[ $art.target ] optionalSemi
|
|
1156
1142
|
|
|
|
1157
1143
|
// we do not support `Composition of many { e }` - ambiguity ad-hoc target versus foreign keys!
|
|
1158
|
-
typeToMany[ $art ] typeAssociationElementCont[ $art
|
|
1144
|
+
typeToMany[ $art ] typeAssociationElementCont[ $art ]
|
|
1159
1145
|
|
|
|
1160
|
-
typeToOne[ $art ] typeAssociationElementCont[ $art
|
|
1146
|
+
typeToOne[ $art ] typeAssociationElementCont[ $art ]
|
|
1161
1147
|
|
|
|
1162
|
-
simplePath[ $art.target, 'artref' ] typeAssociationElementCont[ $art
|
|
1148
|
+
simplePath[ $art.target, 'artref' ] typeAssociationElementCont[ $art ]
|
|
1163
1149
|
)
|
|
1164
1150
|
|
|
|
1165
1151
|
(
|
|
@@ -1171,52 +1157,55 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1171
1157
|
// #ATN: typeRefOptArgs can start with TYPE
|
|
1172
1158
|
( typeStruct[ $art.items ]
|
|
1173
1159
|
nullability[ $art.items ]?
|
|
1174
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-struct' ]?
|
|
1175
1160
|
| typeTypeOf[ $art.items ]
|
|
1176
1161
|
nullability[ $art.items ]?
|
|
1177
|
-
{ this.docComment( $
|
|
1178
|
-
annotationAssignment_ll1[ $
|
|
1162
|
+
{ this.docComment( $art ); }
|
|
1163
|
+
annotationAssignment_ll1[ $art ]*
|
|
1179
1164
|
| typeRefOptArgs[ $art.items ]
|
|
1180
|
-
nullability[ $art.items ]?
|
|
1181
|
-
{ this.docComment( $
|
|
1182
|
-
annotationAssignment_ll1[ $
|
|
1165
|
+
nullability[ $art.items ]? // only if not followed by `enum`
|
|
1166
|
+
{ this.docComment( $art ); }
|
|
1167
|
+
annotationAssignment_ll1[ $art ]*
|
|
1183
1168
|
(
|
|
1169
|
+
{ if ($art.items.notNull) {
|
|
1170
|
+
this.message( 'syntax-unexpected-null', $art.items.notNull.location,
|
|
1171
|
+
{ keyword: $art.items.notNull.val ? 'not null' : 'null' } );
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1184
1174
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1185
1175
|
enumSymbolDef[ $art.items ]*
|
|
1186
|
-
'}' { this.
|
|
1187
|
-
|
|
1176
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1177
|
+
nullability[ $art.items ]?
|
|
1188
1178
|
)?
|
|
1189
1179
|
)
|
|
1190
1180
|
requiredSemi // also req after struct/enum
|
|
1191
1181
|
|
|
|
1192
1182
|
typeTypeOf[ $art ] elementProperties[ $art ]?
|
|
1193
|
-
{ this.docComment( $
|
|
1194
|
-
annotationAssignment_ll1[ $
|
|
1183
|
+
{ this.docComment( $art ); }
|
|
1184
|
+
annotationAssignment_ll1[ $art ]*
|
|
1195
1185
|
requiredSemi // also req after foreign key spec
|
|
1196
1186
|
|
|
|
1197
1187
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1198
1188
|
typeRefOptArgs[ $art ]
|
|
1199
|
-
{ this.docComment( $
|
|
1200
|
-
annotationAssignment_ll1[ $
|
|
1189
|
+
{ this.docComment( $art ); }
|
|
1190
|
+
annotationAssignment_ll1[ $art ]*
|
|
1201
1191
|
( elementProperties[ $art ]
|
|
1202
|
-
{ this.docComment( $
|
|
1203
|
-
annotationAssignment_ll1[ $
|
|
1192
|
+
{ this.docComment( $art ); }
|
|
1193
|
+
annotationAssignment_ll1[ $art ]*
|
|
1204
1194
|
)?
|
|
1205
1195
|
requiredSemi
|
|
1206
1196
|
|
|
|
1207
1197
|
typeRefOptArgs[ $art ]
|
|
1208
|
-
{ this.docComment( $
|
|
1209
|
-
annotationAssignment_ll1[ $
|
|
1198
|
+
{ this.docComment( $art ); }
|
|
1199
|
+
annotationAssignment_ll1[ $art ]*
|
|
1210
1200
|
(
|
|
1211
1201
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1212
1202
|
enumSymbolDef[ $art ]*
|
|
1213
|
-
'}' { this.
|
|
1203
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1214
1204
|
elementProperties[ $art ]?
|
|
1215
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1216
1205
|
|
|
|
1217
1206
|
elementProperties[ $art ]
|
|
1218
|
-
{ this.docComment( $
|
|
1219
|
-
annotationAssignment_ll1[ $
|
|
1207
|
+
{ this.docComment( $art ); }
|
|
1208
|
+
annotationAssignment_ll1[ $art ]*
|
|
1220
1209
|
)?
|
|
1221
1210
|
requiredSemi // also req after enum spec
|
|
1222
1211
|
)
|
|
@@ -1229,65 +1218,45 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1229
1218
|
else if ($e.expr)
|
|
1230
1219
|
$art.value = $e.expr;
|
|
1231
1220
|
}
|
|
1232
|
-
{ this.docComment( $
|
|
1233
|
-
annotationAssignment_ll1[ $
|
|
1221
|
+
{ this.docComment( $art ); }
|
|
1222
|
+
annotationAssignment_ll1[ $art ]* // for enum symbol def via EXTEND
|
|
1234
1223
|
requiredSemi
|
|
1235
1224
|
)
|
|
1236
1225
|
;
|
|
1237
1226
|
|
|
1238
|
-
extendElement[
|
|
1239
|
-
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
1227
|
+
extendElement[ art, outer ]
|
|
1228
|
+
@after{ /* #ATN 1 */ this.attachLocation( $art ); }
|
|
1240
1229
|
:
|
|
1241
1230
|
// #ATN: element name can be ELEMENT
|
|
1242
|
-
expected=ELEMENT
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
extendWithOptElements[ $art, $annos ]
|
|
1247
|
-
;
|
|
1248
|
-
|
|
1249
|
-
bracedSelectItemListDef[ query ]
|
|
1250
|
-
:
|
|
1251
|
-
'{'
|
|
1252
|
-
{ if (!$query.columns) $query.columns = []; } // set it early to avoid "wildcard" errors
|
|
1253
|
-
(
|
|
1254
|
-
selectItemDef[ $query.columns ]
|
|
1255
|
-
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1256
|
-
selectItemDef[ $query.columns ]
|
|
1257
|
-
)*
|
|
1258
|
-
)?
|
|
1259
|
-
'}'
|
|
1231
|
+
( expected=ELEMENT { $art.expectedKind = 'element'; } )?
|
|
1232
|
+
name=ident['Element']
|
|
1233
|
+
{ this.addDef( $art, $outer, 'elements', 'extend', $name.id ); }
|
|
1234
|
+
extendWithOptElements[ $art, $art ]
|
|
1260
1235
|
;
|
|
1261
1236
|
|
|
1262
|
-
selectItemDef[ outer ] locals[
|
|
1263
|
-
@after{ if ($
|
|
1237
|
+
selectItemDef[ outer ] locals[ art ]
|
|
1238
|
+
@after{ if ($art) this.attachLocation( $art ); }
|
|
1264
1239
|
:
|
|
1265
1240
|
star='*'
|
|
1266
1241
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1267
1242
|
|
|
|
1268
|
-
{ this.docComment( $
|
|
1269
|
-
annotationAssignment_atn[ $
|
|
1243
|
+
{ $art = {};; this.docComment( $art ); }
|
|
1244
|
+
annotationAssignment_atn[ $art ]*
|
|
1270
1245
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1271
1246
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^([,.:\[@]|as)$/i ) ; } // not '{'
|
|
1272
|
-
virtual=VIRTUAL?
|
|
1273
|
-
key=KEY?
|
|
1274
|
-
|
|
1275
|
-
{
|
|
1276
|
-
if ($virtual) $art.art.virtual = this.valueWithTokenLocation( true, $virtual );
|
|
1277
|
-
if ($key) $art.art.key = this.valueWithTokenLocation( true, $key );
|
|
1278
|
-
}
|
|
1247
|
+
( virtual=VIRTUAL { $art.virtual = this.valueWithTokenLocation( true, $virtual ); } )?
|
|
1248
|
+
( key=KEY { $art.key = this.valueWithTokenLocation( true, $key ); } )?
|
|
1249
|
+
selectItemDefBody[ $art, $outer ]
|
|
1279
1250
|
;
|
|
1280
1251
|
|
|
1281
|
-
selectItemDefBody[
|
|
1282
|
-
@after{ /* #ATN 2 */
|
|
1252
|
+
selectItemDefBody[ art, outer ]
|
|
1253
|
+
@after{ /* #ATN 2 */ }
|
|
1283
1254
|
:
|
|
1255
|
+
{ $outer.push( $art ); }
|
|
1284
1256
|
(
|
|
1285
|
-
e=expression
|
|
1257
|
+
e=expression { $art.value = $e.expr; }
|
|
1286
1258
|
// we cannot use 'condition' instead, as long as we allow aliases without
|
|
1287
1259
|
// AS (using rule 'ident' instead of 'identNoKeyword') -> ambiguities
|
|
1288
|
-
{
|
|
1289
|
-
$art = this.addItem( $outer, null, null, $annos, { value: $e.expr } );
|
|
1290
|
-
}
|
|
1291
1260
|
( AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1292
1261
|
| n2=ident['Item'] { $art.name = this.fragileAlias( $n2.id, true ); }
|
|
1293
1262
|
| { if (this.getCurrentToken().text !== '.') this.classifyImplicitName( 'Item', $e.expr ); }
|
|
@@ -1311,13 +1280,12 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1311
1280
|
)
|
|
1312
1281
|
)?
|
|
1313
1282
|
|
|
|
1314
|
-
{ $art = this.addItem( $outer, null, null, $annos ); }
|
|
1315
1283
|
selectItemInlineList[ $art, 'expand' ]
|
|
1316
1284
|
excludingClause[ $art ]?
|
|
1317
1285
|
AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1318
1286
|
)
|
|
1319
|
-
{ this.docComment( $
|
|
1320
|
-
annotationAssignment_fix[ $
|
|
1287
|
+
{ this.docComment( $art ); }
|
|
1288
|
+
annotationAssignment_fix[ $art ]*
|
|
1321
1289
|
( ':'
|
|
1322
1290
|
// #ATN: typeRefOptArgs can start with TYPE, REDIRECTED
|
|
1323
1291
|
( re=REDIRECTED to=TO
|
|
@@ -1326,15 +1294,15 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1326
1294
|
(
|
|
1327
1295
|
typeAssociationCont[ $art ]
|
|
1328
1296
|
|
|
|
1329
|
-
{ this.docComment( $
|
|
1330
|
-
annotationAssignment_ll1[ $
|
|
1297
|
+
{ this.docComment( $art ); }
|
|
1298
|
+
annotationAssignment_ll1[ $art ]*
|
|
1331
1299
|
)
|
|
1332
1300
|
| typeTypeOf[ $art ]
|
|
1333
|
-
{ this.docComment( $
|
|
1334
|
-
annotationAssignment_ll1[ $
|
|
1335
|
-
| typeRefOptArgs[ $art ]
|
|
1336
|
-
{ this.docComment( $
|
|
1337
|
-
annotationAssignment_ll1[ $
|
|
1301
|
+
{ this.docComment( $art ); }
|
|
1302
|
+
annotationAssignment_ll1[ $art ]*
|
|
1303
|
+
| typeRefOptArgs[ $art ]
|
|
1304
|
+
{ this.docComment( $art ); }
|
|
1305
|
+
annotationAssignment_ll1[ $art ]*
|
|
1338
1306
|
|
|
|
1339
1307
|
typeAssociationBase[ $art, false ]
|
|
1340
1308
|
// #ATN: path could start with MANY or ONE - make sure a token follows in same rule!
|
|
@@ -1345,28 +1313,39 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1345
1313
|
)?
|
|
1346
1314
|
;
|
|
1347
1315
|
|
|
1316
|
+
bracedSelectItemListDef[ query ]
|
|
1317
|
+
:
|
|
1318
|
+
'{' { $query.columns = this.createArray(); }
|
|
1319
|
+
(
|
|
1320
|
+
selectItemDef[ $query.columns ]
|
|
1321
|
+
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1322
|
+
selectItemDef[ $query.columns ]
|
|
1323
|
+
)*
|
|
1324
|
+
)?
|
|
1325
|
+
'}' { this.finalizeDictOrArray( $query.columns ); }
|
|
1326
|
+
;
|
|
1327
|
+
|
|
1348
1328
|
selectItemInlineList[ art, clause ]
|
|
1349
1329
|
:
|
|
1350
|
-
'{'
|
|
1351
|
-
{ $art[$clause] = []; }
|
|
1330
|
+
'{' { $art[$clause] = this.createArray(); }
|
|
1352
1331
|
(
|
|
1353
1332
|
selectItemInlineDef[ $art[$clause] ]
|
|
1354
1333
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1355
1334
|
selectItemInlineDef[ $art[$clause] ]
|
|
1356
1335
|
)*
|
|
1357
1336
|
)?
|
|
1358
|
-
'}'
|
|
1337
|
+
'}' { this.finalizeDictOrArray( $art[$clause] ); }
|
|
1359
1338
|
;
|
|
1360
1339
|
|
|
1361
|
-
selectItemInlineDef[ outer ] locals[
|
|
1362
|
-
@after{ if ($
|
|
1340
|
+
selectItemInlineDef[ outer ] locals[ art ]
|
|
1341
|
+
@after{ if ($art) this.attachLocation( $art ); }
|
|
1363
1342
|
:
|
|
1364
1343
|
star='*'
|
|
1365
1344
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1366
1345
|
|
|
|
1367
|
-
{ this.docComment( $
|
|
1368
|
-
annotationAssignment_atn[ $
|
|
1369
|
-
|
|
1346
|
+
{ $art = {};; this.docComment( $art ); }
|
|
1347
|
+
annotationAssignment_atn[ $art ]*
|
|
1348
|
+
selectItemDefBody[ $art, $outer ]
|
|
1370
1349
|
;
|
|
1371
1350
|
|
|
1372
1351
|
parameterListDef[ art ]
|
|
@@ -1380,51 +1359,22 @@ parameterListDef[ art ]
|
|
|
1380
1359
|
parameterDef[ $art ]
|
|
1381
1360
|
)*
|
|
1382
1361
|
)?
|
|
1383
|
-
')' { this.
|
|
1362
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
1384
1363
|
;
|
|
1385
1364
|
|
|
1386
|
-
parameterDef[ outer ] locals[ art
|
|
1387
|
-
@after { this.attachLocation($art); }
|
|
1365
|
+
parameterDef[ outer ] locals[ art = {} ]
|
|
1366
|
+
@after { this.attachLocation( $art ); }
|
|
1388
1367
|
:
|
|
1389
|
-
{ this.docComment( $
|
|
1390
|
-
annotationAssignment_ll1[ $
|
|
1368
|
+
{ this.docComment( $art ); }
|
|
1369
|
+
annotationAssignment_ll1[ $art ]*
|
|
1391
1370
|
name=ident['Param']
|
|
1392
|
-
{
|
|
1393
|
-
this.docComment( $
|
|
1394
|
-
annotationAssignment_fix[ $
|
|
1371
|
+
{ this.addDef( $art, $outer, 'params', 'param', $name.id );
|
|
1372
|
+
this.docComment( $art ); }
|
|
1373
|
+
annotationAssignment_fix[ $art ]*
|
|
1395
1374
|
typeSpec[ $art ]
|
|
1396
1375
|
defaultValue[ $art ]?
|
|
1397
|
-
{ this.docComment( $
|
|
1398
|
-
annotationAssignment_ll1[ $
|
|
1399
|
-
;
|
|
1400
|
-
|
|
1401
|
-
entityParameters[ art ]
|
|
1402
|
-
:
|
|
1403
|
-
'(' { $art.params = this.createDict(); }
|
|
1404
|
-
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1405
|
-
// see annotationAssignment_paren
|
|
1406
|
-
(
|
|
1407
|
-
entityParameterDef[ $art ]
|
|
1408
|
-
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1409
|
-
entityParameterDef[ $art ]
|
|
1410
|
-
)*
|
|
1411
|
-
)?
|
|
1412
|
-
')' { this.setDictEndLocation( $art.params ); }
|
|
1413
|
-
;
|
|
1414
|
-
|
|
1415
|
-
entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
1416
|
-
@after { this.attachLocation($art); }
|
|
1417
|
-
:
|
|
1418
|
-
{ this.docComment( $annos ); }
|
|
1419
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1420
|
-
name=ident['Param']
|
|
1421
|
-
{ $art = this.addDef( $outer, 'params', 'param', $name.id, $annos );
|
|
1422
|
-
this.docComment( $annos ); }
|
|
1423
|
-
annotationAssignment_fix[ $annos ]*
|
|
1424
|
-
typeSpec[ $art ]
|
|
1425
|
-
defaultValue[ $art ]?
|
|
1426
|
-
{ this.docComment( $annos ); }
|
|
1427
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1376
|
+
{ this.docComment( $art ); }
|
|
1377
|
+
annotationAssignment_ll1[ $art ]*
|
|
1428
1378
|
;
|
|
1429
1379
|
|
|
1430
1380
|
nullability[ art ]
|
|
@@ -1451,21 +1401,25 @@ elementProperties[ elem ]
|
|
|
1451
1401
|
|
|
1452
1402
|
// View definitions ----------------------------------------------------------
|
|
1453
1403
|
|
|
1454
|
-
viewDef[
|
|
1455
|
-
@after { this.attachLocation($art); }
|
|
1404
|
+
viewDef[ art, outer ] locals[ name = {} ]
|
|
1405
|
+
@after { this.attachLocation( $art ); }
|
|
1456
1406
|
:
|
|
1457
1407
|
v=VIEW simplePath[ $name, 'Entity' ]
|
|
1458
|
-
{ $art
|
|
1459
|
-
this.
|
|
1460
|
-
|
|
1408
|
+
{ $art['$'+'syntax'] = 'view';
|
|
1409
|
+
this.addDef( $art, $outer, 'artifacts', 'entity', $name );
|
|
1410
|
+
this.docComment( $art ); }
|
|
1411
|
+
annotationAssignment_fix[ $art ]*
|
|
1461
1412
|
(
|
|
1462
|
-
|
|
1413
|
+
parameterListDef[ $art ]
|
|
1463
1414
|
|
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1415
|
+
// TODO: warning deprecated?
|
|
1416
|
+
( HideAlternatives | WITH ) { $art.params = this.createDict(); }
|
|
1417
|
+
PARAMETERS
|
|
1418
|
+
parameterDef[ $art ]
|
|
1419
|
+
( ',' parameterDef[ $art ] )* // no optional final ',' here
|
|
1420
|
+
{ this.finalizeDictOrArray( $art.params ); }
|
|
1467
1421
|
)?
|
|
1468
|
-
AS qe=queryExpression { $art.query = $qe.query; }
|
|
1422
|
+
AS qe=queryExpression { $art.query = $qe.query; }
|
|
1469
1423
|
// TODO check ANTLR: bad msg with 'view V as'<eof> but 'view V as FOO' is fine
|
|
1470
1424
|
requiredSemi
|
|
1471
1425
|
;
|
|
@@ -1496,12 +1450,12 @@ typeSpec[ art ] // for params
|
|
|
1496
1450
|
(
|
|
1497
1451
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1498
1452
|
enumSymbolDef[ $art ]*
|
|
1499
|
-
'}' { this.
|
|
1453
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1500
1454
|
)?
|
|
1501
1455
|
)
|
|
1502
1456
|
;
|
|
1503
1457
|
|
|
1504
|
-
returnTypeSpec[ art
|
|
1458
|
+
returnTypeSpec[ art ]
|
|
1505
1459
|
@after{ /* #ATN 1 */ }
|
|
1506
1460
|
:
|
|
1507
1461
|
ret=RETURNS { $art.returns = { location: this.tokenLocation( $ret ), kind: 'param' }; }
|
|
@@ -1517,17 +1471,15 @@ returnTypeSpec[ art, annos ]
|
|
|
1517
1471
|
(
|
|
1518
1472
|
ENUM '{' { $art.returns.enum = this.createDict(); }
|
|
1519
1473
|
enumSymbolDef[ $art.returns ]*
|
|
1520
|
-
'}' { this.
|
|
1521
|
-
|
|
|
1522
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-params' ]
|
|
1474
|
+
'}' { this.finalizeDictOrArray( $art.returns.enum ); }
|
|
1523
1475
|
)?
|
|
1524
1476
|
)
|
|
1525
1477
|
|
|
1526
|
-
requiredSemi // currently for all - might change if we get rid of the misplaced annos
|
|
1478
|
+
requiredSemi // currently for all - might change if we get rid of the misplaced annos (TODO: Now removed)
|
|
1527
1479
|
;
|
|
1528
1480
|
|
|
1529
1481
|
|
|
1530
|
-
typeSpecSemi[ art
|
|
1482
|
+
typeSpecSemi[ art ] // with 'includes', for type and annotation defs
|
|
1531
1483
|
@after{ /* #ATN 3 */ }
|
|
1532
1484
|
:
|
|
1533
1485
|
typeStruct[ $art ]
|
|
@@ -1565,18 +1517,28 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1565
1517
|
optionalSemi
|
|
1566
1518
|
| typeTypeOf[ $art.items ]
|
|
1567
1519
|
nullability[ $art.items ]?
|
|
1568
|
-
{ this.docComment( $
|
|
1569
|
-
annotationAssignment_ll1[ $
|
|
1520
|
+
{ this.docComment( $art ); }
|
|
1521
|
+
annotationAssignment_ll1[ $art ]*
|
|
1570
1522
|
requiredSemi
|
|
1571
1523
|
| typeRefOptArgs[ $art.items ]
|
|
1572
|
-
nullability[ $art.items ]?
|
|
1573
|
-
{ this.docComment( $
|
|
1574
|
-
annotationAssignment_ll1[ $
|
|
1524
|
+
nullability[ $art.items ]? // only if not followed by `enum`
|
|
1525
|
+
{ this.docComment( $art ); }
|
|
1526
|
+
annotationAssignment_ll1[ $art ]*
|
|
1575
1527
|
(
|
|
1528
|
+
{ if ($art.items.notNull) {
|
|
1529
|
+
this.message( 'syntax-unexpected-null', $art.items.notNull.location,
|
|
1530
|
+
{ keyword: $art.items.notNull.val ? 'not null' : 'null' } );
|
|
1531
|
+
}
|
|
1532
|
+
}
|
|
1576
1533
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1577
1534
|
enumSymbolDef[ $art.items ]*
|
|
1578
|
-
'}' { this.
|
|
1579
|
-
|
|
1535
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1536
|
+
(
|
|
1537
|
+
nullability[ $art.items ]
|
|
1538
|
+
requiredSemi
|
|
1539
|
+
|
|
|
1540
|
+
optionalSemi
|
|
1541
|
+
)
|
|
1580
1542
|
|
|
|
1581
1543
|
requiredSemi
|
|
1582
1544
|
)
|
|
@@ -1584,14 +1546,14 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1584
1546
|
|
|
|
1585
1547
|
typeTypeOf[ $art ]
|
|
1586
1548
|
defaultValue[ $art ]?
|
|
1587
|
-
{ this.docComment( $
|
|
1588
|
-
annotationAssignment_ll1[ $
|
|
1549
|
+
{ this.docComment( $art ); }
|
|
1550
|
+
annotationAssignment_ll1[ $art ]* requiredSemi
|
|
1589
1551
|
|
|
|
1590
1552
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1591
1553
|
typeRefOptArgs[ $art ]
|
|
1592
1554
|
defaultValue[ $art ]?
|
|
1593
|
-
{ this.docComment( $
|
|
1594
|
-
annotationAssignment_ll1[ $
|
|
1555
|
+
{ this.docComment( $art ); }
|
|
1556
|
+
annotationAssignment_ll1[ $art ]*
|
|
1595
1557
|
requiredSemi
|
|
1596
1558
|
|
|
|
1597
1559
|
// alt lookahead includes MANY '{'
|
|
@@ -1599,12 +1561,12 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1599
1561
|
simplePath[ $art.type, 'artref' ]
|
|
1600
1562
|
(
|
|
1601
1563
|
typeRefArgs[ $art ]
|
|
1602
|
-
{ this.docComment( $
|
|
1603
|
-
annotationAssignment_ll1[ $
|
|
1564
|
+
{ this.docComment( $art ); }
|
|
1565
|
+
annotationAssignment_ll1[ $art ]*
|
|
1604
1566
|
(
|
|
1605
1567
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1606
1568
|
enumSymbolDef[ $art ]*
|
|
1607
|
-
'}' { this.
|
|
1569
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1608
1570
|
(
|
|
1609
1571
|
optionalSemi
|
|
1610
1572
|
|
|
|
@@ -1619,12 +1581,12 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1619
1581
|
':' // with element, e.g. `type T : E:elem enum { ... }`
|
|
1620
1582
|
{ $art.type.scope = $art.type.path.length; }
|
|
1621
1583
|
simplePath[ $art.type, 'ref']
|
|
1622
|
-
{ this.docComment( $
|
|
1623
|
-
annotationAssignment_ll1[ $
|
|
1584
|
+
{ this.docComment( $art ); }
|
|
1585
|
+
annotationAssignment_ll1[ $art ]*
|
|
1624
1586
|
(
|
|
1625
1587
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1626
1588
|
enumSymbolDef[ $art ]*
|
|
1627
|
-
'}' { this.
|
|
1589
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1628
1590
|
(
|
|
1629
1591
|
optionalSemi
|
|
1630
1592
|
|
|
|
@@ -1636,12 +1598,12 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1636
1598
|
requiredSemi
|
|
1637
1599
|
)
|
|
1638
1600
|
|
|
|
1639
|
-
{ this.docComment( $
|
|
1640
|
-
annotationAssignment_ll1[ $
|
|
1601
|
+
{ this.docComment( $art ); }
|
|
1602
|
+
annotationAssignment_ll1[ $art ]*
|
|
1641
1603
|
(
|
|
1642
1604
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1643
1605
|
enumSymbolDef[ $art ]*
|
|
1644
|
-
'}' { this.
|
|
1606
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1645
1607
|
(
|
|
1646
1608
|
optionalSemi
|
|
1647
1609
|
|
|
|
@@ -1669,7 +1631,7 @@ typeStruct[ art, attachLoc = false ]
|
|
|
1669
1631
|
:
|
|
1670
1632
|
'{' { $art.elements = this.createDict(); }
|
|
1671
1633
|
elementDef[ $art ]*
|
|
1672
|
-
'}' { this.
|
|
1634
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
1673
1635
|
;
|
|
1674
1636
|
|
|
1675
1637
|
typeCompoStruct[ art ]
|
|
@@ -1677,7 +1639,7 @@ typeCompoStruct[ art ]
|
|
|
1677
1639
|
:
|
|
1678
1640
|
COMPOSITIONofBRACE { $art.elements = this.createDict(); }
|
|
1679
1641
|
elementDef[ $art ]*
|
|
1680
|
-
'}' { this.
|
|
1642
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
1681
1643
|
;
|
|
1682
1644
|
|
|
1683
1645
|
typeArray[ art ]
|
|
@@ -1699,7 +1661,7 @@ typeArray[ art ]
|
|
|
1699
1661
|
(
|
|
1700
1662
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1701
1663
|
enumSymbolDef[ $art.items ]*
|
|
1702
|
-
'}' { this.
|
|
1664
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1703
1665
|
)?
|
|
1704
1666
|
)
|
|
1705
1667
|
;
|
|
@@ -1728,33 +1690,31 @@ typeAssociationCont[ art ]
|
|
|
1728
1690
|
:
|
|
1729
1691
|
(
|
|
1730
1692
|
'{' { $art.foreignKeys = this.createDict(); }
|
|
1731
|
-
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1732
1693
|
(
|
|
1733
1694
|
foreignKey[ $art ]
|
|
1734
1695
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1735
1696
|
foreignKey[ $art ]
|
|
1736
1697
|
)*
|
|
1737
1698
|
)?
|
|
1738
|
-
'}' { this.
|
|
1699
|
+
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1739
1700
|
|
|
|
1740
1701
|
ON cond=condition
|
|
1741
1702
|
{ $art.on=$cond.cond; }
|
|
1742
1703
|
)
|
|
1743
1704
|
;
|
|
1744
1705
|
|
|
1745
|
-
typeAssociationElementCont[ art
|
|
1706
|
+
typeAssociationElementCont[ art ] // including Composition
|
|
1746
1707
|
// optional NULL / NOT NULL for managed association only
|
|
1747
1708
|
:
|
|
1748
1709
|
(
|
|
1749
1710
|
'{' { $art.foreignKeys = this.createDict(); }
|
|
1750
|
-
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1751
1711
|
(
|
|
1752
1712
|
foreignKey[ $art ]
|
|
1753
1713
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1754
1714
|
foreignKey[ $art ]
|
|
1755
1715
|
)*
|
|
1756
1716
|
)?
|
|
1757
|
-
'}' { this.
|
|
1717
|
+
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1758
1718
|
nullability[ $art ]?
|
|
1759
1719
|
|
|
|
1760
1720
|
ON cond=condition
|
|
@@ -1762,8 +1722,8 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1762
1722
|
|
|
|
1763
1723
|
nullability[ $art ]
|
|
1764
1724
|
)?
|
|
1765
|
-
{ this.docComment( $
|
|
1766
|
-
annotationAssignment_ll1[ $
|
|
1725
|
+
{ this.docComment( $art ); }
|
|
1726
|
+
annotationAssignment_ll1[ $art ]*
|
|
1767
1727
|
requiredSemi // also req after foreign key spec
|
|
1768
1728
|
;
|
|
1769
1729
|
|
|
@@ -1817,10 +1777,9 @@ cardinality[ art ] locals[ card = {} ]
|
|
|
1817
1777
|
foreignKey[ outer ] locals[ art = {}, elem = {} ]
|
|
1818
1778
|
@after { this.attachLocation($art); }
|
|
1819
1779
|
:
|
|
1820
|
-
simplePath[ $elem, 'ref' ]
|
|
1780
|
+
simplePath[ $elem, 'ref' ] { $art.targetElement = $elem; }
|
|
1821
1781
|
( AS name=ident['Key'] )?
|
|
1822
|
-
{
|
|
1823
|
-
undefined, { targetElement: $elem } ); }
|
|
1782
|
+
{ this.addDef( $art, $outer, 'foreignKeys', 'key', ($ctx.name) ? $name.id : $elem.path ); }
|
|
1824
1783
|
;
|
|
1825
1784
|
|
|
1826
1785
|
typeTypeOf[ art ] locals[ _sync = 'nop' ]
|
|
@@ -1852,11 +1811,11 @@ typeRefOptArgs[ art ]
|
|
|
1852
1811
|
|
|
1853
1812
|
typeRefArgs[ art ]
|
|
1854
1813
|
:
|
|
1855
|
-
paren='('
|
|
1814
|
+
paren='(' { $art['$'+'typeArgs'] = this.createArray(); }
|
|
1856
1815
|
(
|
|
1857
1816
|
// unnamed arguments
|
|
1858
1817
|
head=Number
|
|
1859
|
-
{ $art['$'+'typeArgs']
|
|
1818
|
+
{ $art['$'+'typeArgs'].push( this.numberLiteral( $head ) ); }
|
|
1860
1819
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1861
1820
|
(
|
|
1862
1821
|
v=VARIABLE
|
|
@@ -1880,14 +1839,14 @@ typeRefArgs[ art ]
|
|
|
1880
1839
|
typeNamedArg[ $art ]
|
|
1881
1840
|
)*
|
|
1882
1841
|
)
|
|
1883
|
-
')'
|
|
1842
|
+
')'{ this.finalizeDictOrArray( $art['$'+'typeArgs']); }
|
|
1884
1843
|
;
|
|
1885
1844
|
|
|
1886
1845
|
typeNamedArg[ art ] locals[ arg = '' ]
|
|
1887
1846
|
:
|
|
1888
1847
|
name=ident['paramname']
|
|
1889
1848
|
':'
|
|
1890
|
-
{ if (this.checkTypeFacet( $art, $name.id ))
|
|
1849
|
+
{ if ($name.id && this.checkTypeFacet( $art, $name.id ))
|
|
1891
1850
|
$arg = $name.id.id;
|
|
1892
1851
|
}
|
|
1893
1852
|
(
|
|
@@ -1924,10 +1883,10 @@ queryExpression returns[ query ] // QLSubqueryComplex, SubqueryComplex
|
|
|
1924
1883
|
| op=MINUS q=DISTINCT?
|
|
1925
1884
|
)
|
|
1926
1885
|
qt=queryTerm
|
|
1927
|
-
{ $query = this.leftAssocBinaryOp( $query, $op, $q, $qt.query );; $ctx.q = null; }
|
|
1886
|
+
{ if ($qt.query) $query = this.leftAssocBinaryOp( $query, $op, $q, $qt.query );; $ctx.q = null; }
|
|
1928
1887
|
)*
|
|
1929
|
-
( ob=orderByClause[ $query ] { $query = $ob.query; } ) ?
|
|
1930
|
-
( lc=limitClause[ $query ] { $query = $lc.query; } ) ?
|
|
1888
|
+
( ob=orderByClause[ $query ] { if ($ob.query) $query = $ob.query; } ) ?
|
|
1889
|
+
( lc=limitClause[ $query ] { if ($lc.query) $query = $lc.query; } ) ?
|
|
1931
1890
|
;
|
|
1932
1891
|
|
|
1933
1892
|
orderByClause[ inQuery ] returns [ query ]
|
|
@@ -2026,7 +1985,7 @@ overClause returns [ over ]
|
|
|
2026
1985
|
@after { this.attachLocation( $over ); }
|
|
2027
1986
|
:
|
|
2028
1987
|
o=OVER { $over = { op: this.valueWithTokenLocation( 'over', $o ) , args: [] } }
|
|
2029
|
-
'('
|
|
1988
|
+
'(' // TODO: check whether an extra location could be useful
|
|
2030
1989
|
( pb=partitionByClause { $over.args.push( $pb.expr ); } )?
|
|
2031
1990
|
( ob=overOrderByClause { $over.args.push( $ob.expr ); } )?
|
|
2032
1991
|
( wf=windowFrameClause { $over.args.push( $wf.wf ); } )?
|
|
@@ -2079,13 +2038,13 @@ queryPrimary returns[ query = {} ]
|
|
|
2079
2038
|
(
|
|
2080
2039
|
mixin=MIXIN '{' { $query.mixin = this.createDict(); }
|
|
2081
2040
|
mixinElementDef[ $query ]*
|
|
2082
|
-
'}' { this.
|
|
2041
|
+
'}' { this.finalizeDictOrArray( $query.mixin ); }
|
|
2083
2042
|
INTO
|
|
2084
2043
|
)?
|
|
2085
2044
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
2086
2045
|
{ $query.quantifier = this.valueWithTokenLocation( $ad.text.toLowerCase(), $ad ); }
|
|
2087
2046
|
)?
|
|
2088
|
-
bracedSelectItemListDef[ $query ]?
|
|
2047
|
+
bracedSelectItemListDef[ $query, 'columns' ]?
|
|
2089
2048
|
excludingClause[ $query ]?
|
|
2090
2049
|
|
|
|
2091
2050
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
@@ -2131,7 +2090,7 @@ tableExpression returns[ table ] // TableOrJoin
|
|
|
2131
2090
|
ON cond=condition { $table.on = $cond.cond; }
|
|
2132
2091
|
|
|
|
2133
2092
|
crj=CROSS jn=JOIN tt=tableTerm
|
|
2134
|
-
{ $table = this.leftAssocBinaryOp( $table, $jn, $crj, $tt.table, 'join' ); }
|
|
2093
|
+
{ if (!$table) { $table = {}; } $table = this.leftAssocBinaryOp( $table, $jn, $crj, $tt.table, 'join' ); }
|
|
2135
2094
|
)*
|
|
2136
2095
|
;
|
|
2137
2096
|
|
|
@@ -2313,9 +2272,11 @@ conditionTerm returns [ cond ]
|
|
|
2313
2272
|
|
|
|
2314
2273
|
{ $cond = { args: [ $expr.expr ] }; }
|
|
2315
2274
|
NOT predicate[ $cond, true ]
|
|
2275
|
+
{ if (!$cond.op) $cond = null; } // predicate failed to parse, avoid subseqential errors
|
|
2316
2276
|
|
|
|
2317
2277
|
{ $cond = { args: [ $expr.expr ] }; }
|
|
2318
2278
|
predicate[ $cond, false ]
|
|
2279
|
+
{ if (!$cond.op) $cond = null; } // predicate failed to parse, avoid subseqential errors
|
|
2319
2280
|
)? // optional: for conditions in parentheses
|
|
2320
2281
|
;
|
|
2321
2282
|
|
|
@@ -2429,7 +2390,9 @@ expressionTerm returns [ expr ] locals [ op, args = [] ]
|
|
|
2429
2390
|
}
|
|
2430
2391
|
)
|
|
2431
2392
|
|
|
|
2432
|
-
qm=
|
|
2393
|
+
qm= '?' // is automatically not mentioned as CC candidate
|
|
2394
|
+
// if we have an HideAlternatives here, we would block it to use it in
|
|
2395
|
+
// parallel to an expression (would produce adaptivePredict() otherwise)
|
|
2433
2396
|
{ $expr = { param: this.valueWithTokenLocation( '?', $qm ), scope: 'param' };
|
|
2434
2397
|
this.csnParseOnly( 'Dynamic parameter "?" is not supported', $qm );
|
|
2435
2398
|
}
|
|
@@ -2457,39 +2420,12 @@ expressionTerm returns [ expr ] locals [ op, args = [] ]
|
|
|
2457
2420
|
;
|
|
2458
2421
|
|
|
2459
2422
|
specialFunction returns [ ret = { } ] locals[ art = {} ]
|
|
2460
|
-
@after{ /* #ATN 1 */ }
|
|
2461
2423
|
:
|
|
2462
|
-
|
|
2463
|
-
{ $ret = this.functionAst( $fun, $open ); }
|
|
2464
|
-
// #ATN: we do not want to reserve these three optional keywords
|
|
2465
|
-
(
|
|
2466
|
-
t=( LEADING | TRAILING | BOTH ) { $ret.args[0].args.push( $t.text ); }
|
|
2467
|
-
( e=expression { $ret.args[0].args.push( $e.expr ); } )?
|
|
2468
|
-
t=FROM e=expression { $ret.args[0].args.push( $t.text, $e.expr ); }
|
|
2469
|
-
|
|
|
2470
|
-
e=expression
|
|
2471
|
-
(
|
|
2472
|
-
{ $ret.args[0].args.push( $e.expr ); }
|
|
2473
|
-
t=FROM e=expression
|
|
2474
|
-
{ $ret.args[0].args.push( $t.text, $e.expr ); }
|
|
2475
|
-
|
|
|
2476
|
-
{ $ret.args[0] = $e.expr; }
|
|
2477
|
-
)
|
|
2478
|
-
)
|
|
2479
|
-
')'
|
|
2480
|
-
|
|
|
2481
|
-
fun=EXTRACT open='('
|
|
2482
|
-
{ $ret = this.functionAst( $fun, $open ); }
|
|
2483
|
-
t=( YEAR | MONTH | DAY | HOUR | MINUTE | SECOND )
|
|
2484
|
-
f=FROM e=expression
|
|
2485
|
-
{ $ret.args[0].args.push( $t.text, $f.text, $e.expr ); }
|
|
2486
|
-
')'
|
|
2487
|
-
|
|
|
2488
|
-
ca=CAST open='('
|
|
2424
|
+
ca=CAST '(' // see createArray() in action
|
|
2489
2425
|
{
|
|
2490
2426
|
$ret = {
|
|
2491
2427
|
op: this.valueWithTokenLocation( 'cast', $ca ),
|
|
2492
|
-
args:
|
|
2428
|
+
args: this.createArray(),
|
|
2493
2429
|
location: this.tokenLocation( $ca )
|
|
2494
2430
|
};
|
|
2495
2431
|
}
|
|
@@ -2497,8 +2433,7 @@ specialFunction returns [ ret = { } ] locals[ art = {} ]
|
|
|
2497
2433
|
{
|
|
2498
2434
|
$ret.args.push( $e.expr );
|
|
2499
2435
|
}
|
|
2500
|
-
')'
|
|
2501
|
-
// TODO: ROUND - see also resolver.js
|
|
2436
|
+
')' { this.finalizeDictOrArray( $ret.args ); }
|
|
2502
2437
|
;
|
|
2503
2438
|
|
|
2504
2439
|
// query path includes aggregation:
|
|
@@ -2524,36 +2459,47 @@ valuePath[ category, location = null ] returns[ qp = { path: [] } ] locals[ _syn
|
|
|
2524
2459
|
;
|
|
2525
2460
|
|
|
2526
2461
|
fromArguments[ pathStep ]
|
|
2462
|
+
@init{ if (!$pathStep) $pathStep = {}; } // grammar robustness, see test/negative/parser/NamedExpression.cds
|
|
2527
2463
|
:
|
|
2528
|
-
|
|
2529
|
-
|
|
2464
|
+
'(' { $pathStep.args = this.createDict(); $pathStep['$'+'syntax'] = ':'; } // necessary?
|
|
2465
|
+
name=ident['paramname'] ':'
|
|
2466
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2530
2467
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2531
|
-
|
|
2468
|
+
name=ident['paramname'] ':'
|
|
2469
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2532
2470
|
)*
|
|
2533
|
-
')'
|
|
2471
|
+
')' { this.finalizeDictOrArray( $pathStep.args ); }
|
|
2534
2472
|
;
|
|
2535
2473
|
|
|
2536
2474
|
pathArguments[ pathStep, considerSpecial ]
|
|
2537
|
-
@
|
|
2475
|
+
@init{
|
|
2476
|
+
if (!$pathStep) $pathStep = {}; // grammar robustness, see test/negative/parser/NamedExpression.cds
|
|
2477
|
+
this.genericFunctionsStack.push( this['$'+'genericKeywords'] );
|
|
2478
|
+
}
|
|
2538
2479
|
:
|
|
2539
2480
|
{ this.excludeExpected([ 'ORDER' ]); }
|
|
2540
|
-
|
|
2541
|
-
{ this.prepareGenericKeywords( $considerSpecial ); }
|
|
2542
|
-
// ATN, LL2: Identifier can start both named arguments and the positional.
|
|
2481
|
+
'(' // dict or array, see below
|
|
2543
2482
|
// Make sure that we do not introduce A:B paths in expressions!
|
|
2483
|
+
// Need to avoid adaptPredict(), otherwise Generic keywords won't work in funcExpression
|
|
2484
|
+
{ this.setLocalTokenForId( { ':': 'HelperToken1', '=>': 'HelperToken2' } ); }
|
|
2544
2485
|
(
|
|
2545
|
-
|
|
2486
|
+
{ $pathStep.args = this.createDict(); $pathStep['$'+'syntax'] = ':'; }
|
|
2487
|
+
id=HelperToken1 ':'
|
|
2488
|
+
namedExpression[ $pathStep, this.identAst( $id, 'paramname', true ) ]
|
|
2546
2489
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2547
|
-
|
|
2490
|
+
name=ident['paramname'] ':'
|
|
2491
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2548
2492
|
)*
|
|
2549
2493
|
|
|
|
2550
|
-
{ $pathStep.args =
|
|
2551
|
-
|
|
2494
|
+
{ $pathStep.args = this.createDict(); } // TODO: XSN func path cleanup
|
|
2495
|
+
id=HelperToken2 '=>'
|
|
2496
|
+
namedExpression[ $pathStep, this.identAst( $id, 'paramname', true ) ]
|
|
2552
2497
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2553
|
-
|
|
2498
|
+
name=ident['paramname'] '=>'
|
|
2499
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2554
2500
|
)*
|
|
2555
2501
|
|
|
|
2556
|
-
{ $pathStep.args =
|
|
2502
|
+
{ $pathStep.args = this.createArray(); }
|
|
2557
2503
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
2558
2504
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2559
2505
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
@@ -2566,47 +2512,82 @@ pathArguments[ pathStep, considerSpecial ]
|
|
|
2566
2512
|
}
|
|
2567
2513
|
)?
|
|
2568
2514
|
|
|
|
2569
|
-
|
|
2570
|
-
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
2571
|
-
|
|
|
2572
|
-
d=DISTINCT { $pathStep.quantifier = this.valueWithTokenLocation( 'distinct', $d ); }
|
|
2573
|
-
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
2574
|
-
( ',' e2=expression { $pathStep.args.push( $e2.expr ); } )*
|
|
2575
|
-
|
|
|
2576
|
-
star='*'
|
|
2577
|
-
{ $pathStep.args = [ { location: this.tokenLocation( $star ), val: '*', literal: 'token' } ]; }
|
|
2578
|
-
|
|
|
2579
|
-
{ $pathStep.args = []; }
|
|
2515
|
+
{ $pathStep.args = this.createArray(); }
|
|
2580
2516
|
)
|
|
2581
|
-
')'
|
|
2517
|
+
')' { this.finalizeDictOrArray( $pathStep.args ); }
|
|
2582
2518
|
;
|
|
2519
|
+
finally { // see @init
|
|
2520
|
+
if (!$pathStep.args) $pathStep.args = [];
|
|
2521
|
+
this['$'+'genericKeywords'] = this.genericFunctionsStack.pop();
|
|
2522
|
+
}
|
|
2583
2523
|
|
|
2584
|
-
namedExpression[ pathStep ]
|
|
2524
|
+
namedExpression[ pathStep, id ]
|
|
2585
2525
|
:
|
|
2586
|
-
|
|
2587
|
-
{ if ($pathStep && $
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
$pathStep['$'+'syntax'] = ':';
|
|
2526
|
+
elem=expression
|
|
2527
|
+
{ if ($pathStep && $id) {
|
|
2528
|
+
this.addDef( ($ctx.elem) ? $elem.expr : { location: $id.location },
|
|
2529
|
+
$pathStep, 'args', 0, $id );
|
|
2591
2530
|
}
|
|
2592
2531
|
}
|
|
2593
2532
|
;
|
|
2594
2533
|
|
|
2595
|
-
|
|
2596
|
-
:
|
|
2597
|
-
name=ident['paramname'] a='=>' elem=expression
|
|
2598
|
-
{ if ($name.id) this.addDef( $pathStep, 'args', 0, $name.id, true,
|
|
2599
|
-
($ctx.elem) ? $elem.expr : { location: $name.id.location } ); }
|
|
2600
|
-
;
|
|
2601
|
-
|
|
2602
|
-
funcExpression[ pathStep, considerSpecial ]
|
|
2534
|
+
funcExpression[ pathStep, considerSpecial ] locals[ args ]
|
|
2603
2535
|
@init { this.prepareGenericKeywords( $considerSpecial ); }
|
|
2604
2536
|
:
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2537
|
+
(
|
|
2538
|
+
expr=expression
|
|
2539
|
+
{ $pathStep.args.push( $expr.expr ); }
|
|
2540
|
+
|
|
|
2541
|
+
GenericExpr // keyword as replacement for expression, like '*'
|
|
2542
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2543
|
+
|
|
|
2544
|
+
GenericIntro // keyword as introduction of expression, like DISTINCT
|
|
2545
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2546
|
+
expr=expression
|
|
2547
|
+
{ $args = this.setLastAsXpr( $pathStep.args );
|
|
2548
|
+
$args.push( $expr.expr ); }
|
|
2549
|
+
|
|
|
2550
|
+
// Rule 'pathArguments' makes a decision based on the first two lookahead
|
|
2551
|
+
// tokens of this rule → we need to list tokens which would be changed to
|
|
2552
|
+
// GenericExpr or GenericIntro, and are not already covered by 'expression'
|
|
2553
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2554
|
+
( HideAlternatives | '*' | ALL | DISTINCT )
|
|
2555
|
+
// now continue parsing like GenericExpr:
|
|
2556
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2557
|
+
)
|
|
2558
|
+
(
|
|
2559
|
+
{ if (!$args) $args = this.setLastAsXpr( $pathStep.args ); }
|
|
2560
|
+
(
|
|
2561
|
+
{ this.prepareGenericKeywords( $considerSpecial, 'separator' ); }
|
|
2562
|
+
(
|
|
2563
|
+
GenericSeparator
|
|
2564
|
+
|
|
|
2565
|
+
// For ANTLR's lookahead calculations, we need to list tokens here
|
|
2566
|
+
// which could be changed to GenericSeparator. Do not invent a
|
|
2567
|
+
// keyword token which is just used here (Identifier does work
|
|
2568
|
+
// perfectly)! If we want, we could add all non-reserved keywords
|
|
2569
|
+
// except ORDER, and most reserved.
|
|
2570
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2571
|
+
( HideAlternatives | Identifier | FROM | IN | WITH | GROUP )
|
|
2572
|
+
)
|
|
2573
|
+
{ $args.push( this.xprToken() );
|
|
2574
|
+
this.prepareGenericKeywords( $considerSpecial, 'expr' );
|
|
2575
|
+
}
|
|
2576
|
+
(
|
|
2577
|
+
expr=expression
|
|
2578
|
+
{ $args.push( $expr.expr ); }
|
|
2579
|
+
|
|
|
2580
|
+
GenericExpr
|
|
2581
|
+
{ $args.push( this.xprToken() ); }
|
|
2582
|
+
|
|
|
2583
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2584
|
+
// Again, we need to list tokens which could make it to GenericExpr
|
|
2585
|
+
// and which do not start an expression
|
|
2586
|
+
( HideAlternatives | ALL )
|
|
2587
|
+
{ $args.push( this.xprToken() ); }
|
|
2588
|
+
)
|
|
2589
|
+
)+
|
|
2590
|
+
)?
|
|
2610
2591
|
;
|
|
2611
2592
|
|
|
2612
2593
|
cardinalityAndFilter[ pathStep ] locals [ _sync = 'nop' ]
|
|
@@ -2648,32 +2629,41 @@ optionalWhereForFilter
|
|
|
2648
2629
|
|
|
2649
2630
|
// Simple paths and values ---------------------------------------------------
|
|
2650
2631
|
|
|
2651
|
-
|
|
2652
|
-
@after { this.attachLocation($val); }
|
|
2632
|
+
annoValue[ assignment ]
|
|
2653
2633
|
:
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2634
|
+
base=annoValueBase[ $assignment ]
|
|
2635
|
+
|
|
|
2636
|
+
// no docComment() here
|
|
2637
|
+
// this alternative is done with token rewrite in rule "annotationAssignment_atn"
|
|
2638
|
+
at='@'? annotationPath[ $assignment, 'ref', $at ]
|
|
2639
|
+
annotationPathVariant[ $assignment ]?
|
|
2640
|
+
;
|
|
2641
|
+
|
|
2642
|
+
annoValueBase[ assignment ] locals [ seenEllipsis = false ]
|
|
2643
|
+
@after { this.attachLocation( $assignment ); }
|
|
2644
|
+
:
|
|
2645
|
+
'{' // no location here, we flatten
|
|
2646
|
+
{ $assignment['$'+'flatten'] = []; this.meltKeywordToIdentifier(); }
|
|
2647
|
+
flattenedValue[ $assignment ]
|
|
2658
2648
|
(
|
|
2659
2649
|
',' {
|
|
2660
2650
|
this.meltKeywordToIdentifier();
|
|
2661
2651
|
if (this.isStraightBefore("}")) break; // allow ',' before ')'
|
|
2662
2652
|
}
|
|
2663
|
-
|
|
2653
|
+
flattenedValue[ $assignment ]
|
|
2664
2654
|
)*
|
|
2665
2655
|
'}'
|
|
2666
2656
|
|
|
|
2667
|
-
|
|
2668
|
-
|
|
2657
|
+
'[' // no need for createArray() here, $assignment.location is set
|
|
2658
|
+
{ $assignment.val = []; $assignment.literal = 'array'; }
|
|
2669
2659
|
(
|
|
2670
2660
|
(
|
|
2671
|
-
head=
|
|
2661
|
+
head=annoSubValue { $assignment.val.push( $head.val ); }
|
|
2672
2662
|
|
|
|
2673
|
-
e='...' ( UP TO upTo=
|
|
2663
|
+
e='...' ( UP TO upTo=annoSubValue )?
|
|
2674
2664
|
{{
|
|
2675
2665
|
const item = { literal: 'token', val: '...', location: this.tokenLocation($e) };
|
|
2676
|
-
$
|
|
2666
|
+
$assignment.val.push( item );
|
|
2677
2667
|
if ($ctx.upTo) item.upTo = $upTo.val;
|
|
2678
2668
|
$seenEllipsis = !$ctx.upTo || 'upTo';
|
|
2679
2669
|
}}
|
|
@@ -2681,17 +2671,16 @@ annoValueBase returns[ val ] locals [ seenEllipsis = false ]
|
|
|
2681
2671
|
(
|
|
2682
2672
|
',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
|
|
2683
2673
|
(
|
|
2684
|
-
tail=
|
|
2674
|
+
tail=annoSubValue { $assignment.val.push( $tail.val ); }
|
|
2685
2675
|
|
|
|
2686
2676
|
{ $ctx.upTo = null; } // is not reset
|
|
2687
|
-
e='...' ( UP TO upTo=
|
|
2677
|
+
e='...' ( UP TO upTo=annoSubValue )?
|
|
2688
2678
|
{{
|
|
2689
2679
|
const item = { literal: 'token', val: '...', location: this.tokenLocation($e) };
|
|
2690
2680
|
if ($ctx.upTo) item.upTo = $upTo.val;
|
|
2691
|
-
$
|
|
2681
|
+
$assignment.val.push( item );
|
|
2692
2682
|
if ($seenEllipsis === true) // TODO: adapt msg to UP TO
|
|
2693
|
-
this.error( 'syntax-unexpected-ellipsis', $e, { code: '...' }
|
|
2694
|
-
'Expected no more than one $(CODE)' );
|
|
2683
|
+
this.error( 'syntax-unexpected-ellipsis', $e, { '#': 'std', code: '...' } );
|
|
2695
2684
|
else
|
|
2696
2685
|
$seenEllipsis = !$ctx.upTo || 'upTo';
|
|
2697
2686
|
}}
|
|
@@ -2706,80 +2695,65 @@ annoValueBase returns[ val ] locals [ seenEllipsis = false ]
|
|
|
2706
2695
|
'Expecting an array item $(NEWCODE) after an item with $(CODE)' );
|
|
2707
2696
|
}
|
|
2708
2697
|
|
|
|
2709
|
-
v1=literalValue { $
|
|
2698
|
+
v1=literalValue { Object.assign( $assignment, $v1.val ); }
|
|
2710
2699
|
|
|
|
2711
2700
|
( plus='+' | min='-' ) num=Number
|
|
2712
|
-
{ $
|
|
2701
|
+
{ Object.assign( $assignment, this.numberLiteral( $num, $plus||$min ) ); }
|
|
2713
2702
|
;
|
|
2714
2703
|
|
|
2715
|
-
|
|
2704
|
+
flattenedValue[ assignment ] locals[ val = { name: {} } ]
|
|
2716
2705
|
:
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
{ $val = {}; } // TODO: think about expression value representation
|
|
2720
|
-
at='@'? annotationPath[ $val, 'ref', $at ]
|
|
2721
|
-
annotationPathVariant[ $val ]?
|
|
2722
|
-
;
|
|
2723
|
-
|
|
2724
|
-
namedValue[ struct ] locals[ namedVal = { name: {} } ]
|
|
2725
|
-
:
|
|
2726
|
-
at='@'? annotationPath[ $namedVal.name, 'name', $at ]
|
|
2727
|
-
(
|
|
2728
|
-
'#' { this.meltKeywordToIdentifier(); }
|
|
2729
|
-
variant=ident['variant'] { $namedVal.name.variant = $variant.id; }
|
|
2730
|
-
)?
|
|
2706
|
+
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2707
|
+
( annotationPathVariant[ $val.name ] )?
|
|
2731
2708
|
(
|
|
2732
2709
|
':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
|
|
2733
|
-
|
|
2710
|
+
annoValue[ $val ]
|
|
2734
2711
|
)?
|
|
2735
|
-
{
|
|
2736
|
-
|
|
2712
|
+
{ $assignment['$'+'flatten'].push( $val ); }
|
|
2713
|
+
;
|
|
2714
|
+
|
|
2715
|
+
namedValue[ struct ] locals[ val = { name: {} } ]
|
|
2716
|
+
:
|
|
2717
|
+
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2718
|
+
( ':' sub=annoSubValue { Object.assign( $val, $sub.val ); } )?
|
|
2719
|
+
{
|
|
2720
|
+
if (!$val.location) $val.location = $val.name.location;
|
|
2721
|
+
this.addDef( $val, $struct, 'struct', null, $val.name ); // TODO: re-check name
|
|
2722
|
+
}
|
|
2737
2723
|
;
|
|
2738
2724
|
|
|
2739
|
-
|
|
2725
|
+
annoSubValue returns[ val = {} ]
|
|
2740
2726
|
@after { this.attachLocation($val); }
|
|
2741
2727
|
:
|
|
2742
|
-
{
|
|
2743
|
-
|
|
2728
|
+
'{' // no need for createDict() here, $val.location is set
|
|
2729
|
+
{ $val.struct = Object.create(null); $val.literal = 'struct'; }
|
|
2744
2730
|
{ this.meltKeywordToIdentifier(); }
|
|
2745
|
-
|
|
2731
|
+
namedValue[ $val ]
|
|
2746
2732
|
( ','
|
|
2747
2733
|
{
|
|
2748
2734
|
this.meltKeywordToIdentifier();
|
|
2749
2735
|
if (this.isStraightBefore("}")) break; // allow ',' before '}'
|
|
2750
2736
|
}
|
|
2751
|
-
|
|
2737
|
+
namedValue[ $val ]
|
|
2752
2738
|
)*
|
|
2753
2739
|
'}'
|
|
2754
2740
|
|
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
( head=
|
|
2741
|
+
'[' // no need for createArray() here, $val.location is set
|
|
2742
|
+
{ $val.val = []; $val.literal = 'array'; }
|
|
2743
|
+
( head=annoSubValue { $val.val.push( $head.val ); }
|
|
2758
2744
|
( ',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
|
|
2759
|
-
tail=
|
|
2745
|
+
tail=annoSubValue { $val.val.push( $tail.val ); }
|
|
2760
2746
|
)*
|
|
2761
2747
|
)?
|
|
2762
2748
|
']'
|
|
2763
2749
|
|
|
|
2764
|
-
v1=literalValue { $val
|
|
2750
|
+
v1=literalValue { Object.assign( $val, $v1.val ); }
|
|
2765
2751
|
|
|
|
2766
2752
|
( plus='+' | min='-' ) num=Number
|
|
2767
|
-
{ $val
|
|
2753
|
+
{ Object.assign( $val, this.numberLiteral( $num, $plus||$min ) ); }
|
|
2768
2754
|
|
|
|
2769
|
-
{ $val = {}; } // TODO: think about expression value representation
|
|
2770
2755
|
at='@'? annotationPath[ $val, 'ref', $at ]
|
|
2771
|
-
(
|
|
2772
|
-
'#' { this.meltKeywordToIdentifier(); }
|
|
2773
|
-
variant=ident['variant'] { $val.variant = $variant.id; }
|
|
2774
|
-
)?
|
|
2775
|
-
;
|
|
2776
|
-
|
|
2777
|
-
namedValueInArray[ struct ] locals[ name = {} ]
|
|
2778
|
-
:
|
|
2779
|
-
at='@'? annotationPath[ $name, 'name', $at ]
|
|
2780
|
-
( ':' elem=arrayValue )?
|
|
2781
|
-
{ this.addDef( $struct, 'struct', null, $name, true,
|
|
2782
|
-
($ctx.elem) ? $elem.val : { location: $name.location } ); }
|
|
2756
|
+
( annotationPathVariant[ $val ] )?
|
|
2783
2757
|
;
|
|
2784
2758
|
|
|
2785
2759
|
literalValue returns[ val ] locals[ tok ]
|
|
@@ -2837,12 +2811,12 @@ annotationPath[ art, category, headat = null ] locals[ _sync = 'nop' ]
|
|
|
2837
2811
|
)*
|
|
2838
2812
|
;
|
|
2839
2813
|
|
|
2840
|
-
annotationPathVariant[ art ]
|
|
2814
|
+
annotationPathVariant[ art ] locals[ variant = {} ]
|
|
2841
2815
|
@after { this.attachLocation($art); }
|
|
2842
2816
|
:
|
|
2843
|
-
// TODO: warning for space
|
|
2817
|
+
// TODO: warning for space after '#'
|
|
2844
2818
|
'#' { this.meltKeywordToIdentifier(); }
|
|
2845
|
-
variant
|
|
2819
|
+
simplePath[ $variant, 'variant' ] { $art.variant = $variant; }
|
|
2846
2820
|
;
|
|
2847
2821
|
|
|
2848
2822
|
// Identifier and non-reserved keywords --------------------------------------
|
|
@@ -2871,13 +2845,11 @@ ident[ category ] returns[ id ]
|
|
|
2871
2845
|
| ASPECT
|
|
2872
2846
|
| ASSOCIATION
|
|
2873
2847
|
| BETWEEN
|
|
2874
|
-
| BOTH
|
|
2875
2848
|
| COLUMNS
|
|
2876
2849
|
| COMPOSITION
|
|
2877
2850
|
| CONTEXT
|
|
2878
2851
|
| CROSS
|
|
2879
2852
|
| CURRENT
|
|
2880
|
-
| DAY
|
|
2881
2853
|
| DEFAULT
|
|
2882
2854
|
| DEFINE
|
|
2883
2855
|
| DEFINITIONS
|
|
@@ -2901,14 +2873,12 @@ ident[ category ] returns[ id ]
|
|
|
2901
2873
|
| FUNCTION
|
|
2902
2874
|
| GROUP
|
|
2903
2875
|
| HAVING
|
|
2904
|
-
| HOUR
|
|
2905
2876
|
| INNER
|
|
2906
2877
|
| INTERSECT
|
|
2907
2878
|
| INTO
|
|
2908
2879
|
| IS
|
|
2909
2880
|
| JOIN
|
|
2910
2881
|
| LAST
|
|
2911
|
-
| LEADING
|
|
2912
2882
|
| LEFT
|
|
2913
2883
|
| LIKE
|
|
2914
2884
|
| LIMIT
|
|
@@ -2916,9 +2886,7 @@ ident[ category ] returns[ id ]
|
|
|
2916
2886
|
| MANY
|
|
2917
2887
|
| MASKED
|
|
2918
2888
|
| MINUS
|
|
2919
|
-
| MINUTE
|
|
2920
2889
|
| MIXIN
|
|
2921
|
-
| MONTH
|
|
2922
2890
|
| NAMESPACE
|
|
2923
2891
|
| NULLS
|
|
2924
2892
|
| OFFSET
|
|
@@ -2935,10 +2903,8 @@ ident[ category ] returns[ id ]
|
|
|
2935
2903
|
| RIGHT
|
|
2936
2904
|
| ROW
|
|
2937
2905
|
| ROWS
|
|
2938
|
-
| SECOND
|
|
2939
2906
|
| SERVICE
|
|
2940
2907
|
| THEN
|
|
2941
|
-
| TRAILING
|
|
2942
2908
|
| UNION
|
|
2943
2909
|
| UP
|
|
2944
2910
|
| TO
|
|
@@ -2947,7 +2913,6 @@ ident[ category ] returns[ id ]
|
|
|
2947
2913
|
| UNBOUNDED
|
|
2948
2914
|
| VARIABLE
|
|
2949
2915
|
| VIEW
|
|
2950
|
-
| YEAR
|
|
2951
2916
|
;
|
|
2952
2917
|
|
|
2953
2918
|
//----------------------------------------------------------------------------
|
|
@@ -3039,7 +3004,6 @@ CASE : [cC][aA][sS][eE] ;
|
|
|
3039
3004
|
CAST : [cC][aA][sS][tT] ;
|
|
3040
3005
|
DISTINCT : [dD][iI][sS][tT][iI][nN][cC][tT] ;
|
|
3041
3006
|
EXISTS : [eE][xX][iI][sS][tT][sS] ;
|
|
3042
|
-
EXTRACT : [eE][xX][tT][rR][aA][cC][tT] ;
|
|
3043
3007
|
// FALSE: see Boolean
|
|
3044
3008
|
FROM : [fF][rR][oO][mM] ;
|
|
3045
3009
|
IN : [iI][nN] ;
|
|
@@ -3052,7 +3016,6 @@ ON : [oO][nN] ;
|
|
|
3052
3016
|
SELECT : [sS][eE][lL][eE][cC][tT] ;
|
|
3053
3017
|
SOME : [sS][oO][mM][eE] ;
|
|
3054
3018
|
WHEN : [wW][hH][eE][nN] ;
|
|
3055
|
-
TRIM : [tT][rR][iI][mM] ;
|
|
3056
3019
|
// TRUE: see Boolean
|
|
3057
3020
|
WHERE : [wW][hH][eE][rR][eE] ;
|
|
3058
3021
|
WITH : [wW][iI][tT][hH] ;
|
|
@@ -3066,6 +3029,7 @@ Number // DO NOT RENAME OR MOVE THIS RULE !!!
|
|
|
3066
3029
|
;
|
|
3067
3030
|
|
|
3068
3031
|
// Unreserved keywords (are case-insensitive): -------------------------------
|
|
3032
|
+
// Do not add keywords just for specialFunctions!
|
|
3069
3033
|
|
|
3070
3034
|
ABSTRACT : [aA][bB][sS][tT][rR][aA][cC][tT] ;
|
|
3071
3035
|
ACTION : [aA][cC][tT][iI][oO][nN] ;
|
|
@@ -3078,13 +3042,11 @@ ASC : [aA][sS][cC] ;
|
|
|
3078
3042
|
ASPECT : [aA][sS][pP][eE][cC][tT] ;
|
|
3079
3043
|
ASSOCIATION : [aA][sS][sS][oO][cC][iI][aA][tT][iI][oO][nN] ;
|
|
3080
3044
|
BETWEEN : [bB][eE][tT][wW][eE][eE][nN] ;
|
|
3081
|
-
BOTH : [bB][oO][tT][hH] ;
|
|
3082
3045
|
COLUMNS : [cC][oO][lL][uU][mM][nN][sS];
|
|
3083
3046
|
COMPOSITION : [cC][oO][mM][pP][oO][sS][iI][tT][iI][oO][nN] ;
|
|
3084
3047
|
CONTEXT : [cC][oO][nN][tT][eE][xX][tT] ;
|
|
3085
3048
|
CROSS : [cC][rR][oO][sS][sS] ;
|
|
3086
3049
|
CURRENT : [cC][uU][rR][rR][eE][nN][tT] ;
|
|
3087
|
-
DAY : [dD][aA][yY] ;
|
|
3088
3050
|
DEFAULT : [dD][eE][fF][aA][uU][lL][tT] ;
|
|
3089
3051
|
DEFINE : [dD][eE][fF][iI][nN][eE] ;
|
|
3090
3052
|
DEFINITIONS : [dD][eE][fF][iI][nN][iI][tT][iI][oO][nN][sS] ;
|
|
@@ -3108,14 +3070,12 @@ FULL : [fF][uU][lL][lL] ;
|
|
|
3108
3070
|
FUNCTION : [fF][uU][nN][cC][tT][iI][oO][nN] ;
|
|
3109
3071
|
GROUP : [gG][rR][oO][uU][pP] ;
|
|
3110
3072
|
HAVING : [hH][aA][vV][iI][nN][gG] ;
|
|
3111
|
-
HOUR : [hH][oO][uU][rR] ;
|
|
3112
3073
|
INNER : [iI][nN][nN][eE][rR] ;
|
|
3113
3074
|
INTERSECT : [iI][nN][tT][eE][rR][sS][eE][cC][tT] ;
|
|
3114
3075
|
INTO : [iI][nN][tT][oO] ;
|
|
3115
3076
|
IS : [iI][sS] ;
|
|
3116
3077
|
JOIN : [jJ][oO][iI][nN] ;
|
|
3117
3078
|
LAST : [lL][aA][sS][tT] ;
|
|
3118
|
-
LEADING : [lL][eE][aA][dD][iI][nN][gG] ;
|
|
3119
3079
|
LEFT : [lL][eE][fF][tT] ;
|
|
3120
3080
|
LIKE : [lL][iI][kK][eE] ;
|
|
3121
3081
|
LIMIT : [lL][iI][mM][iI][tT] ;
|
|
@@ -3123,9 +3083,7 @@ LOCALIZED: [lL][oO][cC][aA][lL][iI][zZ][eE][dD];
|
|
|
3123
3083
|
MANY : [mM][aA][nN][yY] ;
|
|
3124
3084
|
MASKED : [mM][aA][sS][kK][eE][dD] ;
|
|
3125
3085
|
MINUS : [mM][iI][nN][uU][sS] ;
|
|
3126
|
-
MINUTE : [mM][iI][nN][uU][tT][eE] ;
|
|
3127
3086
|
MIXIN : [mM][iI][xX][iI][nN] ;
|
|
3128
|
-
MONTH : [mM][oO][nN][tT][hH] ;
|
|
3129
3087
|
NAMESPACE : [nN][aA][mM][eE][sS][pP][aA][cC][eE] ;
|
|
3130
3088
|
NULLS : [nN][uU][lL][lL][sS] ;
|
|
3131
3089
|
OFFSET : [oO][fF][fF][sS][eE][tT] ;
|
|
@@ -3143,10 +3101,8 @@ RETURNS : [rR][eE][tT][uU][rR][nN][sS] ;
|
|
|
3143
3101
|
RIGHT : [rR][iI][gG][hH][tT] ;
|
|
3144
3102
|
ROW : [rR][oO][wW] ;
|
|
3145
3103
|
ROWS : [rR][oO][wW][sS] ;
|
|
3146
|
-
SECOND : [sS][eE][cC][oO][nN][dD] ;
|
|
3147
3104
|
SERVICE : [sS][eE][rR][vV][iI][cC][eE] ;
|
|
3148
3105
|
THEN : [tT][hH][eE][nN] ;
|
|
3149
|
-
TRAILING : [tT][rR][aA][iI][lL][iI][nN][gG] ;
|
|
3150
3106
|
TO : [tT][oO] ; // or make reserved? (is in SQL-92)
|
|
3151
3107
|
TYPE : [tT][yY][pP][eE] ;
|
|
3152
3108
|
UNION : [uU][nN][iI][oO][nN] ;
|
|
@@ -3156,7 +3112,6 @@ USING : [uU][sS][iI][nN][gG] ;
|
|
|
3156
3112
|
VARIABLE : [vV][aA][rR][iI][aA][bB][lL][eE] ;
|
|
3157
3113
|
VIEW : [vV][iI][eE][wW] ;
|
|
3158
3114
|
// VIRTUAL: [vV][iI][rR][tT][uU][aA][lL] ; see tokens {}
|
|
3159
|
-
YEAR : [yY][eE][aA][rR] ;
|
|
3160
3115
|
|
|
3161
3116
|
// Identifiers, must BE LAST, DIRECTLY AFTER the unreserved keywords ---------
|
|
3162
3117
|
|