Issue 10646: Missing explanations in BNF (qvt-rtf) Source: Model Driven Solutions (Dr. Edward Willink, ed(at)willink.me.uk) Nature: Uncategorized Issue Severity: Summary: The OCL 2.0 spec has a 32 page section on concrete semantics. QVTr has 1.5 pages of BNF but no explanation. In particular: What are the semantics of 'import' which has no abstract counterpart? Where is the explanation of the role of [ '{' <oclExpressionCS> '}' ] in a <domain>? Where is the instruction on how to treat the "_" identifier? Resolution: Revised Text: Add a sub-section in section 7.13 with the following content: The mapping is specified using attribute grammar similar to how OCL' concrete to abstract syntax mapping is specified. topLevelCS topLevelCS ::= importListCS? transformationListCS? Abstract syntax mapping topLevelCS.ast : Set(RelationalTransformation) Synthesized attributes topLevelCS.ast = TransformationListCS.ast Inherited attributes transformationListCS.env = if (importListCS.ast.notEmpty()) then Environment.EMPTY_ENV.addElement('imported transformation', importListCS.ast) else Environment.EMPTY_ENV endif importListCS importListCS[1] ::= 'import' unitCS ';' importListCS[2]? Abstract syntax mapping importListCS[1].ast : Set(RelationalTransformation) Synthesized attributes importListCS[1].ast = unitCS.ast->union(importListCS[2].ast) unitCS unitCS ::= identifierCS ('.' identifierCS)* Abstract syntax mapping unitCS.ast : Set(RelationalTransformation) Synthesized attributes <left unspecified> The dot separated identifiers identify a compilation unit that is expected to contain transformation specifications. As explained in section 7.13.1 of the spec, how the dot separated identifiers are mapped to, say, a file system hierarchy is implementation specific. transformationListCS transformationListCS[1] ::= transformationCS transformationListCS[2]? Abstract syntax mapping transformationListCS[1].ast : Set(RelationalTransformation) Synthesized attributes transformationListCS[1].ast = Set{transformationCS.ast}->union(transformationListCS[2].ast) Inherited attributes transformationCS[1].env = transformationListCS[1].env transformationListCS[2].env = transformationListCS[1].env transformationCS transformationCS ::= 'transformation' identifierCS[1] '(' modelDeclListCS ')' ('extends' identifierCS[2])? '{' keyDeclListCS? relQueryListCS? '}' Abstract syntax mapping transformationCS.ast : RelationalTransformation Synthesized attributes transformationCS.ast.name = identifierCS[1].ast transformationCS.ast.modelParameter = modelDeclListCS.ast if (not identifierCS[2].ast.oclIsUndefined()) then transformationCS.ast.extends = let importedTransformationSet:Set(RelationalTransformation) = transformationCS.env.lookup('imported transformations').referredElement.oclAsType(SetType) in importedTransformationSet->any(t | t.name = identifierCS[2].ast) endif transformationCS.ast.rule = relQueryListCS->select(r | r.OclIsTypeOf(Relation)) transformationCS.ast.ownedOperation = relQueryListCS->select(r | r.OclIsTypeOf(Function)) transformationCS.ast.ownedKey = keyDeclListCS.ast Inherited attributes identifierCS[1].env = transformationCS.env modelDeclListCS.env = transformationCS.env identifierCS[2].env = transformationCS.env let env:Environment = transformationCS.env.addElement('context transformation', transformationCS.ast) in keyDeclListCS.env = env and relQueryListCS.env = env modelDeclListCS modelDeclListCS[1] ::= modelDeclCS (',' modelDeclListCS[2])? Abstract syntax mapping modelDeclListCS[1].ast : Sequence(TypedModel) Synthesized attributes modelDeclListCS[1].ast = Sequence{modelDeclCS.ast}->union(modelDeclListCS[2].ast) Inherited attributes modelDeclCS.env = modelDeclListCS[1].env modelDeclListCS[2].env = modelDeclListCS[1].env keyDeclListCS keyDeclListCS[1] ::= keyDeclCS keyDeclListCS[2]? Abstract syntax mapping keyDeclListCS[1].ast : Set(Key) Synthesized attributes keyDeclListCS[1].ast = Set{keyDeclCS.ast}->union(keyDeclListCS[2].ast) Inherited attributes keyDeclCS.env = keyDeclListCS[1].env keyDeclListCS[2].env = keyDeclListCS[1].env relQueryListCS relQueryListCS[1] ::= relQueryCS relQueryListCS[2]? Abstract syntax mapping relQueryListCS[1].ast : Set(ModelElement) Synthesized attributes relQueryListCS[1].ast = Set{relQueryCS.ast}->union(relQueryListCS[2].ast) Inherited attributes relQueryCS.env = relQueryListCS[1].env relQueryListCS[2].env = relQueryListCS[1].env relQueryCS [A] relQueryCS ::= relationCS [B] relQueryCS ::= queryCS Abstract syntax mapping relQueryCS.ast : ModelElement Synthesized attributes [A] relQueryCS.ast = relationCS.ast [B] relQueryCS.ast = queryCS.ast Inherited attributes [A] relationCS.env = relQueryCS.env [B] queryCS.env = relQueryCS.env modelDeclCS modelDeclCS ::= modelIdCS ':' metaModelIdCS Abstract syntax mapping modelDeclCS.ast : TypedModel Synthesized attributes modelDeclCS.ast.name = modelIdCS.ast modelDeclCS.ast.usedPackage = metaModelIdCS.ast Inherited attributes modelIdCS.env = modelDeclCS.env metaModelIdCS.env = modelDeclCS.env modelIdCS modelIdCS ::= identifierCS Abstract syntax mapping modelIdCS.ast : String Synthesized attributes modelIdCS.ast = identifierCS.ast metaModelIdCS metaModelIdCS ::= identifierCS Abstract syntax mapping metaModelIdCS.ast : Package Synthesized attributes metaModelIdCS.ast = loadMetaModelPackage(identifierCS.ast) // How the package is located and loaded is tool specific and so left unspecified. keyDeclCS keyDeclCS ::= 'key' classIdCS '{' keyPropertyListCS '}' ';' Abstract syntax mapping keyDeclCS.ast : Key Synthesized attributes keyDeclCS.ast.identifies = classIdCS.ast keyDeclCS.ast.part->union(keyDeclCS.ast.oppositePart) = keyPropertyListCS.ast Inherited attributes classIdCS.env = keyDeclCS.env keyPropertyListCS.env = keyDeclCS.env.addElement('context key', keyDeclCS.ast) keyPropertyListCS keyPropertyListCS[1] ::= keyPropertyCS (',' keyPropertyListCS[2])? Abstract syntax mapping keyPropertyListCS[1].ast : Set(Property) Synthesized attributes keyPropertyListCS[1].ast : Set{keyPropertyCS.ast}->union(keyPropertyListCS[2].ast) Inherited attributes keyPropertyCS.env = keyPropertyListCS[1].env keyPropertyListCS[2].env = keyPropertyListCS[1].env classIdCS classIdCS ::= pathNameCS Abstract syntax mapping classIdCS.ast : Class Synthesized attributes classIdCS.ast = let trans:RelationalTransformation = classIdCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) in trans.lookupClassName(pathNameCS.ast) keyPropertyCS [A] keyPropertyCS ::= identifierCS [B] keyPropertyCS ::= 'opposite' '(' classIdCS '.' identifierCS ')' Abstract syntax mapping: keyPropertyCS.ast : Property Synthesized attributes: [A] keyPropertyCS.ast = let cls:Class = keyPropertyCS.env.lookup('context key'). referredElement.oclAsType(Key).identifies in cls.lookupProperty(identifierCS.ast) keyPropertyCS.env.lookup('context key').referredElement.oclAsType(Key). part->includes(keyPropertyCS.ast) [B] keyPropertyCS.ast = classIdCS.ast.lookupProperty(identifierCS.ast) keyPropertyCS.env.lookup('context key').referredElement.oclAsType(Key). oppositePart->includes(keyPropertyCS.ast) Inherited attributes: [B] classIdCS.env = keyPropertyCS.env relationCS relationCS ::= topQualifierCS? 'relation' identifierCS[1] ('overrides' identifierCS[2])? '{' varDeclListCS? domainListCS whenCS? whereCS? '}' Abstract syntax mapping relationCS.ast : Relation Synthesized attributes relationCS.ast.isTopLevel = if (not topQualifierCS.ast.oclIsUndefined() and topQualifierCS.ast = 'top') then true else false endif relationCS.ast.name = identifierCS[1].ast if (not identifierCS[2].ast.oclIsUndefined()) then relationCS.ast.overrides = let currTrans:RelationTransformation = relationCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) in currTrans.extends.rule->any(r | r.name = identifierCS[2].ast) endif relationCS.ast.variable = varDeclListCS.ast->union( domainListCS->iterate(d:RelationDomain; domainVars:Set(Variable)={} | domainVars->including(d.rootVariable)) ) relationCS.ast.domain = domainListCS.ast relationCS.ast.when = whenCS.ast relationCS.ast.where = whereCS.ast Inherited attributes let env:Environment = relationCS.env.addElement('context relation', relationCS.ast) in varDeclListCS.env = env domainListCS.env = env whenCS.env = env whereCS.env = env topQualifierCS topQualifierCS ::= 'top' Abstract syntax mapping topQualifierCS.ast : String Synthesized attributes topQualifierCS.ast = 'top' varDeclListCS varDeclListCS[1] ::= varDeclarationCS varDeclListCS[2]? Abstract syntax mapping varDeclListCS[1].ast : Set(Variable) Synthesized attributes varDeclListCS[1].ast ::= varDeclarationCS.ast->union(varDeclListCS[2].ast) Inherited attributes varDeclarationCS.env = varDeclListCS[1].env varDeclListCS[2].env = varDeclListCS[1].env varDeclarationCS varDeclarationCS ::= varListCS ':' TypeCS ';' Abstract syntax mapping varDeclarationCS.ast : Set(Variable) Synthesized attributes varDeclarationCs.ast->size() = varListCS.ast->size() varListCS.ast->forAll(vn | varDeclarationCS.ast->exists(v | v.name = vn and v.type = TypeCS.ast) ) Inherited attributes TypeCS.env = varDeclarationCS.env varListCS varListCS[1] ::= identifierCS (',' varListCS[2])? Abstract syntax mapping varListCS[1].ast : Set(String) Synthesized attributes varListCS[1].ast : Set{identifierCS.ast}->union(varListCS[2].ast) domainListCS domainListCS[1] ::= domainCS domainListCS[2]? Abstract syntax mapping domainListCS[1].ast : Sequence(RelationDomain) Synthesized attributes domainListCS[1].ast = Sequence{domainCS.ast}->union(domainListCS[2].ast) Inherited attributes domainCS.env = domainListCS[1].env domainListCS[2].env = domainListCS[1].env domainCS domainCS[A] ::= modelDomainCS domainCS[B] ::= primitiveDomainCS Abstract syntax mapping domainCS.ast : RelationDomain Synthesized attributes [A] domainCS.ast = modelDomainCS.ast [B] domainCS.ast = primitiveDomainCS.ast Inherited attributes [A] modelDomainCS.env = domainCS.env [B] primitiveDomainCS.env = domainCS.env modelDomainCS modelDomainCS ::= checkEnforceQualifierCS? 'domain' modelIdCS templateCS ('implementedby' OperationCallExpCS)? ('default_values' '{' assignmentExpListCS '}')? ';' Abstract syntax mapping modelDomainCS.ast : RelationDomain Synthesized attributes if (checkEnforceQualifierCS.ast.oclIsUndefined()) then modelDomainCS.ast.isCheckable = false and modelDomainCS.ast.isEnforceable = false else if (checkEnforceQualifierCS.ast = 'checkonly') then modelDomainCS.ast.isCheckable = true and modelDomainCS.ast.isEnforceable = false else modelDomainCS.ast.isCheckable = true and modelDomainCS.ast.isEnforceable = true endif endif modelDomainCS.ast.typedModel = modelDomainCS.env.lookup('context transformation').modelParameter-> any(t | t.name = modelIdCS.ast) modelDomainCS.ast.pattern.templateExpression = templateCS.ast modelDomainCS.ast.rootVariable = templateCS.ast.bindsTo if (not OperationCallExpCS.ast.oclIsUndefined()) then let rel:Relation = modelDomainCS.env.lookup('context relation'). referredElement.oclAsType(Relation) in rel.operationalImpl.impl = OperationCallExpCS.ast.referredOperation and rel.operationalImpl.inDirectionOf = modelDomainCS.ast.typedModel endif if (assignmentExpListCS.ast.notEmpty()) then modelDomainCS.ast.defaultAssignment = assignmentExpListCS.ast endif Inherited attributes let env:Environment = modelDomainCS.env.addElement('context domain', modelDomainCS.ast) in templateCS.env = env OperationCallExpCS.env = env assignmentExpListCS.env = env primitiveTypeDomainCS primitiveTypeDomainCS ::= 'primitive' 'domain' identifierCS ':' TypeCS ';' Abstract syntax mapping primitiveTypeDomainCS.ast : RelationDomain Synthesized attributes primitiveTypeDomainCS.ast.rootVariable.name = identifierCS.ast primitiveTypeDomainCS.ast.rootVariable.type = TypeCS.ast Inherited attributes TypeCS.env = primitiveTypeDomainCS.env checkEnforceQualifierCS [A] checkEnforceQualifierCS ::= 'checkonly' [B] checkEnforceQualifierCS ::= 'enforce' Abstract syntax mapping checkEnforceQualifierCS.ast : String Synthesized attributes [A] checkEnforceQualifierCS.ast = 'checkonly' [B] checkEnforceQualifierCS.ast = 'enforce' templateCS [A] templateCS ::= objectTemplateCS ('{' OclExpressionCS '}')? [B] templateCS ::= collectionTemplateCS ('{' OclExpressionCS '}')? Abstract syntax mapping templateCS.ast : TemplateExp Synthesized attributes [A] templateCS.ast = objectTemplateCS.ast if (not OclExpressionCS.ast.oclIsUndefined()) then templateCS.ast.where = OclExpressionCS.ast endif [B] templateCS.ast = collectionTemplateCS.ast if (not OclExpressionCS.ast.oclIsUndefined()) then templateCS.ast.where = OclExpressionCS.ast endif Inherited attributes [A] objectTemplateCS.env = templateCS.env OclExpressionCS.env = templateCS.env [B] collectionTemplateCS.env = templateCS.env OclExpressionCS.env = templateCS.env objectTemplateCS objectTemplateCS ::= identifierCS? ':' pathNameCS '{' propertyTemplateListCS? '}' Abstract syntax mapping objectTemplateCS.ast : ObjectTemplateExp Synthesized attributes let cls:Class = objectTemplateCS.env.lookup('context domain'). referredElement.typedModel.usedPackage.getEnvironmentWithoutParents(). lookupPathName(pathNameCS.ast).referredElement.oclAsType(Class) in if (not identifierCS.ast.oclIsUndefined) then objectTemplateCS.ast.bindsTo.name = identifierCS.ast and objectTemplateCS.ast.bindsTo.type = cls and objectTemplateCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> exists(v | v = objectTemplateCS.ast.bindsTo) endif and objectTemplateCS.ast.referredClass = cls objectTemplateCS.ast.part = propertyTemplateListCS.ast Inherited attributes propertyTemplateListCS.env = objectTemplateCS.env.addElement('context template', objectTemplateCS.ast) propertyTemplateListCS propertyTemplateListCS[1] ::= propertyTemplateCS (',' propertyTemplateListCS[2])? Abstract syntax mapping propertyTemplateListCS[1].ast : Set(PropertyTemplateItem) Synthesized attributes propertyTemplateListCS[1].ast = Set{propertyTemplateCS.ast}-> union(propertyTemplateListCS[2].ast) Inherited attributes propertyTemplateCS.env = propertyTemplateListCS[1].env propertyTemplateListCS[2].env = propertyTemplateListCS[1].env propertyTemplateCS [A] propertyTemplateCS ::= identifierCS '=' ExtOclExpressionCS [B] propertyTemplateCS ::= 'opposite' '(' classIdCS '.' identifierCS ')' '=' ExtOclExpressionCS Abstract syntax mapping: propertyTemplateCS.ast : PropertyTemplateItem Synthesized attributes: [A] propertyTemplateCS.ast.referredProperty = propertyTemplateCS.env.lookup('context template'). referredElement.oclAsType(ObjectTemplateExp). referredClass.lookupProperty(identifierCS.ast) propertyTemplateCS.ast.isOpposite = false propertyTemplateCS.ast.value = ExtOclExpressionCS.ast [A] propertyTemplateCS.ast.referredProperty = classIdCS.ast.lookupProperty(identifierCS.ast) propertyTemplateCS.ast.isOpposite = true propertyTemplateCS.ast.value = ExtOclExpressionCS.ast Inherited attributes: [A] ExtOclExpressionCS.env = propertyTemplateCS.env [B] ExtOclExpressionCS.env = propertyTemplateCS.env classIdCS.env = propertyTemplateCS.env collectionTemplateCS collectionTemplateCS ::= identifierCS? ':' CollectionTypeIdentifierCS '(' TypeCS ')' '{' (memberListCS '++' restCS)? '}' Abstract syntax mapping collectionTemplateCS.ast : CollectionTemplateExp Synthesized attributes if (CollectionTypeIdentifierCS.ast = CollectionKind::Set) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(SetType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::Sequence) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(SequenceType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::Bag) then collectionTemplateCS.ast.referredCollectionType.oclIsTypeOf(BagType) else if (CollectionTypeIdentifierCS.ast = CollectionKind::OrderedSet) then collectionTemplateCS.ast.referredCollectionType. oclIsTypeOf(OrderedSetType) endif endif endif endif collectionTemplateCS.ast.referredCollectionType.elementType = TypeCS.ast if (not identifierCS.ast.oclIsUndefined) then collectionTemplateCS.ast.bindsTo.name = identifierCS.ast and collectionTemplateCS.ast.bindsTo.type = collectionTemplateCS.ast.referredCollectionType and collectionTemplateCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> exists(v | v = collectionTemplateCS.ast.bindsTo) endif if (memberListCS->notEmpty()) then collectionTemplateCS.ast.member = memberListCS.ast endif if (not restCS.oclIsUndefined()) then collectionTemplateCS.ast.rest = restCS.ast endif Inherited attributes TypeCS.env = collectionTemplateCS.env memberListCS.env = collectionTemplateCS.env restCS.env = collectionTemplateCS.env memberListCS memberListCS[1] ::= memberCS (',' memberListCS[2])? Abstract syntax mapping memberListCS[1].ast : Sequence(OclExpression) Synthesized attributes memberListCS[1].ast = Sequence{memberCS.ast}->union(memberListCS[2].ast) Inherited attributes memberCS.env = memberListCS[1].env memberListCS[2].env = memberListCS[1].env restCS [A] restCS ::= identifierCS [B] restCS ::= '_' Abstract syntax mapping restCS.ast : Variable Synthesized attributes [A] restCS.ast = restCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable->any(v | v.name = identifierCS.ast) [B] restCS.ast.name = '_' memberCS [A] memberCS ::= identifierCS [B] memberCS ::= templateCS [C] memberCS ::= '_' Abstract syntax mapping memberCS.ast : OclExpression Synthesized attributes [A] memberCS.ast = memberCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable->any(v | v.name = identifierCS.ast) [B] memberCS.ast = templateCS.ast [C] memberCS.ast.oclIsTypeOf(Variable) memberCS.ast.oclAsType(Variable).name = '_' Inherited attributes [B] templateCS.env = memberCS.env assignmentExpListCS assignmentExpListCS[1] ::= assignmentExpCS assignmentExpListCS[2]? Abstract syntax mapping assignmentExpListCS[1].ast : Set(RelationDomainAssignment) Synthesized attributes assignmentExpListCS[1].ast = Set{assignmentExpCS.ast}-> union(assignmentExpListCS[2].ast) Inherited attributes assignmentExpListCS[2].env = assignmentExpListCS[1].env assignmentExpCS.env = assignmentExpListCS[1].env assignmentExpCS assignmentExpCS ::= identifierCS '=' OclExpressionCS ';' Abstract syntax mapping assignmentExpCS.ast : RelationDomainAssignment Synthesized attributes assignmentExpCS.ast.variable = assignmentExpCS.env.lookup('context relation'). referredElement.oclAsType(Relation).variable-> any(v | v.name = identifierCS.ast) assignmentExpCS.ast.valueExp = OclExpressionCS.ast Inherited attributes OclExpressionCS.env = assignmentExpCS.env whenCS whenCS ::= 'when' '{' predicateListCS '}' Abstract syntax mapping whenCS.ast : Pattern Synthesized attributes whenCS.ast.predicate = predicateListCS.ast Inherited attributes predicateListCS.env = whenCS.env whereCS whereCS ::= 'where' '{' predicateListCS '}' Abstract syntax mapping whereCS.ast : Pattern Synthesized attributes whereCS.ast.predicate = predicateListCS.ast Inherited attributes predicateListCS.env = whereCS.env predicateListCS predicateListCS[1] ::= predicateCS ';' predicateListCS[2]? Abstract syntax mapping predicateListCS[1].ast : Set(Predicate) Synthesized attributes predicateListCS[1].ast = Set{predicateCS.ast}->union(predicateListCS[2].ast) Inherited attributes predicateCS.env = predicateListCS[1].env predicateListCS[2].env = predicateListCS[1].env predicateCS predicateCS ::= ExtOclExpressionCS Abstract syntax mapping predicateCS.ast : Predicate Synthesized attributes predicateCS.ast.conditionExpression = ExtOclExpressionCS.ast Inherited attributes ExtOclExpressionCS.env = predicateCS.env queryCS queryCS ::= 'query' identifierCS '(' paramDeclListCS? ')' ':' TypeCS queryBodyCS Abstract syntax mapping queryCS.ast : Function Synthesized attributes queryCS.ast.name = identifierCS.ast queryCS.ast.ownedParameter = paramDeclListCS.ast queryCS.ast.type = TypeCS.ast queryCS.ast.queryExpression = queryBodyCS.ast Inherited attributes paramDeclListCS.env = queryCS.env queryBodyCS.env = queryCS.env paramDeclListCS paramDeclListCS[1] ::= paramDeclarationCS (',' paramDeclListCS[2])? Abstract syntax mapping paramDeclListCS[1].ast : Sequence(Parameter) Synthesized attributes paramDeclListCS[1].ast = Sequence{paramDeclarationCS.ast}-> union(paramDeclListCS[2].ast) Inherited attributes paramDeclarationCS.env = paramDeclListCS[1].env paramDeclListCS[2].env = paramDeclListCS[1].env paramDeclarationCS paramDeclarationCS ::= identifierCS ':' TypeCS Abstract syntax mapping paramDeclarationCS.ast : Parameter Synthesized attributes paramDeclarationCS.ast.name = identifierCS.ast paramDeclarationCS.ast.type = typeCS.ast Inherited attributes typeCS.env = paramDeclarationCS.env queryBodyCS [A] queryBodyCS ::= ';' [B] queryBodyCS ::= '{' OclExpressionCS '}' Abstract syntax mapping queryBodyCS.ast : OclExpression Synthesized attributes [B] queryBodyCS.ast = OclExpressionCS.ast Inherited attributes [B] OclExpressionCS.env = queryBodyCS.env ExtOclExpressionCS [A] ExtOclExpressionCS ::= OclExpressionCS [B] ExtOclExpressionCS ::= templateCS [C] ExtOclExpressionCS ::= RelationCallExpCS Abstract syntax mapping ExtOclExpressionCS.ast : OclExpressionCS Synthesized attributes [A] ExtOclExpressionCS.ast = OclExpressionCS.ast [B] ExtOclExpressionCS.ast = templateCS.ast [C] ExtOclExpressionCS.ast = RelationCallExpCS.ast Inherited attributes [A] OclExpressionCS.env = ExtOclExpressionCS.env [B] templateCS.env = ExtOclExpressionCS.env [C] RelationCallExpCS.env = ExtOclExpressionCS.env RelationCallExpCS RelationCallExpCS ::= (identifierCS[1] '.')? identifierCS[2] '(' argumentsCS? ')' Abstract syntax mapping RelationCallExpCS.ast : RelationCallExp Synthesized attributes RelationCallExpCS.ast.referredRelation = let trans:RelationalTransformation = if (not identifierCS[1].ast.oclIsUndefined) then RelationCallExpCS.env.lookup('imported transformation'). referredElement.oclAsType(CollectionType)-> any(t | t.name = identifierCS[1].ast) else RelationCallExpCS.env.lookup('context transformation'). referredElement.oclAsType(RelationalTransformation) endif in trans.rule->any(r | r.name = identifierCS[2].ast). oclAsType(RelationalTransformation) RelationCallExpCS.ast.argument = argumentsCS.ast Inherited attributes argumentsCS.env = RelationCallExpCS.env argumentsCS argumentsCS[1] ::= OclExpressionCS (',' argumentsCS[2])? Abstract syntax mapping argumentsCS[1].ast : Sequence(OclExpression) Synthesized attributes argumentsCS[1].ast = Sequence{OclExpressionCS.ast}->union(argumentsCS[2].ast) Inherited attributes OclExpressionCS.env = argumentsCS[1].env argumentsCS[2].env = argumentsCS[1].env Operations context RelationalTransformation::lookupClassName(names: Sequence(String)) : Class post: result = let typesPackage:Package = self.modelParameter.usedPackage->any(p| not p.getEnvironmentWithoutParents().lookupPathName(names).oclIsUndefined()) in typesPackage.getEnvironmentWithoutParents().lookupPathName(names).oclAsType(Class) Actions taken: February 6, 2007: received issue April 26, 2010: closed issue Discussion: Resolution: Deferred Comment: Specifying more formally the mapping between the concrete syntax and the metamodel - as it was achieved for the OCL language - could be interesting. However it is a very time expensive task. Also, may be difficult to maintain. We prefer defer such decision to a future RTF. End of Annotations:===== s is issue # 10646 Missing explanations in BNF The OCL 2.0 spec has a 32 page section on concrete semantics. QVTr has 1.5 pages of BNF but no explanation. In particular: What are the semantics of 'import' which has no abstract counterpart? Where is the explanation of the role of [ '{' '}' ] in a ? X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvgEAMrMPkrUnw4R/2dsb2JhbACKaoRhvTyECgU From: "Ed Willink" To: Subject: QVT 1.1 Issue 10646 Ballot 1 Disposition Date: Mon, 22 Jun 2009 08:19:05 +0100 X-Mailer: Microsoft Outlook, Build 10.0.6838 Thread-Index: AcnzCbmC3rT+jiIIT82po1gXt87I8Q== X-Plusnet-Relay: 2312666f5ca5093c35e44d73439a3275 Hi Again, apologies for the very late comment on this. Apologies too for the long email. This is a very difficult area where precision is important. Provision of this resolution demonstrates the need for the resolution, but unfortunately the resolution has an erroneous precision that will make QVTr 1.1 unimplementable whereas QVTr 1.0 is just mildly ambiguous and conflicting. Please do not include the resolution in QVT 1.1 without significant rework. I found the definition of the "checkonly"/"enforce" to isCheckable/isEnforceable helpful, although different to three of my own intuitive guesses based on attempts to avoid errors in ModelMorf and Rel2Core examples. The problems identified below are the result of a local review of the resolution. In the absence of a coherent Environment semantics it has not been possible to perform a global review. In particular, I was unable to review the specification for the arguably redundant bindsTo. [Incidentally, the same resolution approach is needed for QVTc and QVTo]. Disambiguating rules -------------------- The resolution uses a similar approach to the OCL 2.0 specification, but neglects to provide any disambiguating rules although many are needed. Environments ------------ OCL and the resolution employ environments to carry definitions specific to particular CS constructs, so that a CS reference may be resolved with the aid of an environment or the AST. In EssentialOCL, all definitions are resolvable with in the immutable AST with the exception of let and iterator expressions for which a nestedEnvironment() is used to carry the extra variable declaration with the aid of addElement(). The nestedEnvironment supports name occlusion from outer scopes. In CompleteOCL, further definitions may be introduced by a definition constraint. The OCL specification provides no precise insight into how an environment changes to accommodate the definition. Should the name be added to the AST or to the environment? Is the name available for forward reference? Environment::addElement is defined as a query operation thereby inhibiting side effects. Consequently usage such as XX.env = YY.env.addElement(Z.name, Z.ast, false) leaves the environment of YY unchanged and creates an extended environment for XX. A series of such usages creates a series of progressively elaborated environments that support backward but not forward referencing. This was not a clear requirement of the QVT 1.0 specification and it prevents any variable declarations being introduced in an object template tree being resolved through environments in other object template trees or predicate expressions. Imposition of no forward referencing seems very undesirable, particularly since the order of domains is imposed by the model parameter order. Imagine a Java program in which all methods had to be defined in a no-forward reference order. As noted above, CompleteOCL neglected to define how AST definitions were added to the AST. QVTr must solve this problem since QVTr defines a hierarchically scoped AST rather than an annotation of a pre-existing AST. I recommend a two stage approach. The inherited attributes section should first compute an environment from the pushed-down parent environment augmented by pull-ups from child constructs so that a complete immutable and consequently unambiguous environment is associated with each construct and then pushed-down to the children. During the pull-up the environment acquires a mapping from name to future-AST. During the push-down residual future-AST attributes are populated to give a valid AST. Reference resolution -------------------- OCL uses lookup functions to resolve variable references. It is necessary either to overload the lookup functions so that the the distinct QVTr variable definition sites can be located in the AST, or to use some form of Environment::addElement where each definition is defined so that resolution in the environment is possible. Details ======= Throughout, many disambiguating rules are needed to define illegal semantics. For instance "any" is often used to select a syntactically valid value. Corresponding usage in the OCL specification has a disambiguating rule to clarify what the consequence of not "one" is. My current best attempt at Disambiguating Rules is attached. Environment::addElement takes three arguments, the third being a mayBeImplicit argument. This has been omitted throughout without explanation. identifierCS ------------ OCL defines SimpleNameCS. A degenerate mapping from identifierCS to SimplenameCS is required. topLevelCS ---------- The 'imported transformation' environment element is later referenced as 'imported transformations'. Typo: TransformationListCS for transformationListCS in Synthesized attributes. importListCS ------------ Semantics of import conflicts must be defined. unitCS ------ Typo: ast is not a Set. Surely the import is of packages (enumerations or operations) or at least transformations (QVTo implementations) rather than necessarily relational-transformations? transformationCS ---------------- ownedTag is not synthesized. keyDeclListCS ------------- Typo: wrong font in synthesized attributes modelDeclCS ----------- The [B] grammar: modelDeclCS ::= modelIdCS ':' '{' metaModelIdListCS '}' is missing. keyDeclCS --------- Synthesized attributes appear to have experienced a copy and paste error while providing distinct part and oppositePart left hand sides. keyPropertyCS ------------- The synthesized attributes poke the parent. Suggest: it would be clearer for the parent to gather and distribute children similar to the relation/query allocation by transformationCS. relationCS ---------- Transformation.extends does not appear to be transitive. topQualifierCS -------------- Suggest: a boolean or enumerated value rather than a string. domainListCS ------------ Typo: missing indentation. primitiveTypeDomainCS --------------------- isCheckable, isEnforceable not synthesized. objectTemplateCS ---------------- Variable needs to be added to relation to provide a container. Variable needs to be added to relation environment to provide visibility. collectionTemplateCS -------------------- Variable needs to be added to relation to provide a container. Variable needs to be added to relation environment to provide visibility. Suggest: last two if guards are redundant. restCS ------ Variable needs to be added to relation to provide a container. Non-_ named variable needs to be added to relation environment to provide visibility. memberCS -------- Variable needs to be added to relation to provide a container. Non-_ named variable needs to be added to relation environment to provide visibility. whenCS ------ predicateListCS should be optional. whereCS ------- predicateListCS should be optional. ExtOclExpressionCS ------------------ This is not present in the QVTr or OCL grammar. Presumably it represents the QVTr extension to OCL's OclExpressionCS. However it is an extension, since at least RelationCallExpCS can be used in an ordinary OclExpressionCS using "not" or "and". [A], [B], [C] should therefore follow on from OCL's [A], [B], [C]..., [I]. RelationCallExpressionCS ------------------------ How is a RelationCallExpressionCS distinguished from an OperationCallExpCS? Regards Ed Willink Where is the instruction on how to treat the "_" identifier?