7.4.8 优先级规则
OCL中操作的优先级从高到低是:
- 字面量和变量表达式,"("和")","if-then-else-endif"
- "let-in"
- @pre
- 调用表达式:"^", "^^", ".", "->"
- 单操作符"not"和"-"
- "*" 和 "/"
- "+" 和二元操作符"-"
- "<", ">", "<=", ">="
- "=", "<>"
- "and"
- "or"
- "xor"
- "implies"
- "in"
所有中缀操作符都是左关联,同级操作符从左到右计算。
let表达式即有高优先级又有低优先级;左部是高从而使得let表达式可以作为操作中的一个原子值,右部低从而可以使得in表达式可以是任意的表达式。"a + let ... in a + let ... in a + a" 是 "a + (let... in (a + (let ... in (a + a))))"。
"("和")"可以用来改变优先级和关联性。
7.4.9 中缀操作符的使用
OCL中允许使用中缀操作符。操作符 '+', '-', '*', '/', '=', '<>', '<', '>', '<=', '>=' 都是中缀操作符。如果某个类型使用正确的签名定义了其中的一种操作符,那么它们就可以被用做中缀操作符。表达式 a + b 等同于 a._'+'(b),也即在 a 上调用 "+" 操作,参数是 b。
类型中定义的中缀操作符只能有一个参数,对于中缀操作符 '<', '>', '<=', '>=', '<>', 'and', 'or', 'xor' 返回类型必须是布尔。
7.4.10 导航操作符和导航简化
有两种导航操作符:"." 和 "->"。
"."操作符支持来自对象的到属性和操作的导航:
anObject.name aString.indexOf(':')
"->"操作符支持来自集合的到属性、操作或迭代的导航:
aBag->elementType aSet->union(anotherSet) aSet->collect(name)
此外还有两种导航简化(shorthands):"." 和 "->"。
"."导航简化在一个集合上执行一个隐式的属性或操作collect操作:
aSet.name 是 aSet->collect(name)的简化
"->"导航简化在一个对象上执行一个隐式的集合转化:
anObject->union(aSet) 是 anObject.oclAsSet()->union(aSet)的简化
这些操作符和简化总结在表7.5中。
Table 7.5 - - Navigation Operators and Shorthands
Object Source | Collection Source | |
---|---|---|
. | 对象导航操作 | 隐式的集合转化导航简化 |
-> | 隐式的集合转化导航简化 | 集合导航操作 |
7.4.11 关键字
OCL中的关键字是保留字。这意味着这些关键字不能作为一个名称出现。可以通过把保留字包装在一个以下划线做前缀的单引号内来把一个保留字用作一个包、类型、特征、变量或约束的名称。关键字列表如下:
and if or body implies package
context in post def init pre
derive inv self else invalid static
endif let then endpackage not true
false null xor
下面的字限制使用。限制使用的字只能用作名称并且前面有一个"::"。限制字也可以通过把它包装在一个以下划线做前缀的单引号内来使用:
Bag OrderedSet Boolean Real Collection Sequence
Integer Set OclAny String OclInvalid Tuple
OclMessage UnlimitedNatural OclVoid
注意,类似iterate, forAll 和 oclType 等操作名既不是保留字也不是限制字。
7.4.12 注释
OCL中的注释写在两个连续的虚线(减号)后。两个虚线号之后一直到改行结束都是注释。
例如:
-- this is a comment
7.4.13 无效值
有些表达式在计算时会产生一个无效的值。例如,使用oclAsType()对一个对象进行不支持的类型进行类型转换或对一个空集合调用->first()操作都会产生一个无效值。通常,如果表达式的一部分是null或无效,那么它本身也是无效的。然而,对此规则还有一些重要的例外。首先,是逻辑操作符:
- True对任意值进行OR都是True
- False对任意值进行AND都是False
- False IMPLIES 任意值都是True
- 任意值IMPLIES True都是True
OR和AND的规则是与操作数的次序无关的,并且不管其他子表达式的值是否已知它们都是有效的。
OR和AND的规则适用于 exists 和forAll 迭代。
IF表达式是另一个例外。只要条件和所选择的分支有效,那么它就是有效的,而不用管其它分支的值。
null对象可以在 = 和 <> 比较中与有效(non-invalid)对象进行比较。
最后,OCL中有显示的操作用于测试表达式的值是否未定义。oclIsUndefined() 是OclAny上的一个操作,如果参数是null或invalid,那么产生true,否则false。类似的,OclAny上的另一操作 oclIsInvalid()在参数是invalid时产生true,否则false。所有显示的操作都定义在11.3.2和11.3.3。