9.3.35 OperationCallExpCS
操作调用有许多不同的形式。A用于infix,B用于对象的隐式集合,C是一个直接的操作调用,D具有一个隐式的源表达式。E、F、J与C、D、I 类似,它们使用了@pre。G涵盖了静态操作调用。规则H用于单前缀表达式。I 和 J使用 pathNameCS来允许访问重定义的操作中使用限定的操作名称。
[A] OperationCallExpCS ::= OclExpressionCS[1] simpleNameCS OclExpressionCS[2]
[B] OperationCallExpCS ::= OclExpressionCS ‘->’ simpleNameCS ‘(‘ argumentsCS? ‘)’
[C] OperationCallExpCS ::= OclExpressionCS ‘.’ simpleNameCS ‘(‘ argumentsCS? ‘)’
[D] OperationCallExpCS ::= simpleNameCS ‘(’ argumentsCS? ‘)’
[E] OperationCallExpCS ::= OclExpressionCS ‘.’ simpleNameCS isMarkedPreCS ‘(’ argumentsCS? ‘)’
[F] OperationCallExpCS ::= simpleNameCS isMarkedPreCS ‘(’ argumentsCS? ‘)’
[G] OperationCallExpCS ::= pathNameCS ‘(’ argumentsCS? ‘)’
[H] OperationCallExpCS ::= simpleNameCS OclExpressionCS
[I] OperationCallExpCS ::= OclExpressionCS '.' pathNameCS '::' simpleNameCS '(' argumentsCS? ')'
[J] OperationCallExpCS ::= OclExpressionCS '.' pathNameCS '::' simpleNameCS isMarkedPreCS '(' argumentsCS? ')'
抽象语法映射
OperationCallExpCS.ast : OperationCallExp
合成的属性
-- 该规则用于二元操作,例如‘+,’ ‘-,’ ‘*,’ etc. 它只有一个实参.
[A] OperationCallExpCS.ast.arguments = Sequence{OclExpression2[2].ast}
OperationCallExpCS.ast.source = OclExpressionCS[1].ast
OperationCallExpCS.ast.referredOperation =
OclExpressionCS.ast.type.lookupOperation (
simpleNameCS.ast,
Sequence{OclExpression[2].ast.type} )
-- source要么是个集合,要么是用做集合的单一对象
[B] OperationCallExpCS.ast.arguments = argumentsCS.ast
-- 如果OclExpressionCS是一个集合类型, 那么source是这个OclExpressionCS.
-- 否则source必须通过定义一个包含该OclExpressionCS在内的单列集合来构造。这可以通过调用标准操作"asSet()"来完成
OperationCallExpCS.ast.source =
if OclExpressionCS.ast.type.oclIsKindOf(CollectionType) then
OclExpressionCS.ast
else
OclExpressionCS.ast.withAsSet()
endif
---- The referred operation:
OperationCallExpCS.ast.referredOperation =
if OclExpressionCS.ast.type.oclIsKindOf (CollectionType) then
-- this is a collection operation called on a collection
OclExpressionCS.ast.type.lookupOperation (simpleNameCS.ast,
if (argumentsCS->notEmpty()) then
argumentsCS.ast->collect(type)
else
Sequence{}
endif )
else
-- this is a set operation called on an object => implicit Set with one element
SetType.allInstances()->any (st | st.elementType = OclExpressionCS.ast.type).lookupOperation (
simpleNameCS.ast, if (argumentsCS->notEmpty()) then
argumentsCS.ast->collect(type)
else
Sequence{}
endif )
endif
[C] OperationCallExpCS.ast.referredOperation =
OclExpressionCS.ast.type.lookupOperation (simpleNameCS.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
OperationCallExpCS.ast.arguments = argumentsCS.ast
OperationCallExpCS.ast.source = OclExpressionCS.ast
[D] OperationCallExpCS.ast.arguments = argumentsCS.ast and
OperationCallExpCS.ast.referredOperation =
env.lookupImplicitOperation(simpleName.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
OperationCallExpCS.ast.source = env.lookupImplicitSourceForOperation(
simpleName.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
[E] -- incorporate the isPre() operation.
OperationCallExpCS.ast.referredOperation =
OclExpressionCS.ast.type.lookupOperation (simpleNameCS.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
OperationCallExpCS.ast.arguments = argumentsCS.ast
OperationCallExpCS.ast.source = OclExpressionCS.ast.isPre = true
[F] -- incorporate atPre() operation with the implicit source
OperationCallExpCS.ast.arguments = argumentsCS.ast and
OperationCallExpCS.ast.referredOperation =
env.lookupImplicitOperation(simpleName.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
)
OperationCallExpCS.ast.source =
env.lookupImplicitSourceForOperation(simpleName.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
).isPre = true
[G] OperationCallExpCS.ast.arguments = argumentsCS.ast and
OperationCallExpCS.ast.referredOperation =
env.lookupPathName(pathName.ast,
e{} endif) --译者注:这里有语法问题
OperationCallExpCS.ast.source->isEmpty()
-- this rule is for unary operators as ‘-’ and ‘not’ etc. It has no argument.
[H] OperationCallExpCS.ast.arguments->isEmpty()
OperationCallExpCS.ast.source = OclExpressionCS.ast
OperationCallExpCS.ast.referredOperation =
OclExpressionCS.ast.type.lookupOperation (simpleNameCS.ast, Sequence{} )
[I] let owner : Classifier = pathNameCS.env.lookupPathName(pathNameCS.ast).referredElement.oclAsType(Classifier) in
OperationCallExpCS.ast.referredOperation =
owner.lookupOperation (simpleNameCS.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
OperationCallExpCS.ast.arguments = argumentsCS.ast
OperationCallExpCS.ast.source = OclExpressionCS.ast
[J] -- incorporate the isPre() operation.
let owner : Classifier =
pathNameCS.env.lookupPathName(pathNameCS.ast).referredElement.oclAsType(Classifier)
in OperationCallExpCS.ast.referredOperation =
owner.lookupOperation (simpleNameCS.ast,
if argumentsCS->notEmpty()
then arguments.ast->collect(type)
else Sequence{} endif)
OperationCallExpCS.ast.arguments = argumentsCS.ast
OperationCallExpCS.ast.source = OclExpressionCS.ast.isPre = true
继承的属性
[A] OclExpressionCS[1].env= OperationCallExpCS.env
[A] OclExpressionCS[2].env= OperationCallExpCS.env
[B] OclExpressionCS.env= OperationCallExpCS.env
[B] argumentsCS.env = OperationCallExpCS.env
[C] OclExpressionCS.env= OperationCallExpCS.env
[C] argumentsCS.env = OperationCallExpCS.env
[D] argumentsCS.env = OperationCallExpCS.env
[E] OclExpressionCS.env= OperationCallExpCS.env
[E] argumentsCS.env = OperationCallExpCS.env
[F] argumentsCS.env = OperationCallExpCS.env
[I] OclExpressionCS.env= OperationCallExpCS.env
[I] argumentsCS.env = OperationCallExpCS.env
[J] OclExpressionCS.env= OperationCallExpCS.env
[J] argumentsCS.env = OperationCallExpCS.env
歧义消除规则
[1][A] 所引用的操作名称必须是一个操作。
Set{‘+’,’-’,’*’,’/’,’and’,’or’,’xor’,’=’,’<=’,’>=’,’<‘,’>’}->includes(simpleNameCS.ast)
[2][A,B,C,D,E,F] 所指操作必须是source类型上定义的。
not OperationCallExpCS.ast.referredOperation.oclIsUndefined()
[3][I,J] pathNameCS必须是当前环境中的一个分类符的名称。
OperationCallExpCS.env.lookupPathName(pathNameCS.ast).referredElement.oclIsKindOf(Classifier)
[4][I, J] source表达式的类型必须符合所引用操作的属主的类型。
let owner : Classifier = pathNameCS.env.lookupPathName(pathNameCS.ast).referredElement.oclAsType(Classifier) in
OclExpressionCS.ast.type.conformsTo(owner)