@sap/cds-compiler 2.13.8 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +155 -1594
- package/bin/cdsc.js +144 -66
- 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 +237 -122
- package/lib/api/options.js +17 -88
- package/lib/api/validate.js +12 -16
- package/lib/base/keywords.js +216 -109
- package/lib/base/message-registry.js +152 -37
- package/lib/base/messages.js +145 -83
- package/lib/base/model.js +44 -2
- package/lib/base/optionProcessorHelper.js +19 -0
- package/lib/checks/actionsFunctions.js +7 -5
- package/lib/checks/annotationsOData.js +11 -32
- package/lib/checks/arrayOfs.js +1 -34
- 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 +4 -5
- package/lib/compiler/assert-consistency.js +16 -10
- package/lib/compiler/base.js +1 -0
- package/lib/compiler/builtins.js +98 -9
- package/lib/compiler/checks.js +22 -70
- package/lib/compiler/define.js +61 -13
- package/lib/compiler/extend.js +79 -14
- package/lib/compiler/finalize-parse-cdl.js +46 -29
- package/lib/compiler/index.js +100 -37
- package/lib/compiler/moduleLayers.js +7 -0
- package/lib/compiler/populate.js +19 -18
- package/lib/compiler/propagator.js +7 -4
- package/lib/compiler/resolve.js +297 -234
- package/lib/compiler/shared.js +107 -102
- package/lib/compiler/tweak-assocs.js +16 -11
- package/lib/compiler/utils.js +5 -0
- package/lib/edm/annotations/genericTranslation.js +93 -21
- package/lib/edm/csn2edm.js +230 -115
- package/lib/edm/edm.js +305 -226
- package/lib/edm/edmPreprocessor.js +509 -438
- package/lib/edm/edmUtils.js +31 -45
- package/lib/gen/Dictionary.json +98 -22
- package/lib/gen/language.checksum +1 -1
- package/lib/gen/language.interp +10 -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 +20786 -22199
- package/lib/json/csnVersion.js +10 -11
- package/lib/json/from-csn.js +59 -51
- package/lib/json/to-csn.js +10 -10
- package/lib/language/antlrParser.js +2 -2
- package/lib/language/docCommentParser.js +62 -39
- package/lib/language/errorStrategy.js +52 -40
- package/lib/language/genericAntlrParser.js +348 -229
- package/lib/language/language.g4 +629 -653
- package/lib/language/multiLineStringParser.js +14 -42
- package/lib/language/textUtils.js +44 -0
- package/lib/main.d.ts +46 -43
- package/lib/main.js +108 -79
- package/lib/model/csnRefs.js +34 -7
- package/lib/model/csnUtils.js +337 -332
- package/lib/model/enrichCsn.js +1 -0
- package/lib/model/revealInternalProperties.js +30 -10
- package/lib/model/sortViews.js +32 -31
- package/lib/modelCompare/compare.js +6 -6
- package/lib/optionProcessor.js +73 -46
- 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 +1042 -882
- package/lib/render/toHdbcds.js +195 -245
- package/lib/render/toRename.js +44 -22
- package/lib/render/toSql.js +225 -241
- package/lib/render/utils/common.js +145 -15
- package/lib/render/utils/sql.js +20 -19
- package/lib/sql-identifier.js +6 -0
- package/lib/transform/db/.eslintrc.json +4 -3
- package/lib/transform/db/associations.js +2 -2
- package/lib/transform/db/cdsPersistence.js +5 -15
- package/lib/transform/db/constraints.js +4 -2
- package/lib/transform/db/expansion.js +22 -16
- package/lib/transform/db/flattening.js +109 -80
- package/lib/transform/db/transformExists.js +7 -7
- package/lib/transform/db/views.js +9 -6
- 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 +62 -48
- package/lib/transform/forOdataNew.js +49 -50
- package/lib/transform/localized.js +31 -20
- package/lib/transform/odata/toFinalBaseType.js +16 -14
- package/lib/transform/odata/typesExposure.js +146 -198
- package/lib/transform/odata/utils.js +1 -38
- package/lib/transform/transformUtilsNew.js +67 -84
- package/lib/transform/translateAssocsToJoins.js +7 -3
- package/lib/transform/universalCsn/.eslintrc.json +2 -2
- package/lib/transform/universalCsn/coreComputed.js +16 -9
- package/lib/transform/universalCsn/universalCsnEnricher.js +60 -10
- package/lib/utils/file.js +3 -3
- package/lib/utils/moduleResolve.js +13 -6
- package/lib/utils/timetrace.js +20 -21
- package/package.json +35 -4
- package/share/messages/message-explanations.json +2 -1
- package/share/messages/syntax-expected-integer.md +37 -0
- 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/transform/odata/attachPath.js +0 -96
- package/lib/transform/odata/expandStructKeysInAssociations.js +0 -59
- package/lib/transform/odata/generateForeignKeyElements.js +0 -261
- package/lib/transform/odata/referenceFlattener.js +0 -296
- package/lib/transform/odata/sortByAssociationDependency.js +0 -105
- package/lib/transform/odata/structuralPath.js +0 -72
- package/lib/transform/odata/structureFlattener.js +0 -171
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,95 @@ 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' );
|
|
406
401
|
this.meltKeywordToIdentifier();
|
|
407
402
|
}
|
|
408
|
-
annotateArtifact[ $
|
|
403
|
+
annotateArtifact[ $art, $outer ] // not kind-specific
|
|
409
404
|
)
|
|
410
405
|
;
|
|
411
406
|
|
|
412
|
-
contextDef[
|
|
413
|
-
@after { this.attachLocation($art); }
|
|
407
|
+
contextDef[ art, outer, defOnly = false ] locals[ name = {} ]
|
|
408
|
+
@after { this.attachLocation( $art ); }
|
|
414
409
|
:
|
|
415
410
|
( CONTEXT | service=SERVICE ) simplePath[ $name, $service ? 'Service' : 'Context' ]
|
|
416
|
-
{
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
annotationAssignment_fix[ $annos ]*
|
|
411
|
+
{ this.addDef( $art, $outer, 'artifacts', $service ? 'service' : 'context', $name );
|
|
412
|
+
this.docComment( $art ); }
|
|
413
|
+
annotationAssignment_fix[ $art ]*
|
|
420
414
|
(
|
|
421
|
-
'{' { $art.artifacts = this.createDict(); }
|
|
415
|
+
'{' { $art.artifacts = this.createDict(); $art.extensions = []; }
|
|
422
416
|
artifactDef[ $art, defOnly ]*
|
|
423
|
-
'}' { this.
|
|
417
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
424
418
|
optionalSemi
|
|
425
419
|
|
|
|
426
420
|
requiredSemi
|
|
427
421
|
)
|
|
428
422
|
;
|
|
429
423
|
|
|
430
|
-
extendContext[
|
|
431
|
-
@after { this.attachLocation($art); }
|
|
424
|
+
extendContext[ art, outer ] locals[ name = {} ]
|
|
425
|
+
@after { this.attachLocation( $art ); }
|
|
432
426
|
:
|
|
433
|
-
( CONTEXT
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
$loc ); }
|
|
427
|
+
( CONTEXT { $art.expectedKind = 'context'; } | service=SERVICE { $art.expectedKind = 'service'; })
|
|
428
|
+
simplePath[ $name, $service ? 'Service' : 'Context' ] // not 'Extend' here
|
|
429
|
+
{ $art.name = $name; this.addItem( $art, $outer, 'extensions', 'extend' ); }
|
|
437
430
|
( WITH { this.noSemicolonHere(); } )?
|
|
438
|
-
{ this.docComment( $
|
|
439
|
-
annotationAssignment_ll1[ $
|
|
431
|
+
{ this.docComment( $art ); }
|
|
432
|
+
annotationAssignment_ll1[ $art ]*
|
|
440
433
|
(
|
|
441
434
|
'{' { $art.artifacts = this.createDict(); }
|
|
442
435
|
artifactDef[ $art, $service ? 'SERVICE' : 'CONTEXT' ]*
|
|
443
|
-
'}' { this.
|
|
436
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
444
437
|
optionalSemi
|
|
445
438
|
|
|
|
446
439
|
requiredSemi
|
|
447
440
|
)
|
|
448
441
|
;
|
|
449
442
|
|
|
450
|
-
entityDef[
|
|
451
|
-
@after { this.attachLocation($art); }
|
|
443
|
+
entityDef[ art, outer ] locals[ name = {} ]
|
|
444
|
+
@after { this.attachLocation( $art ); }
|
|
452
445
|
:
|
|
453
446
|
ENTITY simplePath[ $name, 'Entity' ]
|
|
454
|
-
{
|
|
455
|
-
this.docComment( $
|
|
456
|
-
annotationAssignment_fix[ $
|
|
457
|
-
|
|
447
|
+
{ this.addDef( $art, $outer, 'artifacts', 'entity', $name );
|
|
448
|
+
this.docComment( $art ); }
|
|
449
|
+
annotationAssignment_fix[ $art ]*
|
|
450
|
+
parameterListDef[ $art ]?
|
|
458
451
|
(
|
|
459
452
|
( ':'
|
|
460
453
|
includeRef[ $art ]
|
|
@@ -462,15 +455,14 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
462
455
|
includeRef[ $art ]
|
|
463
456
|
)*
|
|
464
457
|
)?
|
|
465
|
-
'{'
|
|
466
|
-
{ $art.elements = this.createDict(); } // better for include and annotate
|
|
458
|
+
'{' { $art.elements = this.createDict(); }
|
|
467
459
|
elementDef[ $art ]*
|
|
468
|
-
'}' { this.
|
|
460
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
469
461
|
// TODO: action definitions in a specific section?
|
|
470
462
|
(
|
|
471
463
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
472
464
|
actionFunctionDef[ $art ]*
|
|
473
|
-
'}' { this.
|
|
465
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
474
466
|
)?
|
|
475
467
|
optionalSemi
|
|
476
468
|
|
|
|
@@ -480,7 +472,7 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
480
472
|
(
|
|
481
473
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
482
474
|
actionFunctionDef[ $art ]*
|
|
483
|
-
'}' { this.
|
|
475
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
484
476
|
optionalSemi
|
|
485
477
|
| requiredSemi
|
|
486
478
|
)
|
|
@@ -490,7 +482,7 @@ entityDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
490
482
|
(
|
|
491
483
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
492
484
|
actionFunctionDef[ $art ]*
|
|
493
|
-
'}' { this.
|
|
485
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
494
486
|
)?
|
|
495
487
|
optionalSemi // TODO: not fully correct without columns or excluding
|
|
496
488
|
)
|
|
@@ -514,7 +506,7 @@ projectionSpec returns[ query ] locals[ src ]
|
|
|
514
506
|
( AS aliasName=ident['FromAlias'] { $src.name = $aliasName.id } )?
|
|
515
507
|
// ANTLR errors are better if we use ( A )? instead of ( A | ):
|
|
516
508
|
{ if (!$src.name) this.classifyImplicitName( $src.scope ? 'FromAlias' : 'Without' ); }
|
|
517
|
-
bracedSelectItemListDef[ $query ]?
|
|
509
|
+
bracedSelectItemListDef[ $query, 'columns' ]?
|
|
518
510
|
excludingClause[ $query ]?
|
|
519
511
|
;
|
|
520
512
|
|
|
@@ -541,25 +533,26 @@ excludingClause[ query ]
|
|
|
541
533
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
542
534
|
projectionExclusion[ $query ]
|
|
543
535
|
)*
|
|
544
|
-
'}' { this.
|
|
536
|
+
'}' { this.finalizeDictOrArray( $query.excludingDict ); }
|
|
545
537
|
;
|
|
546
538
|
|
|
547
|
-
projectionExclusion[ outer ] locals[ art ]
|
|
539
|
+
projectionExclusion[ outer ] locals[ art = {} ]
|
|
548
540
|
@after { this.attachLocation($art); }
|
|
549
541
|
:
|
|
550
542
|
name=ident['ref']
|
|
551
|
-
{
|
|
543
|
+
{ this.addDef( $art, $outer, 'excludingDict', '', $name.id ); }
|
|
552
544
|
;
|
|
553
545
|
|
|
554
|
-
extendEntity[
|
|
555
|
-
@after { /* #ATN 1 */ this.attachLocation($art); }
|
|
546
|
+
extendEntity[ art, outer ] locals[ name = {} ]
|
|
547
|
+
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
556
548
|
:
|
|
557
549
|
ENTITY simplePath[ $name, 'Extend' ]
|
|
558
|
-
{ $art =
|
|
559
|
-
|
|
550
|
+
{ $art.expectedKind = 'entity'; $art.name = $name;
|
|
551
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
552
|
+
}
|
|
560
553
|
(
|
|
561
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
562
|
-
annotationAssignment_ll1[ $
|
|
554
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
555
|
+
annotationAssignment_ll1[ $art ]*
|
|
563
556
|
// ATN: the ref can start with ACTIONS
|
|
564
557
|
(
|
|
565
558
|
includeRef[ $art ]
|
|
@@ -568,8 +561,8 @@ extendEntity[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
568
561
|
extendForEntity[ $art ]
|
|
569
562
|
)
|
|
570
563
|
|
|
|
571
|
-
{ this.docComment( $
|
|
572
|
-
annotationAssignment_ll1[ $
|
|
564
|
+
{ this.docComment( $art ); }
|
|
565
|
+
annotationAssignment_ll1[ $art ]*
|
|
573
566
|
extendForEntity[ $art ]
|
|
574
567
|
)
|
|
575
568
|
;
|
|
@@ -578,33 +571,32 @@ extendForEntity[ art ]
|
|
|
578
571
|
:
|
|
579
572
|
'{' { $art.elements = this.createDict(); }
|
|
580
573
|
elementDefOrExtend[ $art ]*
|
|
581
|
-
'}' { this.
|
|
574
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
582
575
|
(
|
|
583
576
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
584
577
|
actionFunctionDef[ $art ]*
|
|
585
|
-
'}' { this.
|
|
578
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
586
579
|
)?
|
|
587
580
|
optionalSemi
|
|
588
581
|
|
|
|
589
582
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
590
583
|
actionFunctionDef[ $art ]*
|
|
591
|
-
'}' { this.
|
|
584
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
592
585
|
optionalSemi
|
|
593
586
|
|
|
|
594
587
|
requiredSemi
|
|
595
588
|
;
|
|
596
589
|
|
|
597
|
-
extendProjection[
|
|
598
|
-
@after { this.attachLocation($art); }
|
|
590
|
+
extendProjection[ art, outer ] locals[ name = {} ]
|
|
591
|
+
@after { this.attachLocation( $art ); }
|
|
599
592
|
:
|
|
600
593
|
expected=PROJECTION simplePath[ $name, 'Extend' ]
|
|
601
|
-
{
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
$loc ); }
|
|
594
|
+
{ $art.expectedKind = 'entity'; $art.name = $name;
|
|
595
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
596
|
+
}
|
|
605
597
|
( WITH { this.noSemicolonHere(); } )?
|
|
606
|
-
{ this.docComment( $
|
|
607
|
-
annotationAssignment_ll1[ $
|
|
598
|
+
{ this.docComment( $art ); }
|
|
599
|
+
annotationAssignment_ll1[ $art ]*
|
|
608
600
|
(
|
|
609
601
|
'{' { $art.columns = []; }
|
|
610
602
|
(
|
|
@@ -617,13 +609,13 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
617
609
|
(
|
|
618
610
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
619
611
|
actionFunctionDef[ $art ]*
|
|
620
|
-
'}' { this.
|
|
612
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
621
613
|
)?
|
|
622
614
|
optionalSemi
|
|
623
615
|
|
|
|
624
616
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
625
617
|
actionFunctionDef[ $art ]*
|
|
626
|
-
'}' { this.
|
|
618
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
627
619
|
optionalSemi
|
|
628
620
|
|
|
|
629
621
|
requiredSemi
|
|
@@ -631,53 +623,53 @@ extendProjection[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
631
623
|
;
|
|
632
624
|
|
|
633
625
|
// TODO: no action extension?
|
|
634
|
-
actionFunctionDef[ outer ] locals[ art
|
|
635
|
-
@after { this.attachLocation($art); }
|
|
626
|
+
actionFunctionDef[ outer ] locals[ art = {} ]
|
|
627
|
+
@after { this.attachLocation( $art ); }
|
|
636
628
|
:
|
|
637
|
-
{ this.docComment( $
|
|
638
|
-
annotationAssignment_ll1[ $
|
|
629
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
630
|
+
annotationAssignment_ll1[ $art ]*
|
|
639
631
|
(
|
|
640
632
|
ACTION name=ident['BoundAction']
|
|
641
|
-
{
|
|
642
|
-
this.docComment( $
|
|
643
|
-
annotationAssignment_fix[ $
|
|
633
|
+
{ this.addDef( $art, $outer, 'actions', 'action', $name.id );
|
|
634
|
+
this.docComment( $art ); }
|
|
635
|
+
annotationAssignment_fix[ $art ]*
|
|
644
636
|
parameterListDef[ $art ]
|
|
645
|
-
( returnTypeSpec[ $art
|
|
637
|
+
( returnTypeSpec[ $art ] | requiredSemi )
|
|
646
638
|
|
|
|
647
639
|
FUNCTION name=ident['BoundAction']
|
|
648
|
-
{
|
|
649
|
-
this.docComment( $
|
|
650
|
-
annotationAssignment_fix[ $
|
|
640
|
+
{ this.addDef( $art, $outer, 'actions', 'function', $name.id );
|
|
641
|
+
this.docComment( $art ); }
|
|
642
|
+
annotationAssignment_fix[ $art ]*
|
|
651
643
|
parameterListDef[ $art ]
|
|
652
|
-
returnTypeSpec[ $art
|
|
644
|
+
returnTypeSpec[ $art ]
|
|
653
645
|
)
|
|
654
646
|
;
|
|
655
647
|
|
|
656
|
-
actionFunctionMainDef[
|
|
657
|
-
@after { this.attachLocation($art); }
|
|
648
|
+
actionFunctionMainDef[ art, outer ] locals[ name = {} ]
|
|
649
|
+
@after { this.attachLocation( $art ); }
|
|
658
650
|
:
|
|
659
651
|
ACTION simplePath[ $name, 'Action' ]
|
|
660
|
-
{
|
|
661
|
-
this.docComment( $
|
|
662
|
-
annotationAssignment_fix[ $
|
|
652
|
+
{ this.addDef( $art, $outer, 'artifacts', 'action', $name );
|
|
653
|
+
this.docComment( $art ); }
|
|
654
|
+
annotationAssignment_fix[ $art ]*
|
|
663
655
|
parameterListDef[ $art ]
|
|
664
|
-
( returnTypeSpec[ $art
|
|
656
|
+
( returnTypeSpec[ $art ] | requiredSemi )
|
|
665
657
|
|
|
|
666
658
|
FUNCTION simplePath[ $name, 'Action' ]
|
|
667
|
-
{
|
|
668
|
-
this.docComment( $
|
|
669
|
-
annotationAssignment_fix[ $
|
|
659
|
+
{ this.addDef( $art, $outer, 'artifacts', 'function', $name );
|
|
660
|
+
this.docComment( $art ); }
|
|
661
|
+
annotationAssignment_fix[ $art ]*
|
|
670
662
|
parameterListDef[ $art ]
|
|
671
|
-
returnTypeSpec[ $art
|
|
663
|
+
returnTypeSpec[ $art ]
|
|
672
664
|
;
|
|
673
665
|
|
|
674
|
-
eventDef[
|
|
675
|
-
@after { /* #ATN 1 */ this.attachLocation($art); }
|
|
666
|
+
eventDef[ art, outer ] locals[ name = {} ]
|
|
667
|
+
@after { /* #ATN 1 */ this.attachLocation( $art ); }
|
|
676
668
|
:
|
|
677
669
|
EVENT simplePath[ $name, 'Event' ]
|
|
678
|
-
{
|
|
679
|
-
this.docComment( $
|
|
680
|
-
annotationAssignment_fix[ $
|
|
670
|
+
{ this.addDef( $art, $outer, 'artifacts', 'event', $name );
|
|
671
|
+
this.docComment( $art ); }
|
|
672
|
+
annotationAssignment_fix[ $art ]*
|
|
681
673
|
(
|
|
682
674
|
typeStruct[ $art ] optionalSemi
|
|
683
675
|
|
|
|
@@ -693,8 +685,8 @@ eventDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
693
685
|
)*
|
|
694
686
|
typeStruct[ $art ] optionalSemi
|
|
695
687
|
|
|
|
696
|
-
{ this.docComment( $
|
|
697
|
-
annotationAssignment_ll1[ $
|
|
688
|
+
{ this.docComment( $art ); }
|
|
689
|
+
annotationAssignment_ll1[ $art ]*
|
|
698
690
|
requiredSemi
|
|
699
691
|
)
|
|
700
692
|
|
|
|
@@ -708,18 +700,18 @@ eventDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
708
700
|
)
|
|
709
701
|
;
|
|
710
702
|
|
|
711
|
-
aspectDef[
|
|
712
|
-
@after { this.attachLocation($art); }
|
|
703
|
+
aspectDef[ art, outer ] locals[ name = {} ]
|
|
704
|
+
@after { this.attachLocation( $art ); }
|
|
713
705
|
:
|
|
714
706
|
( ASPECT | ( abs=ABSTRACT | HideAlternatives ) ent=ENTITY )
|
|
715
707
|
simplePath[ $name, 'Type' ]
|
|
716
|
-
{
|
|
708
|
+
{ this.addDef( $art, $outer, 'artifacts', 'aspect', $name );
|
|
717
709
|
// backends do not like ['$'+'syntax']: ($ent ? 'entity' : 'aspect')
|
|
718
710
|
if ($ent)
|
|
719
711
|
this.warning( 'syntax-deprecated-abstract', this.tokenLocation( $abs, $ent ), {},
|
|
720
712
|
'Abstract entity definitions are deprecated; use aspect definitions instead' );
|
|
721
|
-
this.docComment( $
|
|
722
|
-
annotationAssignment_fix[ $
|
|
713
|
+
this.docComment( $art ); }
|
|
714
|
+
annotationAssignment_fix[ $art ]*
|
|
723
715
|
( ':'
|
|
724
716
|
(
|
|
725
717
|
includeRef[ $art ]
|
|
@@ -730,99 +722,93 @@ aspectDef[ outer, loc, annos ] locals[ art, name = {} ]
|
|
|
730
722
|
)?
|
|
731
723
|
'{' { $art.elements = this.createDict(); }
|
|
732
724
|
( elementDef[ $art ]* )
|
|
733
|
-
'}' { this.
|
|
725
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
734
726
|
// TODO: action definitions in a specific section?
|
|
735
727
|
(
|
|
736
728
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
737
729
|
actionFunctionDef[ $art ]*
|
|
738
|
-
'}' { this.
|
|
730
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
739
731
|
)?
|
|
740
732
|
optionalSemi
|
|
741
733
|
;
|
|
742
734
|
|
|
743
|
-
typeDef[
|
|
744
|
-
@after { this.attachLocation($art); }
|
|
735
|
+
typeDef[ art, outer ] locals[ name = {} ]
|
|
736
|
+
@after { this.attachLocation( $art ); }
|
|
745
737
|
:
|
|
746
738
|
TYPE simplePath[ $name, 'Type' ]
|
|
747
|
-
{
|
|
748
|
-
this.docComment( $
|
|
749
|
-
annotationAssignment_fix[ $
|
|
750
|
-
typeSpecSemi[ $art
|
|
739
|
+
{ this.addDef( $art, $outer, 'artifacts', 'type', $name );
|
|
740
|
+
this.docComment( $art ); }
|
|
741
|
+
annotationAssignment_fix[ $art ]*
|
|
742
|
+
typeSpecSemi[ $art ]
|
|
751
743
|
;
|
|
752
744
|
|
|
753
|
-
extendType[
|
|
754
|
-
@after { this.attachLocation($art); }
|
|
745
|
+
extendType[ art, outer ] locals[ name = {} ]
|
|
746
|
+
@after { this.attachLocation( $art ); }
|
|
755
747
|
:
|
|
756
748
|
// aspects are types, i.e. kind is 'type' for aspects
|
|
757
749
|
TYPE simplePath[ $name, 'Extend' ]
|
|
758
|
-
{ $art =
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
extendWithOptElements[ $art, $
|
|
750
|
+
{ $art.expectedKind = 'type'; $art.name = $name;
|
|
751
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
752
|
+
}
|
|
753
|
+
extendWithOptElements[ $art, $art ]
|
|
762
754
|
;
|
|
763
755
|
|
|
764
|
-
extendAspect[
|
|
765
|
-
@after { this.attachLocation($art); }
|
|
756
|
+
extendAspect[ art, outer ] locals[ name = {} ]
|
|
757
|
+
@after { this.attachLocation( $art ); }
|
|
766
758
|
:
|
|
767
759
|
// aspects are types, i.e. kind is 'type' for aspects
|
|
768
760
|
ASPECT simplePath[ $name, 'Extend' ]
|
|
769
|
-
{ $art =
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
extendWithOptElements[ $art, $
|
|
761
|
+
{ $art.expectedKind = 'aspect'; $art.name = $name;
|
|
762
|
+
this.addItem( $art, $outer, 'extensions', 'extend' );
|
|
763
|
+
}
|
|
764
|
+
extendWithOptElements[ $art, $art ]
|
|
773
765
|
;
|
|
774
766
|
|
|
775
|
-
annotationDef[
|
|
776
|
-
@after { this.attachLocation($art); }
|
|
767
|
+
annotationDef[ art, outer ] locals[ name = {} ]
|
|
768
|
+
@after { this.attachLocation( $art ); }
|
|
777
769
|
:
|
|
778
770
|
annotation=ANNOTATION simplePath[ $name, 'AnnoDef' ]
|
|
779
771
|
{ 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' );
|
|
772
|
+
this.error( 'syntax-unexpected-vocabulary', $annotation, { '#': $outer.kind } );
|
|
782
773
|
$art = {}; }
|
|
783
|
-
else
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
774
|
+
else {
|
|
775
|
+
if (!$outer.vocabularies) $outer.vocabularies = Object.create(null);
|
|
776
|
+
this.addDef( $art, $outer, 'vocabularies', 'annotation', $name );
|
|
777
|
+
}
|
|
778
|
+
this.docComment( $art ); }
|
|
779
|
+
annotationAssignment_fix[ $art ]*
|
|
780
|
+
typeSpecSemi[ $art ] // also 'includes'...
|
|
788
781
|
;
|
|
789
782
|
|
|
790
|
-
extendArtifact[
|
|
791
|
-
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
783
|
+
extendArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
784
|
+
@after{ /* #ATN 1 */ this.attachLocation( $art ); }
|
|
792
785
|
:
|
|
793
786
|
simplePath[ $name, 'Extend' ]
|
|
787
|
+
( ':' simplePath[ $elemName, 'Element'] )?
|
|
788
|
+
{ this.addExtension( $art, $outer, 'extend', $name, $elemName.path ); }
|
|
794
789
|
(
|
|
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 ]*
|
|
790
|
+
{ this.docComment( $art ); }
|
|
791
|
+
annotationAssignment_ll1[ $art ]*
|
|
807
792
|
(
|
|
808
793
|
'{' { $art.elements = this.createDict(); }
|
|
809
794
|
elementDefOrExtend[ $art ]*
|
|
810
|
-
'}' { this.
|
|
795
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
811
796
|
optionalSemi
|
|
812
797
|
|
|
|
813
798
|
requiredSemi
|
|
814
799
|
)
|
|
815
800
|
|
|
|
816
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
817
|
-
annotationAssignment_ll1[ $
|
|
801
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
802
|
+
annotationAssignment_ll1[ $art ]*
|
|
818
803
|
// #ATN: DEFINITIONS, COLUMNS, ACTIONS etc are not reserved and could be identifiers (ref).
|
|
804
|
+
// TODO: exclude "expected" according to disallowElementExtension()
|
|
819
805
|
(
|
|
820
806
|
includeRef[ $art ]
|
|
821
807
|
requiredSemi
|
|
822
808
|
|
|
|
823
809
|
'{' { $art.elements = this.createDict(); }
|
|
824
810
|
elementDefOrExtend[ $art ]*
|
|
825
|
-
'}' { this.
|
|
811
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
826
812
|
optionalSemi
|
|
827
813
|
|
|
|
828
814
|
requiredSemi
|
|
@@ -831,7 +817,7 @@ extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
831
817
|
DEFINITIONS
|
|
832
818
|
'{' { $art.artifacts = this.createDict(); }
|
|
833
819
|
artifactDef[ $art, true ]*
|
|
834
|
-
'}' { this.
|
|
820
|
+
'}' { this.finalizeDictOrArray( $art.artifacts ); }
|
|
835
821
|
optionalSemi
|
|
836
822
|
|
|
|
837
823
|
{ this.disallowElementExtension( $elemName, $outer, 'columns' ); }
|
|
@@ -849,84 +835,75 @@ extendArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
849
835
|
{ this.disallowElementExtension( $elemName, $outer, 'actions' ); }
|
|
850
836
|
ACTIONS '{' { $art.actions = this.createDict(); }
|
|
851
837
|
actionFunctionDef[ $art ]*
|
|
852
|
-
'}' { this.
|
|
838
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
853
839
|
optionalSemi
|
|
854
840
|
|
|
|
855
841
|
ELEMENTS '{' { $art.elements = this.createDict(); }
|
|
856
842
|
elementDefOrExtend[ $art ]*
|
|
857
|
-
'}' { this.
|
|
843
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
858
844
|
optionalSemi
|
|
859
845
|
|
|
|
860
846
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
861
847
|
enumSymbolDef[ $art ]*
|
|
862
|
-
'}' { this.
|
|
848
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
863
849
|
optionalSemi
|
|
864
850
|
)
|
|
865
851
|
)
|
|
866
852
|
;
|
|
867
853
|
|
|
868
|
-
extendWithOptElements[ art
|
|
854
|
+
extendWithOptElements[ art ]
|
|
869
855
|
:
|
|
870
|
-
WITH { this.noSemicolonHere(); this.docComment( $
|
|
871
|
-
annotationAssignment_ll1[ $
|
|
856
|
+
WITH { this.noSemicolonHere(); this.docComment( $art ); }
|
|
857
|
+
annotationAssignment_ll1[ $art ]*
|
|
872
858
|
(
|
|
873
859
|
includeRef[ $art ]
|
|
874
860
|
requiredSemi
|
|
875
861
|
|
|
|
876
862
|
'{' { $art.elements = this.createDict(); }
|
|
877
863
|
elementDefOrExtend[ $art ]*
|
|
878
|
-
'}' { this.
|
|
864
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
879
865
|
optionalSemi
|
|
880
866
|
|
|
|
881
867
|
requiredSemi
|
|
882
868
|
)
|
|
883
869
|
|
|
|
884
|
-
{ this.docComment( $
|
|
885
|
-
annotationAssignment_ll1[ $
|
|
870
|
+
{ this.docComment( $art ); }
|
|
871
|
+
annotationAssignment_ll1[ $art ]*
|
|
886
872
|
(
|
|
887
873
|
'{' { $art.elements = this.createDict(); }
|
|
888
874
|
elementDefOrExtend[ $art ]*
|
|
889
|
-
'}' { this.
|
|
875
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
890
876
|
optionalSemi
|
|
891
877
|
|
|
|
892
878
|
requiredSemi
|
|
893
879
|
)
|
|
894
880
|
;
|
|
895
881
|
|
|
896
|
-
annotateArtifact[
|
|
897
|
-
@after { this.attachLocation($art); }
|
|
882
|
+
annotateArtifact[ art, outer ] locals[ name = {}, elemName = {} ]
|
|
883
|
+
@after { this.attachLocation( $art ); }
|
|
898
884
|
:
|
|
899
885
|
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
|
-
|
|
886
|
+
( ':' simplePath[ $elemName, 'Element'] )?
|
|
887
|
+
{ this.addExtension( $art, $outer, 'annotate', $name, $elemName.path ); }
|
|
911
888
|
( WITH { this.noSemicolonHere(); } )?
|
|
912
|
-
{ this.docComment( $
|
|
913
|
-
annotationAssignment_ll1[ $
|
|
889
|
+
{ this.docComment( $art ); }
|
|
890
|
+
annotationAssignment_ll1[ $art ]*
|
|
914
891
|
(
|
|
915
892
|
'{' { $art.elements = this.createDict(); }
|
|
916
893
|
annotateElement[ $art ]*
|
|
917
|
-
'}' { this.
|
|
894
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
918
895
|
(
|
|
919
896
|
ACTIONS
|
|
920
897
|
'{' { $art.actions = this.createDict(); }
|
|
921
898
|
annotateAction[ $art ]*
|
|
922
|
-
'}' { this.
|
|
899
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
923
900
|
)?
|
|
924
901
|
optionalSemi
|
|
925
902
|
|
|
|
926
903
|
ACTIONS
|
|
927
904
|
'{' { $art.actions = this.createDict(); }
|
|
928
905
|
annotateAction[ $art ]*
|
|
929
|
-
'}' { this.
|
|
906
|
+
'}' { this.finalizeDictOrArray( $art.actions ); }
|
|
930
907
|
optionalSemi
|
|
931
908
|
|
|
|
932
909
|
'(' { $art.params = this.createDict(); }
|
|
@@ -934,12 +911,12 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
934
911
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
935
912
|
annotateParam[ $art ]
|
|
936
913
|
)*
|
|
937
|
-
')' { this.
|
|
914
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
938
915
|
(
|
|
939
916
|
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
940
917
|
'{' { $art.elements = this.createDict(); }
|
|
941
918
|
annotateElement[ $art ]*
|
|
942
|
-
'}' { this.
|
|
919
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
943
920
|
optionalSemi
|
|
944
921
|
|
|
|
945
922
|
requiredSemi
|
|
@@ -948,7 +925,7 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
948
925
|
RETURNS { $art['$'+'syntax'] = 'returns'; }
|
|
949
926
|
'{' { $art.elements = this.createDict(); }
|
|
950
927
|
annotateElement[ $art ]*
|
|
951
|
-
'}' { this.
|
|
928
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
952
929
|
optionalSemi
|
|
953
930
|
|
|
954
931
|
|
|
|
@@ -956,74 +933,74 @@ annotateArtifact[ outer, loc, annos ] locals[ art, name = {}, elemName = {} ]
|
|
|
956
933
|
)
|
|
957
934
|
;
|
|
958
935
|
|
|
959
|
-
annotateElement[ outer ] locals[ art
|
|
960
|
-
@after{ this.attachLocation($art); }
|
|
936
|
+
annotateElement[ outer ] locals[ art = {} ]
|
|
937
|
+
@after{ this.attachLocation( $art ); }
|
|
961
938
|
:
|
|
962
|
-
{ this.docComment( $
|
|
963
|
-
annotationAssignment_ll1[ $
|
|
939
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
940
|
+
annotationAssignment_ll1[ $art ]*
|
|
964
941
|
name=ident['Element']
|
|
965
|
-
{
|
|
966
|
-
this.docComment( $
|
|
967
|
-
annotationAssignment_ll1[ $
|
|
942
|
+
{ this.addDef( $art, $outer, 'elements', 'annotate', $name.id );
|
|
943
|
+
this.docComment( $art ); }
|
|
944
|
+
annotationAssignment_ll1[ $art ]*
|
|
968
945
|
(
|
|
969
946
|
'{' { $art.elements = this.createDict(); }
|
|
970
947
|
annotateElement[ $art ]*
|
|
971
|
-
'}' { this.
|
|
948
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
972
949
|
optionalSemi
|
|
973
950
|
|
|
|
974
951
|
requiredSemi
|
|
975
952
|
)
|
|
976
953
|
;
|
|
977
954
|
|
|
978
|
-
annotateAction [ outer ] locals [ art
|
|
979
|
-
@after{ this.attachLocation($art); }
|
|
955
|
+
annotateAction [ outer ] locals [ art = {} ]
|
|
956
|
+
@after{ this.attachLocation( $art ); }
|
|
980
957
|
:
|
|
981
|
-
{ this.docComment( $
|
|
982
|
-
annotationAssignment_ll1[ $
|
|
958
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
959
|
+
annotationAssignment_ll1[ $art ]*
|
|
983
960
|
name=ident['BoundAction']
|
|
984
|
-
{
|
|
985
|
-
this.docComment( $
|
|
986
|
-
annotationAssignment_ll1[ $
|
|
961
|
+
{ this.addDef( $art, $outer, 'actions', 'annotate', $name.id );
|
|
962
|
+
this.docComment( $art ); }
|
|
963
|
+
annotationAssignment_ll1[ $art ]*
|
|
987
964
|
(
|
|
988
965
|
'(' { $art.params = this.createDict(); }
|
|
989
966
|
annotateParam[ $art ]
|
|
990
967
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
991
968
|
annotateParam[ $art ]
|
|
992
969
|
)*
|
|
993
|
-
')' { this.
|
|
970
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
994
971
|
)?
|
|
995
972
|
(
|
|
996
973
|
RETURNS '{' { $art.elements = this.createDict(); }
|
|
997
974
|
annotateElement[ $art ]*
|
|
998
|
-
'}' { this.
|
|
975
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
999
976
|
optionalSemi
|
|
1000
977
|
|
|
|
1001
978
|
requiredSemi
|
|
1002
979
|
)
|
|
1003
980
|
;
|
|
1004
981
|
|
|
1005
|
-
annotateParam [ outer ] locals [ art
|
|
1006
|
-
@after{ this.attachLocation($art); }
|
|
982
|
+
annotateParam [ outer ] locals [ art = {} ]
|
|
983
|
+
@after{ this.attachLocation( $art ); }
|
|
1007
984
|
:
|
|
1008
|
-
{ this.docComment( $
|
|
1009
|
-
annotationAssignment_ll1[ $
|
|
985
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
986
|
+
annotationAssignment_ll1[ $art ]*
|
|
1010
987
|
param=ident['Param']
|
|
1011
|
-
{
|
|
1012
|
-
this.docComment( $
|
|
1013
|
-
annotationAssignment_ll1[ $
|
|
988
|
+
{ this.addDef( $art, $outer, 'params', 'annotate', $param.id );
|
|
989
|
+
this.docComment( $art ); }
|
|
990
|
+
annotationAssignment_ll1[ $art ]*
|
|
1014
991
|
;
|
|
1015
992
|
|
|
1016
993
|
// Element definition and its helpers ----------------------------------------
|
|
1017
994
|
|
|
1018
|
-
enumSymbolDef[ outer ] locals[ art
|
|
1019
|
-
@after { this.attachLocation($art); }
|
|
995
|
+
enumSymbolDef[ outer ] locals[ art = {} ]
|
|
996
|
+
@after { this.attachLocation( $art ); }
|
|
1020
997
|
:
|
|
1021
|
-
{ this.docComment( $
|
|
1022
|
-
annotationAssignment_ll1[ $
|
|
998
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
999
|
+
annotationAssignment_ll1[ $art ]*
|
|
1023
1000
|
name=ident['Enum']
|
|
1024
|
-
{
|
|
1025
|
-
this.docComment( $
|
|
1026
|
-
annotationAssignment_ll1[ $
|
|
1001
|
+
{ this.addDef( $art, $outer, 'enum', 'enum', $name.id );
|
|
1002
|
+
this.docComment( $art ); }
|
|
1003
|
+
annotationAssignment_ll1[ $art ]*
|
|
1027
1004
|
( '='
|
|
1028
1005
|
{ this.excludeExpected( ['Boolean', 'QuotedLiteral', "'#'", 'NULL'] ); }
|
|
1029
1006
|
(
|
|
@@ -1033,8 +1010,8 @@ enumSymbolDef[ outer ] locals[ art, annos = [] ]
|
|
|
1033
1010
|
( plus='+' | min='-' ) num=Number
|
|
1034
1011
|
{ $art.value = this.numberLiteral( $num, $plus||$min ); }
|
|
1035
1012
|
)
|
|
1036
|
-
{ this.docComment( $
|
|
1037
|
-
annotationAssignment_ll1[ $
|
|
1013
|
+
{ this.docComment( $art ); }
|
|
1014
|
+
annotationAssignment_ll1[ $art ]*
|
|
1038
1015
|
)?
|
|
1039
1016
|
requiredSemi
|
|
1040
1017
|
;
|
|
@@ -1045,37 +1022,35 @@ defaultValue[ art ] locals[ elem, elements = {} ]
|
|
|
1045
1022
|
DEFAULT expr=expression { $art.default = $expr.expr; }
|
|
1046
1023
|
;
|
|
1047
1024
|
|
|
1048
|
-
elementDefOrExtend[ outer ] locals[
|
|
1049
|
-
@after { /* #ATN 1 */ if ($
|
|
1050
|
-
// tool complains if I test for ($art)
|
|
1025
|
+
elementDefOrExtend[ outer ] locals[ art = {} ]
|
|
1026
|
+
@after { /* #ATN 1 */ } // if ($art) this.attachLocation( $art ); }
|
|
1051
1027
|
:
|
|
1052
|
-
{ this.docComment( $
|
|
1053
|
-
annotationAssignment_ll1[ $
|
|
1028
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1029
|
+
annotationAssignment_ll1[ $art ]*
|
|
1054
1030
|
// #ATN: element name for definition can be EXTEND
|
|
1055
1031
|
(
|
|
1056
1032
|
EXTEND
|
|
1057
|
-
extendElement[ $
|
|
1033
|
+
extendElement[ $art, $outer ]
|
|
1058
1034
|
|
|
|
1059
|
-
|
|
1035
|
+
elementDefInner[ $art, $outer, true ]
|
|
1060
1036
|
)
|
|
1061
1037
|
;
|
|
1062
1038
|
|
|
1063
|
-
elementDef[ outer ] locals[
|
|
1064
|
-
@after { this.attachLocation($art.art); }
|
|
1039
|
+
elementDef[ outer ] locals[ $art = {} ]
|
|
1065
1040
|
:
|
|
1066
|
-
{ this.docComment( $
|
|
1067
|
-
annotationAssignment_ll1[ $
|
|
1068
|
-
|
|
1041
|
+
{ $art.location = this.startLocation();; this.docComment( $art ); }
|
|
1042
|
+
annotationAssignment_ll1[ $art ]*
|
|
1043
|
+
elementDefInner[ $art, $outer, false ]
|
|
1069
1044
|
;
|
|
1070
1045
|
|
|
1071
1046
|
// Actually, this is a subset if elementDefInner...
|
|
1072
1047
|
// TODO: the corresponding restrictions must also be checked in the core
|
|
1073
1048
|
// compiler, as the mixin element could come via CSN
|
|
1074
|
-
mixinElementDef[ outer ] locals[ art ]
|
|
1049
|
+
mixinElementDef[ outer ] locals[ art = {} ]
|
|
1075
1050
|
@after { /* #ATN 2 */ this.attachLocation($art); }
|
|
1076
1051
|
:
|
|
1077
1052
|
name=ident['Mixin']
|
|
1078
|
-
{
|
|
1053
|
+
{ this.addDef( $art, $outer, 'mixin', 'mixin', $name.id ); }
|
|
1079
1054
|
(
|
|
1080
1055
|
':'
|
|
1081
1056
|
// #ATN: referenced type name can be ASSOCIATION or COMPOSITION
|
|
@@ -1097,33 +1072,30 @@ mixinElementDef[ outer ] locals[ art ]
|
|
|
1097
1072
|
requiredSemi
|
|
1098
1073
|
;
|
|
1099
1074
|
|
|
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 */ }
|
|
1075
|
+
elementDefInner[ art, outer, allowEq ]
|
|
1076
|
+
@after{ /* #ATN 5 */ this.attachLocation( $art ); }
|
|
1111
1077
|
:
|
|
1112
1078
|
// TODO: it would be excellent to remove ELEMENT...
|
|
1113
1079
|
// or have a special ident rule without the ELEMENT
|
|
1114
1080
|
// Reason: it would be good for error recovery to start a major block without LL1 ambiguity
|
|
1115
1081
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1116
1082
|
{ this.setLocalToken( 'VIRTUAL', 'VIRTUAL', /^[:{@=}]$/ ); }
|
|
1117
|
-
virtual=VIRTUAL
|
|
1083
|
+
( virtual=VIRTUAL { $art.virtual = this.valueWithTokenLocation( true, $virtual ); } )?
|
|
1084
|
+
( key=KEY { $art.key = this.valueWithTokenLocation( true, $key ); } )?
|
|
1118
1085
|
// #ATN: element name can be MASKED or ELEMENT (2x)
|
|
1119
|
-
masked=MASKED
|
|
1086
|
+
( masked=MASKED
|
|
1087
|
+
{
|
|
1088
|
+
$art.masked = this.valueWithTokenLocation( true, $masked ) ;
|
|
1089
|
+
this.message( 'syntax-invalid-masked', $masked, { keyword: 'masked' },
|
|
1090
|
+
'Keyword $(KEYWORD) not supported' );
|
|
1091
|
+
}
|
|
1092
|
+
)?
|
|
1093
|
+
// TODO: order?
|
|
1120
1094
|
ELEMENT?
|
|
1121
1095
|
name=ident['Element']
|
|
1122
|
-
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
this.docComment( $annos ); }
|
|
1126
|
-
annotationAssignment_fix[ $annos ]*
|
|
1096
|
+
{ this.addDef( $art, $outer, 'elements', 'element', $name.id );
|
|
1097
|
+
this.docComment( $art ); }
|
|
1098
|
+
annotationAssignment_fix[ $art ]*
|
|
1127
1099
|
// TODO: we can think of making the typeSpec optional and do checks instead:
|
|
1128
1100
|
// type optional with '=', type required otherwise
|
|
1129
1101
|
(
|
|
@@ -1138,7 +1110,6 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1138
1110
|
(
|
|
1139
1111
|
typeStruct[ $art ]
|
|
1140
1112
|
nullability[ $art ]?
|
|
1141
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-struct' ]?
|
|
1142
1113
|
requiredSemi
|
|
1143
1114
|
|
|
|
1144
1115
|
typeAssociationBase[ $art, true ]
|
|
@@ -1155,11 +1126,11 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1155
1126
|
typeCompoStruct[ $art.target ] optionalSemi
|
|
1156
1127
|
|
|
|
1157
1128
|
// we do not support `Composition of many { e }` - ambiguity ad-hoc target versus foreign keys!
|
|
1158
|
-
typeToMany[ $art ] typeAssociationElementCont[ $art
|
|
1129
|
+
typeToMany[ $art ] typeAssociationElementCont[ $art ]
|
|
1159
1130
|
|
|
|
1160
|
-
typeToOne[ $art ] typeAssociationElementCont[ $art
|
|
1131
|
+
typeToOne[ $art ] typeAssociationElementCont[ $art ]
|
|
1161
1132
|
|
|
|
1162
|
-
simplePath[ $art.target, 'artref' ] typeAssociationElementCont[ $art
|
|
1133
|
+
simplePath[ $art.target, 'artref' ] typeAssociationElementCont[ $art ]
|
|
1163
1134
|
)
|
|
1164
1135
|
|
|
|
1165
1136
|
(
|
|
@@ -1171,52 +1142,55 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1171
1142
|
// #ATN: typeRefOptArgs can start with TYPE
|
|
1172
1143
|
( typeStruct[ $art.items ]
|
|
1173
1144
|
nullability[ $art.items ]?
|
|
1174
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-struct' ]?
|
|
1175
1145
|
| typeTypeOf[ $art.items ]
|
|
1176
1146
|
nullability[ $art.items ]?
|
|
1177
|
-
{ this.docComment( $
|
|
1178
|
-
annotationAssignment_ll1[ $
|
|
1147
|
+
{ this.docComment( $art ); }
|
|
1148
|
+
annotationAssignment_ll1[ $art ]*
|
|
1179
1149
|
| typeRefOptArgs[ $art.items ]
|
|
1180
|
-
nullability[ $art.items ]?
|
|
1181
|
-
{ this.docComment( $
|
|
1182
|
-
annotationAssignment_ll1[ $
|
|
1150
|
+
nullability[ $art.items ]? // only if not followed by `enum`
|
|
1151
|
+
{ this.docComment( $art ); }
|
|
1152
|
+
annotationAssignment_ll1[ $art ]*
|
|
1183
1153
|
(
|
|
1154
|
+
{ if ($art.items.notNull) {
|
|
1155
|
+
this.message( 'syntax-unexpected-null', $art.items.notNull.location,
|
|
1156
|
+
{ keyword: $art.items.notNull.val ? 'not null' : 'null' } );
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1184
1159
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1185
1160
|
enumSymbolDef[ $art.items ]*
|
|
1186
|
-
'}' { this.
|
|
1187
|
-
|
|
1161
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1162
|
+
nullability[ $art.items ]?
|
|
1188
1163
|
)?
|
|
1189
1164
|
)
|
|
1190
1165
|
requiredSemi // also req after struct/enum
|
|
1191
1166
|
|
|
|
1192
1167
|
typeTypeOf[ $art ] elementProperties[ $art ]?
|
|
1193
|
-
{ this.docComment( $
|
|
1194
|
-
annotationAssignment_ll1[ $
|
|
1168
|
+
{ this.docComment( $art ); }
|
|
1169
|
+
annotationAssignment_ll1[ $art ]*
|
|
1195
1170
|
requiredSemi // also req after foreign key spec
|
|
1196
1171
|
|
|
|
1197
1172
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1198
1173
|
typeRefOptArgs[ $art ]
|
|
1199
|
-
{ this.docComment( $
|
|
1200
|
-
annotationAssignment_ll1[ $
|
|
1174
|
+
{ this.docComment( $art ); }
|
|
1175
|
+
annotationAssignment_ll1[ $art ]*
|
|
1201
1176
|
( elementProperties[ $art ]
|
|
1202
|
-
{ this.docComment( $
|
|
1203
|
-
annotationAssignment_ll1[ $
|
|
1177
|
+
{ this.docComment( $art ); }
|
|
1178
|
+
annotationAssignment_ll1[ $art ]*
|
|
1204
1179
|
)?
|
|
1205
1180
|
requiredSemi
|
|
1206
1181
|
|
|
|
1207
1182
|
typeRefOptArgs[ $art ]
|
|
1208
|
-
{ this.docComment( $
|
|
1209
|
-
annotationAssignment_ll1[ $
|
|
1183
|
+
{ this.docComment( $art ); }
|
|
1184
|
+
annotationAssignment_ll1[ $art ]*
|
|
1210
1185
|
(
|
|
1211
1186
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1212
1187
|
enumSymbolDef[ $art ]*
|
|
1213
|
-
'}' { this.
|
|
1188
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1214
1189
|
elementProperties[ $art ]?
|
|
1215
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-enum' ]?
|
|
1216
1190
|
|
|
|
1217
1191
|
elementProperties[ $art ]
|
|
1218
|
-
{ this.docComment( $
|
|
1219
|
-
annotationAssignment_ll1[ $
|
|
1192
|
+
{ this.docComment( $art ); }
|
|
1193
|
+
annotationAssignment_ll1[ $art ]*
|
|
1220
1194
|
)?
|
|
1221
1195
|
requiredSemi // also req after enum spec
|
|
1222
1196
|
)
|
|
@@ -1229,65 +1203,45 @@ elementDefInner[ outer, loc, annos, allowEq ] returns[ art ]
|
|
|
1229
1203
|
else if ($e.expr)
|
|
1230
1204
|
$art.value = $e.expr;
|
|
1231
1205
|
}
|
|
1232
|
-
{ this.docComment( $
|
|
1233
|
-
annotationAssignment_ll1[ $
|
|
1206
|
+
{ this.docComment( $art ); }
|
|
1207
|
+
annotationAssignment_ll1[ $art ]* // for enum symbol def via EXTEND
|
|
1234
1208
|
requiredSemi
|
|
1235
1209
|
)
|
|
1236
1210
|
;
|
|
1237
1211
|
|
|
1238
|
-
extendElement[
|
|
1239
|
-
@after{ /* #ATN 1 */ this.attachLocation($art); }
|
|
1212
|
+
extendElement[ art, outer ]
|
|
1213
|
+
@after{ /* #ATN 1 */ this.attachLocation( $art ); }
|
|
1240
1214
|
:
|
|
1241
1215
|
// #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
|
-
'}'
|
|
1216
|
+
( expected=ELEMENT { $art.expectedKind = 'element'; } )?
|
|
1217
|
+
name=ident['Element']
|
|
1218
|
+
{ this.addDef( $art, $outer, 'elements', 'extend', $name.id ); }
|
|
1219
|
+
extendWithOptElements[ $art, $art ]
|
|
1260
1220
|
;
|
|
1261
1221
|
|
|
1262
|
-
selectItemDef[ outer ] locals[
|
|
1263
|
-
@after{ if ($
|
|
1222
|
+
selectItemDef[ outer ] locals[ art ]
|
|
1223
|
+
@after{ if ($art) this.attachLocation( $art ); }
|
|
1264
1224
|
:
|
|
1265
1225
|
star='*'
|
|
1266
1226
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1267
1227
|
|
|
|
1268
|
-
{ this.docComment( $
|
|
1269
|
-
annotationAssignment_atn[ $
|
|
1228
|
+
{ $art = {};; this.docComment( $art ); }
|
|
1229
|
+
annotationAssignment_atn[ $art ]*
|
|
1270
1230
|
// VIRTUAL is keyword, except if before the following tokens texts:
|
|
1271
1231
|
{ 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
|
-
}
|
|
1232
|
+
( virtual=VIRTUAL { $art.virtual = this.valueWithTokenLocation( true, $virtual ); } )?
|
|
1233
|
+
( key=KEY { $art.key = this.valueWithTokenLocation( true, $key ); } )?
|
|
1234
|
+
selectItemDefBody[ $art, $outer ]
|
|
1279
1235
|
;
|
|
1280
1236
|
|
|
1281
|
-
selectItemDefBody[
|
|
1282
|
-
@after{ /* #ATN
|
|
1237
|
+
selectItemDefBody[ art, outer ]
|
|
1238
|
+
@after{ /* #ATN 2 */ }
|
|
1283
1239
|
:
|
|
1240
|
+
{ $outer.push( $art ); }
|
|
1284
1241
|
(
|
|
1285
|
-
e=expression
|
|
1242
|
+
e=expression { $art.value = $e.expr; }
|
|
1286
1243
|
// we cannot use 'condition' instead, as long as we allow aliases without
|
|
1287
1244
|
// AS (using rule 'ident' instead of 'identNoKeyword') -> ambiguities
|
|
1288
|
-
{
|
|
1289
|
-
$art = this.addItem( $outer, null, null, $annos, { value: $e.expr } );
|
|
1290
|
-
}
|
|
1291
1245
|
( AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1292
1246
|
| n2=ident['Item'] { $art.name = this.fragileAlias( $n2.id, true ); }
|
|
1293
1247
|
| { if (this.getCurrentToken().text !== '.') this.classifyImplicitName( 'Item', $e.expr ); }
|
|
@@ -1311,13 +1265,12 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1311
1265
|
)
|
|
1312
1266
|
)?
|
|
1313
1267
|
|
|
|
1314
|
-
{ $art = this.addItem( $outer, null, null, $annos ); }
|
|
1315
1268
|
selectItemInlineList[ $art, 'expand' ]
|
|
1316
1269
|
excludingClause[ $art ]?
|
|
1317
1270
|
AS n1=ident['Item'] { $art.name = $n1.id }
|
|
1318
1271
|
)
|
|
1319
|
-
{ this.docComment( $
|
|
1320
|
-
annotationAssignment_fix[ $
|
|
1272
|
+
{ this.docComment( $art ); }
|
|
1273
|
+
annotationAssignment_fix[ $art ]*
|
|
1321
1274
|
( ':'
|
|
1322
1275
|
// #ATN: typeRefOptArgs can start with TYPE, REDIRECTED
|
|
1323
1276
|
( re=REDIRECTED to=TO
|
|
@@ -1326,41 +1279,58 @@ selectItemDefBody[ outer, annos ] returns[ art = {} ]
|
|
|
1326
1279
|
(
|
|
1327
1280
|
typeAssociationCont[ $art ]
|
|
1328
1281
|
|
|
|
1329
|
-
{ this.docComment( $
|
|
1330
|
-
annotationAssignment_ll1[ $
|
|
1282
|
+
{ this.docComment( $art ); }
|
|
1283
|
+
annotationAssignment_ll1[ $art ]*
|
|
1331
1284
|
)
|
|
1332
1285
|
| typeTypeOf[ $art ]
|
|
1333
|
-
{ this.docComment( $
|
|
1334
|
-
annotationAssignment_ll1[ $
|
|
1335
|
-
| typeRefOptArgs[ $art ]
|
|
1336
|
-
{ this.docComment( $
|
|
1337
|
-
annotationAssignment_ll1[ $
|
|
1286
|
+
{ this.docComment( $art ); }
|
|
1287
|
+
annotationAssignment_ll1[ $art ]*
|
|
1288
|
+
| typeRefOptArgs[ $art ]
|
|
1289
|
+
{ this.docComment( $art ); }
|
|
1290
|
+
annotationAssignment_ll1[ $art ]*
|
|
1291
|
+
|
|
|
1292
|
+
typeAssociationBase[ $art, false ]
|
|
1293
|
+
// #ATN: path could start with MANY or ONE - make sure a token follows in same rule!
|
|
1294
|
+
( typeToMany[ $art ] | typeToOne[ $art ] | simplePath[ $art.target, 'artref' ] )
|
|
1295
|
+
typeAssociationCont[ $art ]?
|
|
1296
|
+
{ this.associationInSelectItem( $art ); }
|
|
1338
1297
|
)
|
|
1339
1298
|
)?
|
|
1340
1299
|
;
|
|
1341
1300
|
|
|
1301
|
+
bracedSelectItemListDef[ query ]
|
|
1302
|
+
:
|
|
1303
|
+
'{' { $query.columns = this.createArray(); }
|
|
1304
|
+
(
|
|
1305
|
+
selectItemDef[ $query.columns ]
|
|
1306
|
+
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1307
|
+
selectItemDef[ $query.columns ]
|
|
1308
|
+
)*
|
|
1309
|
+
)?
|
|
1310
|
+
'}' { this.finalizeDictOrArray( $query.columns ); }
|
|
1311
|
+
;
|
|
1312
|
+
|
|
1342
1313
|
selectItemInlineList[ art, clause ]
|
|
1343
1314
|
:
|
|
1344
|
-
'{'
|
|
1345
|
-
{ $art[$clause] = []; }
|
|
1315
|
+
'{' { $art[$clause] = this.createArray(); }
|
|
1346
1316
|
(
|
|
1347
1317
|
selectItemInlineDef[ $art[$clause] ]
|
|
1348
1318
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1349
1319
|
selectItemInlineDef[ $art[$clause] ]
|
|
1350
1320
|
)*
|
|
1351
1321
|
)?
|
|
1352
|
-
'}'
|
|
1322
|
+
'}' { this.finalizeDictOrArray( $art[$clause] ); }
|
|
1353
1323
|
;
|
|
1354
1324
|
|
|
1355
|
-
selectItemInlineDef[ outer ] locals[
|
|
1356
|
-
@after{ if ($
|
|
1325
|
+
selectItemInlineDef[ outer ] locals[ art ]
|
|
1326
|
+
@after{ if ($art) this.attachLocation( $art ); }
|
|
1357
1327
|
:
|
|
1358
1328
|
star='*'
|
|
1359
1329
|
{ $outer.push( this.valueWithTokenLocation( '*', $star ) ); }
|
|
1360
1330
|
|
|
|
1361
|
-
{ this.docComment( $
|
|
1362
|
-
annotationAssignment_atn[ $
|
|
1363
|
-
|
|
1331
|
+
{ $art = {};; this.docComment( $art ); }
|
|
1332
|
+
annotationAssignment_atn[ $art ]*
|
|
1333
|
+
selectItemDefBody[ $art, $outer ]
|
|
1364
1334
|
;
|
|
1365
1335
|
|
|
1366
1336
|
parameterListDef[ art ]
|
|
@@ -1374,51 +1344,22 @@ parameterListDef[ art ]
|
|
|
1374
1344
|
parameterDef[ $art ]
|
|
1375
1345
|
)*
|
|
1376
1346
|
)?
|
|
1377
|
-
')' { this.
|
|
1347
|
+
')' { this.finalizeDictOrArray( $art.params ); }
|
|
1378
1348
|
;
|
|
1379
1349
|
|
|
1380
|
-
parameterDef[ outer ] locals[ art
|
|
1381
|
-
@after { this.attachLocation($art); }
|
|
1350
|
+
parameterDef[ outer ] locals[ art = {} ]
|
|
1351
|
+
@after { this.attachLocation( $art ); }
|
|
1382
1352
|
:
|
|
1383
|
-
{ this.docComment( $
|
|
1384
|
-
annotationAssignment_ll1[ $
|
|
1353
|
+
{ this.docComment( $art ); }
|
|
1354
|
+
annotationAssignment_ll1[ $art ]*
|
|
1385
1355
|
name=ident['Param']
|
|
1386
|
-
{
|
|
1387
|
-
this.docComment( $
|
|
1388
|
-
annotationAssignment_fix[ $
|
|
1356
|
+
{ this.addDef( $art, $outer, 'params', 'param', $name.id );
|
|
1357
|
+
this.docComment( $art ); }
|
|
1358
|
+
annotationAssignment_fix[ $art ]*
|
|
1389
1359
|
typeSpec[ $art ]
|
|
1390
1360
|
defaultValue[ $art ]?
|
|
1391
|
-
{ this.docComment( $
|
|
1392
|
-
annotationAssignment_ll1[ $
|
|
1393
|
-
;
|
|
1394
|
-
|
|
1395
|
-
entityParameters[ art ]
|
|
1396
|
-
:
|
|
1397
|
-
'(' { $art.params = this.createDict(); }
|
|
1398
|
-
// also empty param list (we might do some hacking later to allow reserved words)
|
|
1399
|
-
// see annotationAssignment_paren
|
|
1400
|
-
(
|
|
1401
|
-
entityParameterDef[ $art ]
|
|
1402
|
-
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1403
|
-
entityParameterDef[ $art ]
|
|
1404
|
-
)*
|
|
1405
|
-
)?
|
|
1406
|
-
')' { this.setDictEndLocation( $art.params ); }
|
|
1407
|
-
;
|
|
1408
|
-
|
|
1409
|
-
entityParameterDef[ outer ] locals[ art, annos = [] ]
|
|
1410
|
-
@after { this.attachLocation($art); }
|
|
1411
|
-
:
|
|
1412
|
-
{ this.docComment( $annos ); }
|
|
1413
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1414
|
-
name=ident['Param']
|
|
1415
|
-
{ $art = this.addDef( $outer, 'params', 'param', $name.id, $annos );
|
|
1416
|
-
this.docComment( $annos ); }
|
|
1417
|
-
annotationAssignment_fix[ $annos ]*
|
|
1418
|
-
typeSpec[ $art ]
|
|
1419
|
-
defaultValue[ $art ]?
|
|
1420
|
-
{ this.docComment( $annos ); }
|
|
1421
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1361
|
+
{ this.docComment( $art ); }
|
|
1362
|
+
annotationAssignment_ll1[ $art ]*
|
|
1422
1363
|
;
|
|
1423
1364
|
|
|
1424
1365
|
nullability[ art ]
|
|
@@ -1445,21 +1386,25 @@ elementProperties[ elem ]
|
|
|
1445
1386
|
|
|
1446
1387
|
// View definitions ----------------------------------------------------------
|
|
1447
1388
|
|
|
1448
|
-
viewDef[
|
|
1449
|
-
@after { this.attachLocation($art); }
|
|
1389
|
+
viewDef[ art, outer ] locals[ name = {} ]
|
|
1390
|
+
@after { this.attachLocation( $art ); }
|
|
1450
1391
|
:
|
|
1451
1392
|
v=VIEW simplePath[ $name, 'Entity' ]
|
|
1452
|
-
{ $art
|
|
1453
|
-
this.
|
|
1454
|
-
|
|
1393
|
+
{ $art['$'+'syntax'] = 'view';
|
|
1394
|
+
this.addDef( $art, $outer, 'artifacts', 'entity', $name );
|
|
1395
|
+
this.docComment( $art ); }
|
|
1396
|
+
annotationAssignment_fix[ $art ]*
|
|
1455
1397
|
(
|
|
1456
|
-
|
|
1398
|
+
parameterListDef[ $art ]
|
|
1457
1399
|
|
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1400
|
+
// TODO: warning deprecated?
|
|
1401
|
+
( HideAlternatives | WITH ) { $art.params = this.createDict(); }
|
|
1402
|
+
PARAMETERS
|
|
1403
|
+
parameterDef[ $art ]
|
|
1404
|
+
( ',' parameterDef[ $art ] )* // no optional final ',' here
|
|
1405
|
+
{ this.finalizeDictOrArray( $art.params ); }
|
|
1461
1406
|
)?
|
|
1462
|
-
AS qe=queryExpression { $art.query = $qe.query; }
|
|
1407
|
+
AS qe=queryExpression { $art.query = $qe.query; }
|
|
1463
1408
|
// TODO check ANTLR: bad msg with 'view V as'<eof> but 'view V as FOO' is fine
|
|
1464
1409
|
requiredSemi
|
|
1465
1410
|
;
|
|
@@ -1490,12 +1435,12 @@ typeSpec[ art ] // for params
|
|
|
1490
1435
|
(
|
|
1491
1436
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1492
1437
|
enumSymbolDef[ $art ]*
|
|
1493
|
-
'}' { this.
|
|
1438
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1494
1439
|
)?
|
|
1495
1440
|
)
|
|
1496
1441
|
;
|
|
1497
1442
|
|
|
1498
|
-
returnTypeSpec[ art
|
|
1443
|
+
returnTypeSpec[ art ]
|
|
1499
1444
|
@after{ /* #ATN 1 */ }
|
|
1500
1445
|
:
|
|
1501
1446
|
ret=RETURNS { $art.returns = { location: this.tokenLocation( $ret ), kind: 'param' }; }
|
|
@@ -1511,17 +1456,15 @@ returnTypeSpec[ art, annos ]
|
|
|
1511
1456
|
(
|
|
1512
1457
|
ENUM '{' { $art.returns.enum = this.createDict(); }
|
|
1513
1458
|
enumSymbolDef[ $art.returns ]*
|
|
1514
|
-
'}' { this.
|
|
1515
|
-
|
|
|
1516
|
-
misplacedAnnotations[ $annos, 'syntax-anno-after-params' ]
|
|
1459
|
+
'}' { this.finalizeDictOrArray( $art.returns.enum ); }
|
|
1517
1460
|
)?
|
|
1518
1461
|
)
|
|
1519
1462
|
|
|
1520
|
-
requiredSemi // currently for all - might change if we get rid of the misplaced annos
|
|
1463
|
+
requiredSemi // currently for all - might change if we get rid of the misplaced annos (TODO: Now removed)
|
|
1521
1464
|
;
|
|
1522
1465
|
|
|
1523
1466
|
|
|
1524
|
-
typeSpecSemi[ art
|
|
1467
|
+
typeSpecSemi[ art ] // with 'includes', for type and annotation defs
|
|
1525
1468
|
@after{ /* #ATN 3 */ }
|
|
1526
1469
|
:
|
|
1527
1470
|
typeStruct[ $art ]
|
|
@@ -1559,18 +1502,28 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1559
1502
|
optionalSemi
|
|
1560
1503
|
| typeTypeOf[ $art.items ]
|
|
1561
1504
|
nullability[ $art.items ]?
|
|
1562
|
-
{ this.docComment( $
|
|
1563
|
-
annotationAssignment_ll1[ $
|
|
1505
|
+
{ this.docComment( $art ); }
|
|
1506
|
+
annotationAssignment_ll1[ $art ]*
|
|
1564
1507
|
requiredSemi
|
|
1565
1508
|
| typeRefOptArgs[ $art.items ]
|
|
1566
|
-
nullability[ $art.items ]?
|
|
1567
|
-
{ this.docComment( $
|
|
1568
|
-
annotationAssignment_ll1[ $
|
|
1509
|
+
nullability[ $art.items ]? // only if not followed by `enum`
|
|
1510
|
+
{ this.docComment( $art ); }
|
|
1511
|
+
annotationAssignment_ll1[ $art ]*
|
|
1569
1512
|
(
|
|
1513
|
+
{ if ($art.items.notNull) {
|
|
1514
|
+
this.message( 'syntax-unexpected-null', $art.items.notNull.location,
|
|
1515
|
+
{ keyword: $art.items.notNull.val ? 'not null' : 'null' } );
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1570
1518
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1571
1519
|
enumSymbolDef[ $art.items ]*
|
|
1572
|
-
'}' { this.
|
|
1573
|
-
|
|
1520
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1521
|
+
(
|
|
1522
|
+
nullability[ $art.items ]
|
|
1523
|
+
requiredSemi
|
|
1524
|
+
|
|
|
1525
|
+
optionalSemi
|
|
1526
|
+
)
|
|
1574
1527
|
|
|
|
1575
1528
|
requiredSemi
|
|
1576
1529
|
)
|
|
@@ -1578,46 +1531,27 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1578
1531
|
|
|
|
1579
1532
|
typeTypeOf[ $art ]
|
|
1580
1533
|
defaultValue[ $art ]?
|
|
1581
|
-
{ this.docComment( $
|
|
1582
|
-
annotationAssignment_ll1[ $
|
|
1534
|
+
{ this.docComment( $art ); }
|
|
1535
|
+
annotationAssignment_ll1[ $art ]* requiredSemi
|
|
1583
1536
|
|
|
|
1584
1537
|
l=LOCALIZED { $art.localized = this.valueWithTokenLocation( true, $l ); }
|
|
1585
1538
|
typeRefOptArgs[ $art ]
|
|
1586
1539
|
defaultValue[ $art ]?
|
|
1587
|
-
{ this.docComment( $
|
|
1588
|
-
annotationAssignment_ll1[ $
|
|
1540
|
+
{ this.docComment( $art ); }
|
|
1541
|
+
annotationAssignment_ll1[ $art ]*
|
|
1589
1542
|
requiredSemi
|
|
1590
1543
|
|
|
|
1591
1544
|
// alt lookahead includes MANY '{'
|
|
1592
1545
|
{ $art.type = {}; }
|
|
1593
1546
|
simplePath[ $art.type, 'artref' ]
|
|
1594
1547
|
(
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1599
|
-
(
|
|
1600
|
-
v=VARIABLE
|
|
1601
|
-
{ $art['$'+'typeArgs'].push(
|
|
1602
|
-
{ literal: 'string', val: 'variable', location: this.tokenLocation($v) } );
|
|
1603
|
-
}
|
|
1604
|
-
|
|
|
1605
|
-
f=FLOATING
|
|
1606
|
-
{ $art['$'+'typeArgs'].push(
|
|
1607
|
-
{ literal: 'string', val: 'floating', location: this.tokenLocation($f) } );
|
|
1608
|
-
}
|
|
1609
|
-
|
|
|
1610
|
-
tail=Number
|
|
1611
|
-
{ $art['$'+'typeArgs'].push( this.numberLiteral( $tail ) ); }
|
|
1612
|
-
)
|
|
1613
|
-
)*
|
|
1614
|
-
')'
|
|
1615
|
-
{ this.docComment( $annos ); }
|
|
1616
|
-
annotationAssignment_ll1[ $annos ]*
|
|
1548
|
+
typeRefArgs[ $art ]
|
|
1549
|
+
{ this.docComment( $art ); }
|
|
1550
|
+
annotationAssignment_ll1[ $art ]*
|
|
1617
1551
|
(
|
|
1618
1552
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1619
1553
|
enumSymbolDef[ $art ]*
|
|
1620
|
-
'}' { this.
|
|
1554
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1621
1555
|
(
|
|
1622
1556
|
optionalSemi
|
|
1623
1557
|
|
|
|
@@ -1632,12 +1566,12 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1632
1566
|
':' // with element, e.g. `type T : E:elem enum { ... }`
|
|
1633
1567
|
{ $art.type.scope = $art.type.path.length; }
|
|
1634
1568
|
simplePath[ $art.type, 'ref']
|
|
1635
|
-
{ this.docComment( $
|
|
1636
|
-
annotationAssignment_ll1[ $
|
|
1569
|
+
{ this.docComment( $art ); }
|
|
1570
|
+
annotationAssignment_ll1[ $art ]*
|
|
1637
1571
|
(
|
|
1638
1572
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1639
1573
|
enumSymbolDef[ $art ]*
|
|
1640
|
-
'}' { this.
|
|
1574
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1641
1575
|
(
|
|
1642
1576
|
optionalSemi
|
|
1643
1577
|
|
|
|
@@ -1649,12 +1583,12 @@ typeSpecSemi[ art, annos ] // with 'includes', for type and annotation defs
|
|
|
1649
1583
|
requiredSemi
|
|
1650
1584
|
)
|
|
1651
1585
|
|
|
|
1652
|
-
{ this.docComment( $
|
|
1653
|
-
annotationAssignment_ll1[ $
|
|
1586
|
+
{ this.docComment( $art ); }
|
|
1587
|
+
annotationAssignment_ll1[ $art ]*
|
|
1654
1588
|
(
|
|
1655
1589
|
ENUM '{' { $art.enum = this.createDict(); }
|
|
1656
1590
|
enumSymbolDef[ $art ]*
|
|
1657
|
-
'}' { this.
|
|
1591
|
+
'}' { this.finalizeDictOrArray( $art.enum ); }
|
|
1658
1592
|
(
|
|
1659
1593
|
optionalSemi
|
|
1660
1594
|
|
|
|
@@ -1682,7 +1616,7 @@ typeStruct[ art, attachLoc = false ]
|
|
|
1682
1616
|
:
|
|
1683
1617
|
'{' { $art.elements = this.createDict(); }
|
|
1684
1618
|
elementDef[ $art ]*
|
|
1685
|
-
'}' { this.
|
|
1619
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
1686
1620
|
;
|
|
1687
1621
|
|
|
1688
1622
|
typeCompoStruct[ art ]
|
|
@@ -1690,7 +1624,7 @@ typeCompoStruct[ art ]
|
|
|
1690
1624
|
:
|
|
1691
1625
|
COMPOSITIONofBRACE { $art.elements = this.createDict(); }
|
|
1692
1626
|
elementDef[ $art ]*
|
|
1693
|
-
'}' { this.
|
|
1627
|
+
'}' { this.finalizeDictOrArray( $art.elements ); }
|
|
1694
1628
|
;
|
|
1695
1629
|
|
|
1696
1630
|
typeArray[ art ]
|
|
@@ -1712,7 +1646,7 @@ typeArray[ art ]
|
|
|
1712
1646
|
(
|
|
1713
1647
|
ENUM '{' { $art.items.enum = this.createDict(); }
|
|
1714
1648
|
enumSymbolDef[ $art.items ]*
|
|
1715
|
-
'}' { this.
|
|
1649
|
+
'}' { this.finalizeDictOrArray( $art.items.enum ); }
|
|
1716
1650
|
)?
|
|
1717
1651
|
)
|
|
1718
1652
|
;
|
|
@@ -1741,33 +1675,31 @@ typeAssociationCont[ art ]
|
|
|
1741
1675
|
:
|
|
1742
1676
|
(
|
|
1743
1677
|
'{' { $art.foreignKeys = this.createDict(); }
|
|
1744
|
-
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1745
1678
|
(
|
|
1746
1679
|
foreignKey[ $art ]
|
|
1747
1680
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1748
1681
|
foreignKey[ $art ]
|
|
1749
1682
|
)*
|
|
1750
1683
|
)?
|
|
1751
|
-
'}' { this.
|
|
1684
|
+
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1752
1685
|
|
|
|
1753
1686
|
ON cond=condition
|
|
1754
1687
|
{ $art.on=$cond.cond; }
|
|
1755
1688
|
)
|
|
1756
1689
|
;
|
|
1757
1690
|
|
|
1758
|
-
typeAssociationElementCont[ art
|
|
1691
|
+
typeAssociationElementCont[ art ] // including Composition
|
|
1759
1692
|
// optional NULL / NOT NULL for managed association only
|
|
1760
1693
|
:
|
|
1761
1694
|
(
|
|
1762
1695
|
'{' { $art.foreignKeys = this.createDict(); }
|
|
1763
|
-
{ this.addDef( $art, 'foreignKeys' ); }
|
|
1764
1696
|
(
|
|
1765
1697
|
foreignKey[ $art ]
|
|
1766
1698
|
( ',' { if (this.isStraightBefore("}")) break; } // allow ',' before '}'
|
|
1767
1699
|
foreignKey[ $art ]
|
|
1768
1700
|
)*
|
|
1769
1701
|
)?
|
|
1770
|
-
'}' { this.
|
|
1702
|
+
'}' { this.finalizeDictOrArray( $art.foreignKeys ); }
|
|
1771
1703
|
nullability[ $art ]?
|
|
1772
1704
|
|
|
|
1773
1705
|
ON cond=condition
|
|
@@ -1775,8 +1707,8 @@ typeAssociationElementCont[ art, annos ] // including Composition
|
|
|
1775
1707
|
|
|
|
1776
1708
|
nullability[ $art ]
|
|
1777
1709
|
)?
|
|
1778
|
-
{ this.docComment( $
|
|
1779
|
-
annotationAssignment_ll1[ $
|
|
1710
|
+
{ this.docComment( $art ); }
|
|
1711
|
+
annotationAssignment_ll1[ $art ]*
|
|
1780
1712
|
requiredSemi // also req after foreign key spec
|
|
1781
1713
|
;
|
|
1782
1714
|
|
|
@@ -1830,10 +1762,9 @@ cardinality[ art ] locals[ card = {} ]
|
|
|
1830
1762
|
foreignKey[ outer ] locals[ art = {}, elem = {} ]
|
|
1831
1763
|
@after { this.attachLocation($art); }
|
|
1832
1764
|
:
|
|
1833
|
-
simplePath[ $elem, 'ref' ]
|
|
1765
|
+
simplePath[ $elem, 'ref' ] { $art.targetElement = $elem; }
|
|
1834
1766
|
( AS name=ident['Key'] )?
|
|
1835
|
-
{
|
|
1836
|
-
undefined, { targetElement: $elem } ); }
|
|
1767
|
+
{ this.addDef( $art, $outer, 'foreignKeys', 'key', ($ctx.name) ? $name.id : $elem.path ); }
|
|
1837
1768
|
;
|
|
1838
1769
|
|
|
1839
1770
|
typeTypeOf[ art ] locals[ _sync = 'nop' ]
|
|
@@ -1855,9 +1786,21 @@ typeRefOptArgs[ art ]
|
|
|
1855
1786
|
:
|
|
1856
1787
|
simplePath[ $art.type, 'artref' ]
|
|
1857
1788
|
(
|
|
1858
|
-
|
|
1789
|
+
typeRefArgs[ $art ]
|
|
1790
|
+
|
|
|
1791
|
+
':'
|
|
1792
|
+
{ $art.type.scope = $art.type.path.length; }
|
|
1793
|
+
simplePath[ $art.type, 'ref']
|
|
1794
|
+
)?
|
|
1795
|
+
;
|
|
1796
|
+
|
|
1797
|
+
typeRefArgs[ art ]
|
|
1798
|
+
:
|
|
1799
|
+
paren='(' { $art['$'+'typeArgs'] = this.createArray(); }
|
|
1800
|
+
(
|
|
1801
|
+
// unnamed arguments
|
|
1859
1802
|
head=Number
|
|
1860
|
-
{ $art['$'+'typeArgs']
|
|
1803
|
+
{ $art['$'+'typeArgs'].push( this.numberLiteral( $head ) ); }
|
|
1861
1804
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1862
1805
|
(
|
|
1863
1806
|
v=VARIABLE
|
|
@@ -1874,14 +1817,45 @@ typeRefOptArgs[ art ]
|
|
|
1874
1817
|
{ $art['$'+'typeArgs'].push( this.numberLiteral( $tail ) ); }
|
|
1875
1818
|
)
|
|
1876
1819
|
)*
|
|
1877
|
-
')'
|
|
1878
1820
|
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1821
|
+
// named arguments
|
|
1822
|
+
typeNamedArg[ $art ]
|
|
1823
|
+
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
1824
|
+
typeNamedArg[ $art ]
|
|
1825
|
+
)*
|
|
1826
|
+
)
|
|
1827
|
+
')'{ this.finalizeDictOrArray( $art['$'+'typeArgs']); }
|
|
1883
1828
|
;
|
|
1884
1829
|
|
|
1830
|
+
typeNamedArg[ art ] locals[ arg = '' ]
|
|
1831
|
+
:
|
|
1832
|
+
name=ident['paramname']
|
|
1833
|
+
':'
|
|
1834
|
+
{ if (this.checkTypeFacet( $art, $name.id ))
|
|
1835
|
+
$arg = $name.id.id;
|
|
1836
|
+
}
|
|
1837
|
+
(
|
|
1838
|
+
val=Number
|
|
1839
|
+
{ if ($arg && $art && $name.id) {
|
|
1840
|
+
$art[$arg] = this.numberLiteral( $val );
|
|
1841
|
+
}
|
|
1842
|
+
}
|
|
1843
|
+
|
|
|
1844
|
+
v=VARIABLE
|
|
1845
|
+
{ if ($arg && $art && $name.id) {
|
|
1846
|
+
$art[$arg] = { literal: 'string', val: 'variable', location: this.tokenLocation($v) };
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
|
|
|
1850
|
+
f=FLOATING
|
|
1851
|
+
{ if ($arg && $art && $name.id) {
|
|
1852
|
+
$art[$arg] = { literal: 'string', val: 'floating', location: this.tokenLocation($f) };
|
|
1853
|
+
}
|
|
1854
|
+
}
|
|
1855
|
+
)
|
|
1856
|
+
;
|
|
1857
|
+
|
|
1858
|
+
|
|
1885
1859
|
// Queries -------------------------------------------------------------------
|
|
1886
1860
|
|
|
1887
1861
|
queryExpression returns[ query ] // QLSubqueryComplex, SubqueryComplex
|
|
@@ -1996,7 +1970,7 @@ overClause returns [ over ]
|
|
|
1996
1970
|
@after { this.attachLocation( $over ); }
|
|
1997
1971
|
:
|
|
1998
1972
|
o=OVER { $over = { op: this.valueWithTokenLocation( 'over', $o ) , args: [] } }
|
|
1999
|
-
'('
|
|
1973
|
+
'(' // TODO: check whether an extra location could be useful
|
|
2000
1974
|
( pb=partitionByClause { $over.args.push( $pb.expr ); } )?
|
|
2001
1975
|
( ob=overOrderByClause { $over.args.push( $ob.expr ); } )?
|
|
2002
1976
|
( wf=windowFrameClause { $over.args.push( $wf.wf ); } )?
|
|
@@ -2049,13 +2023,13 @@ queryPrimary returns[ query = {} ]
|
|
|
2049
2023
|
(
|
|
2050
2024
|
mixin=MIXIN '{' { $query.mixin = this.createDict(); }
|
|
2051
2025
|
mixinElementDef[ $query ]*
|
|
2052
|
-
'}' { this.
|
|
2026
|
+
'}' { this.finalizeDictOrArray( $query.mixin ); }
|
|
2053
2027
|
INTO
|
|
2054
2028
|
)?
|
|
2055
2029
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
2056
2030
|
{ $query.quantifier = this.valueWithTokenLocation( $ad.text.toLowerCase(), $ad ); }
|
|
2057
2031
|
)?
|
|
2058
|
-
bracedSelectItemListDef[ $query ]?
|
|
2032
|
+
bracedSelectItemListDef[ $query, 'columns' ]?
|
|
2059
2033
|
excludingClause[ $query ]?
|
|
2060
2034
|
|
|
|
2061
2035
|
( ad=( ALL | DISTINCT ) // TODO: or directly after SELECT ?
|
|
@@ -2241,6 +2215,7 @@ conditionAnd returns [ cond ] locals [ args = [], andl = [] ]
|
|
|
2241
2215
|
( and=AND c2=conditionTerm { $args.push($c2.cond); $andl.push(this.valueWithTokenLocation( 'and', $and )) } )*
|
|
2242
2216
|
;
|
|
2243
2217
|
|
|
2218
|
+
// Note: New operators need to be added to functionExpressionOperatorsRequireParentheses[] in toCdl.js.
|
|
2244
2219
|
conditionTerm returns [ cond ]
|
|
2245
2220
|
@after{
|
|
2246
2221
|
if ($cond) { this.attachLocation($cond); } else { $cond = $expr.expr; }
|
|
@@ -2288,6 +2263,7 @@ conditionTerm returns [ cond ]
|
|
|
2288
2263
|
)? // optional: for conditions in parentheses
|
|
2289
2264
|
;
|
|
2290
2265
|
|
|
2266
|
+
// Note: New operators need to be added to functionExpressionOperatorsRequireParentheses[] in toCdl.js.
|
|
2291
2267
|
predicate[ cond, negated ]
|
|
2292
2268
|
// As an alternative, we could have a `negated` properties for the operations
|
|
2293
2269
|
// `isNull`(!), `in`, `between` and `like` (or produce the same AST as for
|
|
@@ -2397,7 +2373,9 @@ expressionTerm returns [ expr ] locals [ op, args = [] ]
|
|
|
2397
2373
|
}
|
|
2398
2374
|
)
|
|
2399
2375
|
|
|
|
2400
|
-
qm=
|
|
2376
|
+
qm= '?' // is automatically not mentioned as CC candidate
|
|
2377
|
+
// if we have an HideAlternatives here, we would block it to use it in
|
|
2378
|
+
// parallel to an expression (would produce adaptivePredict() otherwise)
|
|
2401
2379
|
{ $expr = { param: this.valueWithTokenLocation( '?', $qm ), scope: 'param' };
|
|
2402
2380
|
this.csnParseOnly( 'Dynamic parameter "?" is not supported', $qm );
|
|
2403
2381
|
}
|
|
@@ -2425,39 +2403,12 @@ expressionTerm returns [ expr ] locals [ op, args = [] ]
|
|
|
2425
2403
|
;
|
|
2426
2404
|
|
|
2427
2405
|
specialFunction returns [ ret = { } ] locals[ art = {} ]
|
|
2428
|
-
@after{ /* #ATN 1 */ }
|
|
2429
2406
|
:
|
|
2430
|
-
|
|
2431
|
-
{ $ret = this.functionAst( $fun, $open ); }
|
|
2432
|
-
// #ATN: we do not want to reserve these three optional keywords
|
|
2433
|
-
(
|
|
2434
|
-
t=( LEADING | TRAILING | BOTH ) { $ret.args[0].args.push( $t.text ); }
|
|
2435
|
-
( e=expression { $ret.args[0].args.push( $e.expr ); } )?
|
|
2436
|
-
t=FROM e=expression { $ret.args[0].args.push( $t.text, $e.expr ); }
|
|
2437
|
-
|
|
|
2438
|
-
e=expression
|
|
2439
|
-
(
|
|
2440
|
-
{ $ret.args[0].args.push( $e.expr ); }
|
|
2441
|
-
t=FROM e=expression
|
|
2442
|
-
{ $ret.args[0].args.push( $t.text, $e.expr ); }
|
|
2443
|
-
|
|
|
2444
|
-
{ $ret.args[0] = $e.expr; }
|
|
2445
|
-
)
|
|
2446
|
-
)
|
|
2447
|
-
')'
|
|
2448
|
-
|
|
|
2449
|
-
fun=EXTRACT open='('
|
|
2450
|
-
{ $ret = this.functionAst( $fun, $open ); }
|
|
2451
|
-
t=( YEAR | MONTH | DAY | HOUR | MINUTE | SECOND )
|
|
2452
|
-
f=FROM e=expression
|
|
2453
|
-
{ $ret.args[0].args.push( $t.text, $f.text, $e.expr ); }
|
|
2454
|
-
')'
|
|
2455
|
-
|
|
|
2456
|
-
ca=CAST open='('
|
|
2407
|
+
ca=CAST '(' // see createArray() in action
|
|
2457
2408
|
{
|
|
2458
2409
|
$ret = {
|
|
2459
2410
|
op: this.valueWithTokenLocation( 'cast', $ca ),
|
|
2460
|
-
args:
|
|
2411
|
+
args: this.createArray(),
|
|
2461
2412
|
location: this.tokenLocation( $ca )
|
|
2462
2413
|
};
|
|
2463
2414
|
}
|
|
@@ -2465,8 +2416,7 @@ specialFunction returns [ ret = { } ] locals[ art = {} ]
|
|
|
2465
2416
|
{
|
|
2466
2417
|
$ret.args.push( $e.expr );
|
|
2467
2418
|
}
|
|
2468
|
-
')'
|
|
2469
|
-
// TODO: ROUND - see also resolver.js
|
|
2419
|
+
')' { this.finalizeDictOrArray( $ret.args ); }
|
|
2470
2420
|
;
|
|
2471
2421
|
|
|
2472
2422
|
// query path includes aggregation:
|
|
@@ -2492,36 +2442,47 @@ valuePath[ category, location = null ] returns[ qp = { path: [] } ] locals[ _syn
|
|
|
2492
2442
|
;
|
|
2493
2443
|
|
|
2494
2444
|
fromArguments[ pathStep ]
|
|
2445
|
+
@init{ if (!$pathStep) $pathStep = {}; } // grammar robustness, see test/negative/parser/NamedExpression.cds
|
|
2495
2446
|
:
|
|
2496
|
-
|
|
2497
|
-
|
|
2447
|
+
'(' { $pathStep.args = this.createDict(); $pathStep['$'+'syntax'] = ':'; } // necessary?
|
|
2448
|
+
name=ident['paramname'] ':'
|
|
2449
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2498
2450
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2499
|
-
|
|
2451
|
+
name=ident['paramname'] ':'
|
|
2452
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2500
2453
|
)*
|
|
2501
|
-
')'
|
|
2454
|
+
')' { this.finalizeDictOrArray( $pathStep.args ); }
|
|
2502
2455
|
;
|
|
2503
2456
|
|
|
2504
2457
|
pathArguments[ pathStep, considerSpecial ]
|
|
2505
|
-
@
|
|
2458
|
+
@init{
|
|
2459
|
+
if (!$pathStep) $pathStep = {}; // grammar robustness, see test/negative/parser/NamedExpression.cds
|
|
2460
|
+
this.genericFunctionsStack.push( this['$'+'genericKeywords'] );
|
|
2461
|
+
}
|
|
2506
2462
|
:
|
|
2507
2463
|
{ this.excludeExpected([ 'ORDER' ]); }
|
|
2508
|
-
|
|
2509
|
-
{ this.prepareGenericKeywords( $considerSpecial ); }
|
|
2510
|
-
// ATN, LL2: Identifier can start both named arguments and the positional.
|
|
2464
|
+
'(' // dict or array, see below
|
|
2511
2465
|
// Make sure that we do not introduce A:B paths in expressions!
|
|
2466
|
+
// Need to avoid adaptPredict(), otherwise Generic keywords won't work in funcExpression
|
|
2467
|
+
{ this.setLocalTokenForId( { ':': 'HelperToken1', '=>': 'HelperToken2' } ); }
|
|
2512
2468
|
(
|
|
2513
|
-
|
|
2469
|
+
{ $pathStep.args = this.createDict(); $pathStep['$'+'syntax'] = ':'; }
|
|
2470
|
+
id=HelperToken1 ':'
|
|
2471
|
+
namedExpression[ $pathStep, this.identAst( $id, 'paramname', true ) ]
|
|
2514
2472
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2515
|
-
|
|
2473
|
+
name=ident['paramname'] ':'
|
|
2474
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2516
2475
|
)*
|
|
2517
2476
|
|
|
|
2518
|
-
{ $pathStep.args =
|
|
2519
|
-
|
|
2477
|
+
{ $pathStep.args = this.createDict(); } // TODO: XSN func path cleanup
|
|
2478
|
+
id=HelperToken2 '=>'
|
|
2479
|
+
namedExpression[ $pathStep, this.identAst( $id, 'paramname', true ) ]
|
|
2520
2480
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2521
|
-
|
|
2481
|
+
name=ident['paramname'] '=>'
|
|
2482
|
+
namedExpression[ $pathStep, $name.id ]
|
|
2522
2483
|
)*
|
|
2523
2484
|
|
|
|
2524
|
-
{ $pathStep.args =
|
|
2485
|
+
{ $pathStep.args = this.createArray(); }
|
|
2525
2486
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
2526
2487
|
( ',' { if (this.isStraightBefore(')')) break; } // allow ',' before ')'
|
|
2527
2488
|
funcExpression[ $pathStep, $considerSpecial ]
|
|
@@ -2534,47 +2495,82 @@ pathArguments[ pathStep, considerSpecial ]
|
|
|
2534
2495
|
}
|
|
2535
2496
|
)?
|
|
2536
2497
|
|
|
|
2537
|
-
|
|
2538
|
-
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
2539
|
-
|
|
|
2540
|
-
d=DISTINCT { $pathStep.quantifier = this.valueWithTokenLocation( 'distinct', $d ); }
|
|
2541
|
-
e1=expression { $pathStep.args = [ $e1.expr ]; }
|
|
2542
|
-
( ',' e2=expression { $pathStep.args.push( $e2.expr ); } )*
|
|
2543
|
-
|
|
|
2544
|
-
star='*'
|
|
2545
|
-
{ $pathStep.args = [ { location: this.tokenLocation( $star ), val: '*', literal: 'token' } ]; }
|
|
2546
|
-
|
|
|
2547
|
-
{ $pathStep.args = []; }
|
|
2498
|
+
{ $pathStep.args = this.createArray(); }
|
|
2548
2499
|
)
|
|
2549
|
-
')'
|
|
2500
|
+
')' { this.finalizeDictOrArray( $pathStep.args ); }
|
|
2550
2501
|
;
|
|
2502
|
+
finally { // see @init
|
|
2503
|
+
if (!$pathStep.args) $pathStep.args = [];
|
|
2504
|
+
this['$'+'genericKeywords'] = this.genericFunctionsStack.pop();
|
|
2505
|
+
}
|
|
2551
2506
|
|
|
2552
|
-
namedExpression[ pathStep ]
|
|
2507
|
+
namedExpression[ pathStep, id ]
|
|
2553
2508
|
:
|
|
2554
|
-
|
|
2555
|
-
{ if ($pathStep && $
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
$pathStep['$'+'syntax'] = ':';
|
|
2509
|
+
elem=expression
|
|
2510
|
+
{ if ($pathStep && $id) {
|
|
2511
|
+
this.addDef( ($ctx.elem) ? $elem.expr : { location: $id.location },
|
|
2512
|
+
$pathStep, 'args', 0, $id );
|
|
2559
2513
|
}
|
|
2560
2514
|
}
|
|
2561
2515
|
;
|
|
2562
2516
|
|
|
2563
|
-
|
|
2564
|
-
:
|
|
2565
|
-
name=ident['paramname'] a='=>' elem=expression
|
|
2566
|
-
{ if ($name.id) this.addDef( $pathStep, 'args', 0, $name.id, true,
|
|
2567
|
-
($ctx.elem) ? $elem.expr : { location: $name.id.location } ); }
|
|
2568
|
-
;
|
|
2569
|
-
|
|
2570
|
-
funcExpression[ pathStep, considerSpecial ]
|
|
2517
|
+
funcExpression[ pathStep, considerSpecial ] locals[ args ]
|
|
2571
2518
|
@init { this.prepareGenericKeywords( $considerSpecial ); }
|
|
2572
2519
|
:
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2520
|
+
(
|
|
2521
|
+
expr=expression
|
|
2522
|
+
{ $pathStep.args.push( $expr.expr ); }
|
|
2523
|
+
|
|
|
2524
|
+
GenericExpr // keyword as replacement for expression, like '*'
|
|
2525
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2526
|
+
|
|
|
2527
|
+
GenericIntro // keyword as introduction of expression, like DISTINCT
|
|
2528
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2529
|
+
expr=expression
|
|
2530
|
+
{ $args = this.setLastAsXpr( $pathStep.args );
|
|
2531
|
+
$args.push( $expr.expr ); }
|
|
2532
|
+
|
|
|
2533
|
+
// Rule 'pathArguments' makes a decision based on the first two lookahead
|
|
2534
|
+
// tokens of this rule → we need to list tokens which would be changed to
|
|
2535
|
+
// GenericExpr or GenericIntro, and are not already covered by 'expression'
|
|
2536
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2537
|
+
( HideAlternatives | '*' | ALL | DISTINCT )
|
|
2538
|
+
// now continue parsing like GenericExpr:
|
|
2539
|
+
{ $pathStep.args.push( this.xprToken() ); }
|
|
2540
|
+
)
|
|
2541
|
+
(
|
|
2542
|
+
{ if (!$args) $args = this.setLastAsXpr( $pathStep.args ); }
|
|
2543
|
+
(
|
|
2544
|
+
{ this.prepareGenericKeywords( $considerSpecial, 'separator' ); }
|
|
2545
|
+
(
|
|
2546
|
+
GenericSeparator
|
|
2547
|
+
|
|
|
2548
|
+
// For ANTLR's lookahead calculations, we need to list tokens here
|
|
2549
|
+
// which could be changed to GenericSeparator. Do not invent a
|
|
2550
|
+
// keyword token which is just used here (Identifier does work
|
|
2551
|
+
// perfectly)! If we want, we could add all non-reserved keywords
|
|
2552
|
+
// except ORDER, and most reserved.
|
|
2553
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2554
|
+
( HideAlternatives | Identifier | FROM | IN | WITH | GROUP )
|
|
2555
|
+
)
|
|
2556
|
+
{ $args.push( this.xprToken() );
|
|
2557
|
+
this.prepareGenericKeywords( $considerSpecial, 'expr' );
|
|
2558
|
+
}
|
|
2559
|
+
(
|
|
2560
|
+
expr=expression
|
|
2561
|
+
{ $args.push( $expr.expr ); }
|
|
2562
|
+
|
|
|
2563
|
+
GenericExpr
|
|
2564
|
+
{ $args.push( this.xprToken() ); }
|
|
2565
|
+
|
|
|
2566
|
+
{ this.reportErrorForGenericKeyword(); }
|
|
2567
|
+
// Again, we need to list tokens which could make it to GenericExpr
|
|
2568
|
+
// and which do not start an expression
|
|
2569
|
+
( HideAlternatives | ALL )
|
|
2570
|
+
{ $args.push( this.xprToken() ); }
|
|
2571
|
+
)
|
|
2572
|
+
)+
|
|
2573
|
+
)?
|
|
2578
2574
|
;
|
|
2579
2575
|
|
|
2580
2576
|
cardinalityAndFilter[ pathStep ] locals [ _sync = 'nop' ]
|
|
@@ -2616,32 +2612,41 @@ optionalWhereForFilter
|
|
|
2616
2612
|
|
|
2617
2613
|
// Simple paths and values ---------------------------------------------------
|
|
2618
2614
|
|
|
2619
|
-
|
|
2620
|
-
@after { this.attachLocation($val); }
|
|
2615
|
+
annoValue[ assignment ]
|
|
2621
2616
|
:
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2617
|
+
base=annoValueBase[ $assignment ]
|
|
2618
|
+
|
|
|
2619
|
+
// no docComment() here
|
|
2620
|
+
// this alternative is done with token rewrite in rule "annotationAssignment_atn"
|
|
2621
|
+
at='@'? annotationPath[ $assignment, 'ref', $at ]
|
|
2622
|
+
annotationPathVariant[ $assignment ]?
|
|
2623
|
+
;
|
|
2624
|
+
|
|
2625
|
+
annoValueBase[ assignment ] locals [ seenEllipsis = false ]
|
|
2626
|
+
@after { this.attachLocation( $assignment ); }
|
|
2627
|
+
:
|
|
2628
|
+
'{' // no location here, we flatten
|
|
2629
|
+
{ $assignment['$'+'flatten'] = []; this.meltKeywordToIdentifier(); }
|
|
2630
|
+
flattenedValue[ $assignment ]
|
|
2626
2631
|
(
|
|
2627
2632
|
',' {
|
|
2628
2633
|
this.meltKeywordToIdentifier();
|
|
2629
2634
|
if (this.isStraightBefore("}")) break; // allow ',' before ')'
|
|
2630
2635
|
}
|
|
2631
|
-
|
|
2636
|
+
flattenedValue[ $assignment ]
|
|
2632
2637
|
)*
|
|
2633
2638
|
'}'
|
|
2634
2639
|
|
|
|
2635
|
-
|
|
2636
|
-
|
|
2640
|
+
'[' // no need for createArray() here, $assignment.location is set
|
|
2641
|
+
{ $assignment.val = []; $assignment.literal = 'array'; }
|
|
2637
2642
|
(
|
|
2638
2643
|
(
|
|
2639
|
-
head=
|
|
2644
|
+
head=annoSubValue { $assignment.val.push( $head.val ); }
|
|
2640
2645
|
|
|
|
2641
|
-
e='...' ( UP TO upTo=
|
|
2646
|
+
e='...' ( UP TO upTo=annoSubValue )?
|
|
2642
2647
|
{{
|
|
2643
2648
|
const item = { literal: 'token', val: '...', location: this.tokenLocation($e) };
|
|
2644
|
-
$
|
|
2649
|
+
$assignment.val.push( item );
|
|
2645
2650
|
if ($ctx.upTo) item.upTo = $upTo.val;
|
|
2646
2651
|
$seenEllipsis = !$ctx.upTo || 'upTo';
|
|
2647
2652
|
}}
|
|
@@ -2649,17 +2654,16 @@ annoValueBase returns[ val ] locals [ seenEllipsis = false ]
|
|
|
2649
2654
|
(
|
|
2650
2655
|
',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
|
|
2651
2656
|
(
|
|
2652
|
-
tail=
|
|
2657
|
+
tail=annoSubValue { $assignment.val.push( $tail.val ); }
|
|
2653
2658
|
|
|
|
2654
2659
|
{ $ctx.upTo = null; } // is not reset
|
|
2655
|
-
e='...' ( UP TO upTo=
|
|
2660
|
+
e='...' ( UP TO upTo=annoSubValue )?
|
|
2656
2661
|
{{
|
|
2657
2662
|
const item = { literal: 'token', val: '...', location: this.tokenLocation($e) };
|
|
2658
2663
|
if ($ctx.upTo) item.upTo = $upTo.val;
|
|
2659
|
-
$
|
|
2664
|
+
$assignment.val.push( item );
|
|
2660
2665
|
if ($seenEllipsis === true) // TODO: adapt msg to UP TO
|
|
2661
|
-
this.error( 'syntax-unexpected-ellipsis', $e, { code: '...' }
|
|
2662
|
-
'Expected no more than one $(CODE)' );
|
|
2666
|
+
this.error( 'syntax-unexpected-ellipsis', $e, { '#': 'std', code: '...' } );
|
|
2663
2667
|
else
|
|
2664
2668
|
$seenEllipsis = !$ctx.upTo || 'upTo';
|
|
2665
2669
|
}}
|
|
@@ -2674,67 +2678,66 @@ annoValueBase returns[ val ] locals [ seenEllipsis = false ]
|
|
|
2674
2678
|
'Expecting an array item $(NEWCODE) after an item with $(CODE)' );
|
|
2675
2679
|
}
|
|
2676
2680
|
|
|
|
2677
|
-
v1=literalValue { $
|
|
2681
|
+
v1=literalValue { Object.assign( $assignment, $v1.val ); }
|
|
2678
2682
|
|
|
|
2679
2683
|
( plus='+' | min='-' ) num=Number
|
|
2680
|
-
{ $
|
|
2684
|
+
{ Object.assign( $assignment, this.numberLiteral( $num, $plus||$min ) ); }
|
|
2681
2685
|
;
|
|
2682
2686
|
|
|
2683
|
-
|
|
2687
|
+
flattenedValue[ assignment ] locals[ val = { name: {} } ]
|
|
2684
2688
|
:
|
|
2685
|
-
|
|
2686
|
-
|
|
|
2687
|
-
{ $val = {}; } // TODO: think about expression value representation
|
|
2688
|
-
at='@'? annotationPath[ $val, 'ref', $at ]
|
|
2689
|
-
annotationPathVariant[ $val ]?
|
|
2690
|
-
;
|
|
2691
|
-
|
|
2692
|
-
namedValue[ struct ] locals[ namedVal = { name: {} } ]
|
|
2693
|
-
:
|
|
2694
|
-
at='@'? annotationPath[ $namedVal.name, 'name', $at ]
|
|
2689
|
+
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2695
2690
|
(
|
|
2696
2691
|
'#' { this.meltKeywordToIdentifier(); }
|
|
2697
|
-
variant=ident['variant'] { $
|
|
2692
|
+
variant=ident['variant'] { $val.name.variant = $variant.id; }
|
|
2698
2693
|
)?
|
|
2699
2694
|
(
|
|
2700
2695
|
':' { this.meltKeywordToIdentifier(true); } // allow path as anno value start with reserved
|
|
2701
|
-
|
|
2696
|
+
annoValue[ $val ]
|
|
2702
2697
|
)?
|
|
2703
|
-
{
|
|
2704
|
-
|
|
2698
|
+
{ $assignment['$'+'flatten'].push( $val ); }
|
|
2699
|
+
;
|
|
2700
|
+
|
|
2701
|
+
namedValue[ struct ] locals[ val = { name: {} } ]
|
|
2702
|
+
:
|
|
2703
|
+
at='@'? annotationPath[ $val.name, 'name', $at ]
|
|
2704
|
+
( ':' sub=annoSubValue { Object.assign( $val, $sub.val ); } )?
|
|
2705
|
+
{
|
|
2706
|
+
if (!$val.location) $val.location = $val.name.location;
|
|
2707
|
+
this.addDef( $val, $struct, 'struct', null, $val.name ); // TODO: re-check name
|
|
2708
|
+
}
|
|
2705
2709
|
;
|
|
2706
2710
|
|
|
2707
|
-
|
|
2711
|
+
annoSubValue returns[ val = {} ]
|
|
2708
2712
|
@after { this.attachLocation($val); }
|
|
2709
2713
|
:
|
|
2710
|
-
{
|
|
2711
|
-
|
|
2714
|
+
'{' // no need for createDict() here, $val.location is set
|
|
2715
|
+
{ $val.struct = Object.create(null); $val.literal = 'struct'; }
|
|
2712
2716
|
{ this.meltKeywordToIdentifier(); }
|
|
2713
|
-
|
|
2717
|
+
namedValue[ $val ]
|
|
2714
2718
|
( ','
|
|
2715
2719
|
{
|
|
2716
2720
|
this.meltKeywordToIdentifier();
|
|
2717
2721
|
if (this.isStraightBefore("}")) break; // allow ',' before '}'
|
|
2718
2722
|
}
|
|
2719
|
-
|
|
2723
|
+
namedValue[ $val ]
|
|
2720
2724
|
)*
|
|
2721
2725
|
'}'
|
|
2722
2726
|
|
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
( head=
|
|
2727
|
+
'[' // no need for createArray() here, $val.location is set
|
|
2728
|
+
{ $val.val = []; $val.literal = 'array'; }
|
|
2729
|
+
( head=annoSubValue { $val.val.push( $head.val ); }
|
|
2726
2730
|
( ',' { if (this.isStraightBefore(']')) break; } // allow ',' before ']'
|
|
2727
|
-
tail=
|
|
2731
|
+
tail=annoSubValue { $val.val.push( $tail.val ); }
|
|
2728
2732
|
)*
|
|
2729
2733
|
)?
|
|
2730
2734
|
']'
|
|
2731
2735
|
|
|
|
2732
|
-
v1=literalValue { $val
|
|
2736
|
+
v1=literalValue { Object.assign( $val, $v1.val ); }
|
|
2733
2737
|
|
|
|
2734
2738
|
( plus='+' | min='-' ) num=Number
|
|
2735
|
-
{ $val
|
|
2739
|
+
{ Object.assign( $val, this.numberLiteral( $num, $plus||$min ) ); }
|
|
2736
2740
|
|
|
|
2737
|
-
{ $val = {}; } // TODO: think about expression value representation
|
|
2738
2741
|
at='@'? annotationPath[ $val, 'ref', $at ]
|
|
2739
2742
|
(
|
|
2740
2743
|
'#' { this.meltKeywordToIdentifier(); }
|
|
@@ -2742,14 +2745,6 @@ arrayValue returns[ val ]
|
|
|
2742
2745
|
)?
|
|
2743
2746
|
;
|
|
2744
2747
|
|
|
2745
|
-
namedValueInArray[ struct ] locals[ name = {} ]
|
|
2746
|
-
:
|
|
2747
|
-
at='@'? annotationPath[ $name, 'name', $at ]
|
|
2748
|
-
( ':' elem=arrayValue )?
|
|
2749
|
-
{ this.addDef( $struct, 'struct', null, $name, true,
|
|
2750
|
-
($ctx.elem) ? $elem.val : { location: $name.location } ); }
|
|
2751
|
-
;
|
|
2752
|
-
|
|
2753
2748
|
literalValue returns[ val ] locals[ tok ]
|
|
2754
2749
|
@init{ $tok = this.getCurrentToken(); }
|
|
2755
2750
|
@after { this.attachLocation($val); }
|
|
@@ -2808,7 +2803,7 @@ annotationPath[ art, category, headat = null ] locals[ _sync = 'nop' ]
|
|
|
2808
2803
|
annotationPathVariant[ art ]
|
|
2809
2804
|
@after { this.attachLocation($art); }
|
|
2810
2805
|
:
|
|
2811
|
-
// TODO: warning for space
|
|
2806
|
+
// TODO: warning for space after '#'
|
|
2812
2807
|
'#' { this.meltKeywordToIdentifier(); }
|
|
2813
2808
|
variant=ident['variant'] { $art.variant = $variant.id; }
|
|
2814
2809
|
;
|
|
@@ -2839,13 +2834,11 @@ ident[ category ] returns[ id ]
|
|
|
2839
2834
|
| ASPECT
|
|
2840
2835
|
| ASSOCIATION
|
|
2841
2836
|
| BETWEEN
|
|
2842
|
-
| BOTH
|
|
2843
2837
|
| COLUMNS
|
|
2844
2838
|
| COMPOSITION
|
|
2845
2839
|
| CONTEXT
|
|
2846
2840
|
| CROSS
|
|
2847
2841
|
| CURRENT
|
|
2848
|
-
| DAY
|
|
2849
2842
|
| DEFAULT
|
|
2850
2843
|
| DEFINE
|
|
2851
2844
|
| DEFINITIONS
|
|
@@ -2869,14 +2862,12 @@ ident[ category ] returns[ id ]
|
|
|
2869
2862
|
| FUNCTION
|
|
2870
2863
|
| GROUP
|
|
2871
2864
|
| HAVING
|
|
2872
|
-
| HOUR
|
|
2873
2865
|
| INNER
|
|
2874
2866
|
| INTERSECT
|
|
2875
2867
|
| INTO
|
|
2876
2868
|
| IS
|
|
2877
2869
|
| JOIN
|
|
2878
2870
|
| LAST
|
|
2879
|
-
| LEADING
|
|
2880
2871
|
| LEFT
|
|
2881
2872
|
| LIKE
|
|
2882
2873
|
| LIMIT
|
|
@@ -2884,9 +2875,7 @@ ident[ category ] returns[ id ]
|
|
|
2884
2875
|
| MANY
|
|
2885
2876
|
| MASKED
|
|
2886
2877
|
| MINUS
|
|
2887
|
-
| MINUTE
|
|
2888
2878
|
| MIXIN
|
|
2889
|
-
| MONTH
|
|
2890
2879
|
| NAMESPACE
|
|
2891
2880
|
| NULLS
|
|
2892
2881
|
| OFFSET
|
|
@@ -2903,10 +2892,8 @@ ident[ category ] returns[ id ]
|
|
|
2903
2892
|
| RIGHT
|
|
2904
2893
|
| ROW
|
|
2905
2894
|
| ROWS
|
|
2906
|
-
| SECOND
|
|
2907
2895
|
| SERVICE
|
|
2908
2896
|
| THEN
|
|
2909
|
-
| TRAILING
|
|
2910
2897
|
| UNION
|
|
2911
2898
|
| UP
|
|
2912
2899
|
| TO
|
|
@@ -2915,7 +2902,6 @@ ident[ category ] returns[ id ]
|
|
|
2915
2902
|
| UNBOUNDED
|
|
2916
2903
|
| VARIABLE
|
|
2917
2904
|
| VIEW
|
|
2918
|
-
| YEAR
|
|
2919
2905
|
;
|
|
2920
2906
|
|
|
2921
2907
|
//----------------------------------------------------------------------------
|
|
@@ -3007,7 +2993,6 @@ CASE : [cC][aA][sS][eE] ;
|
|
|
3007
2993
|
CAST : [cC][aA][sS][tT] ;
|
|
3008
2994
|
DISTINCT : [dD][iI][sS][tT][iI][nN][cC][tT] ;
|
|
3009
2995
|
EXISTS : [eE][xX][iI][sS][tT][sS] ;
|
|
3010
|
-
EXTRACT : [eE][xX][tT][rR][aA][cC][tT] ;
|
|
3011
2996
|
// FALSE: see Boolean
|
|
3012
2997
|
FROM : [fF][rR][oO][mM] ;
|
|
3013
2998
|
IN : [iI][nN] ;
|
|
@@ -3020,7 +3005,6 @@ ON : [oO][nN] ;
|
|
|
3020
3005
|
SELECT : [sS][eE][lL][eE][cC][tT] ;
|
|
3021
3006
|
SOME : [sS][oO][mM][eE] ;
|
|
3022
3007
|
WHEN : [wW][hH][eE][nN] ;
|
|
3023
|
-
TRIM : [tT][rR][iI][mM] ;
|
|
3024
3008
|
// TRUE: see Boolean
|
|
3025
3009
|
WHERE : [wW][hH][eE][rR][eE] ;
|
|
3026
3010
|
WITH : [wW][iI][tT][hH] ;
|
|
@@ -3034,6 +3018,7 @@ Number // DO NOT RENAME OR MOVE THIS RULE !!!
|
|
|
3034
3018
|
;
|
|
3035
3019
|
|
|
3036
3020
|
// Unreserved keywords (are case-insensitive): -------------------------------
|
|
3021
|
+
// Do not add keywords just for specialFunctions!
|
|
3037
3022
|
|
|
3038
3023
|
ABSTRACT : [aA][bB][sS][tT][rR][aA][cC][tT] ;
|
|
3039
3024
|
ACTION : [aA][cC][tT][iI][oO][nN] ;
|
|
@@ -3046,13 +3031,11 @@ ASC : [aA][sS][cC] ;
|
|
|
3046
3031
|
ASPECT : [aA][sS][pP][eE][cC][tT] ;
|
|
3047
3032
|
ASSOCIATION : [aA][sS][sS][oO][cC][iI][aA][tT][iI][oO][nN] ;
|
|
3048
3033
|
BETWEEN : [bB][eE][tT][wW][eE][eE][nN] ;
|
|
3049
|
-
BOTH : [bB][oO][tT][hH] ;
|
|
3050
3034
|
COLUMNS : [cC][oO][lL][uU][mM][nN][sS];
|
|
3051
3035
|
COMPOSITION : [cC][oO][mM][pP][oO][sS][iI][tT][iI][oO][nN] ;
|
|
3052
3036
|
CONTEXT : [cC][oO][nN][tT][eE][xX][tT] ;
|
|
3053
3037
|
CROSS : [cC][rR][oO][sS][sS] ;
|
|
3054
3038
|
CURRENT : [cC][uU][rR][rR][eE][nN][tT] ;
|
|
3055
|
-
DAY : [dD][aA][yY] ;
|
|
3056
3039
|
DEFAULT : [dD][eE][fF][aA][uU][lL][tT] ;
|
|
3057
3040
|
DEFINE : [dD][eE][fF][iI][nN][eE] ;
|
|
3058
3041
|
DEFINITIONS : [dD][eE][fF][iI][nN][iI][tT][iI][oO][nN][sS] ;
|
|
@@ -3076,14 +3059,12 @@ FULL : [fF][uU][lL][lL] ;
|
|
|
3076
3059
|
FUNCTION : [fF][uU][nN][cC][tT][iI][oO][nN] ;
|
|
3077
3060
|
GROUP : [gG][rR][oO][uU][pP] ;
|
|
3078
3061
|
HAVING : [hH][aA][vV][iI][nN][gG] ;
|
|
3079
|
-
HOUR : [hH][oO][uU][rR] ;
|
|
3080
3062
|
INNER : [iI][nN][nN][eE][rR] ;
|
|
3081
3063
|
INTERSECT : [iI][nN][tT][eE][rR][sS][eE][cC][tT] ;
|
|
3082
3064
|
INTO : [iI][nN][tT][oO] ;
|
|
3083
3065
|
IS : [iI][sS] ;
|
|
3084
3066
|
JOIN : [jJ][oO][iI][nN] ;
|
|
3085
3067
|
LAST : [lL][aA][sS][tT] ;
|
|
3086
|
-
LEADING : [lL][eE][aA][dD][iI][nN][gG] ;
|
|
3087
3068
|
LEFT : [lL][eE][fF][tT] ;
|
|
3088
3069
|
LIKE : [lL][iI][kK][eE] ;
|
|
3089
3070
|
LIMIT : [lL][iI][mM][iI][tT] ;
|
|
@@ -3091,9 +3072,7 @@ LOCALIZED: [lL][oO][cC][aA][lL][iI][zZ][eE][dD];
|
|
|
3091
3072
|
MANY : [mM][aA][nN][yY] ;
|
|
3092
3073
|
MASKED : [mM][aA][sS][kK][eE][dD] ;
|
|
3093
3074
|
MINUS : [mM][iI][nN][uU][sS] ;
|
|
3094
|
-
MINUTE : [mM][iI][nN][uU][tT][eE] ;
|
|
3095
3075
|
MIXIN : [mM][iI][xX][iI][nN] ;
|
|
3096
|
-
MONTH : [mM][oO][nN][tT][hH] ;
|
|
3097
3076
|
NAMESPACE : [nN][aA][mM][eE][sS][pP][aA][cC][eE] ;
|
|
3098
3077
|
NULLS : [nN][uU][lL][lL][sS] ;
|
|
3099
3078
|
OFFSET : [oO][fF][fF][sS][eE][tT] ;
|
|
@@ -3111,10 +3090,8 @@ RETURNS : [rR][eE][tT][uU][rR][nN][sS] ;
|
|
|
3111
3090
|
RIGHT : [rR][iI][gG][hH][tT] ;
|
|
3112
3091
|
ROW : [rR][oO][wW] ;
|
|
3113
3092
|
ROWS : [rR][oO][wW][sS] ;
|
|
3114
|
-
SECOND : [sS][eE][cC][oO][nN][dD] ;
|
|
3115
3093
|
SERVICE : [sS][eE][rR][vV][iI][cC][eE] ;
|
|
3116
3094
|
THEN : [tT][hH][eE][nN] ;
|
|
3117
|
-
TRAILING : [tT][rR][aA][iI][lL][iI][nN][gG] ;
|
|
3118
3095
|
TO : [tT][oO] ; // or make reserved? (is in SQL-92)
|
|
3119
3096
|
TYPE : [tT][yY][pP][eE] ;
|
|
3120
3097
|
UNION : [uU][nN][iI][oO][nN] ;
|
|
@@ -3124,7 +3101,6 @@ USING : [uU][sS][iI][nN][gG] ;
|
|
|
3124
3101
|
VARIABLE : [vV][aA][rR][iI][aA][bB][lL][eE] ;
|
|
3125
3102
|
VIEW : [vV][iI][eE][wW] ;
|
|
3126
3103
|
// VIRTUAL: [vV][iI][rR][tT][uU][aA][lL] ; see tokens {}
|
|
3127
|
-
YEAR : [yY][eE][aA][rR] ;
|
|
3128
3104
|
|
|
3129
3105
|
// Identifiers, must BE LAST, DIRECTLY AFTER the unreserved keywords ---------
|
|
3130
3106
|
|