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