9.3.25 IteratorExpCS

第一个选择是一个直接的迭代器表达式,使用一个可选的迭代器变量。第二和第三种选择是所谓的隐式collect迭代器。B用于操作,C用于属性,D用于导航,E用于关联类。

[A] IteratorExpCS ::= OclExpressionCS[1] ‘->’ simpleNameCS
                                ‘(‘ (VariableDeclarationCS[1], (‘,’ VariableDeclarationCS[2])? ‘|’ )?
                                    OclExpressionCS[2]
                                ‘)’
[B] IteratorExpCS ::= OclExpressionCS ‘.’ simpleNameCS ‘(‘argumentsCS?’)’
[C] IteratorExpCS ::= OclExpressionCS ‘.’ simpleNameCS
[D] IteratorExpCS ::= OclExpressionCS ‘.’ simpleNameCS (‘[‘ argumentsCS ‘]’)?
[E] IteratorExpCS ::= OclExpressionCS ‘.’ simpleNameCS (‘[‘ argumentsCS ‘]’)?

抽象语法映射

IteratorExpCS.ast : IteratorExp

合成的属性

--ast需要逐位判断,首先是迭代器表达式的源关联
  [A] IteratorExpCS.ast.source = OclExpressionCS[1].ast
    -- 接下来是迭代器表达式的迭代器关联。当存在变量声明时,它的ast是这个迭代器表达式的迭代器;
    -- 当变量声明不存在时,迭代器有一个缺省名称和类型。不管哪种情况,迭代器都不能有初始化表达式
  [A] IteratorExpCS.ast.iterators->at(1).name = if VariableDeclarationCS[1]->isEmpty() then 
                                                    ''
                                                else 
                                                    VariableDeclarationCS[1].ast.name
                                                endif
  [A] IteratorExpCS.ast.iterator->at(1).type =
          if VariableDeclarationCS[1]->isEmpty() or (VariableDeclarationCS[1]->notEmpty() and
                VariableDeclarationCS[1].ast.type.oclIsUndefined() ) then
              OclExpressionCS[1].type.oclAsType (CollectionType).elementType
          else
              VariableDeclarationCS[1].ast.type
          endif
  -- 可选的第二个迭代器
  [A] if VariableDeclarationCS[2]->isEmpty() then
          IteratorExpCS.ast.iterators->size() = 1
      else
          IteratorExpCS.ast.iterators->at(2).name = VariableDeclarationCS[2].ast.name and
          IteratorExpCS.ast.iterators->at(2).type =
                if VariableDeclarationCS[2]->isEmpty() or (VariableDeclarationCS[2]->notEmpty() and
                        VariableDeclarationCS[2].ast.type.oclIsUndefined() ) then
                    OclExpressionCS[1].type.oclAsType (CollectionType).elementType
                else
                    VariableDeclarationCS[2].ast.type
                endif
      endif
  [A] IteratorExpCS.ast.iterators->forAll(initExpression->isEmpty())
  -- 接下来是迭代器表达式的名称属性和body关联
  [A] IteratorExpCS.ast.name = simpleNameCS.ast and
  [A] IteratorExpCS.ast.body = OclExpressionCS[2].ast
  -- 选择B 是一个集合上的隐式collect操作
  [B] IteratorExpCS.ast.iterator.type = OclExpressionCS.ast.type.oclAsType (CollectionType).elementType
  [B] IteratorExpCS.ast.source = OclExpressionCS.ast
  [B] IteratorExpCS.ast.name = 'collect'
  [B] -- 隐式collect的body是通过‘name’引用的操作调用
  IteratorExpCS.ast.body.oclIsKindOf (OperationCallExp) and
  let body : OperationCallExp = IteratorExpCS.ast.body.oclAsType(OperationCallExp)
  in
  body.arguments = argumentsCS.ast  and
  body.source.oclIsKindOf(VariableExp)  and
  body.source.oclAsType (VariableExp).referredVariable = IteratorExpCS.ast.iterator  and
  body.referredOperation =
        OclExpressionCS.ast.type.oclAsType (CollectionType ).elementType
            lookupOperation( simpleNameCS.ast,
                if (argumentsCS->notEmpty()) then 
                    arguments.ast->collect(type)
                else Sequence{} endif)
  -- 选择C/D是一个集合上隐式的关联或属性的collect
  [C, D] IteratorExpCS.ast.iterator.type = OclExpressionCS.ast.type.oclAsType (CollectionType).elementType
  [C, D] IteratorExpCS.ast.source = OclExpressionCS.ast
  [C, D] IteratorExpCS.ast.name = ‘collect’
  [C] -- 隐式collect的body是‘name’所引用的属性
    let refAtt : Attribute = OclExpressionCS.ast.type.oclAsType (CollectionType).
                    elementType.lookupAttribute( simpleNameCS.ast),
    in
        IteratorExpCS.ast.body.oclIsKindOf (AttributeCallExp) and
        let body : AttributeCallExp = IteratorExpCS.ast.body.oclAsType(AttributeCallExp)
        in
            body.source.oclIsKindOf(VariableExp) and
            body.source.oclAsType (VariableExp).referredVariable = IteratorExpCS.ast.iterator and
            body.referredAttribute = refAtt
  [D] -- 隐式collect的body是‘name’所引用的导航调用
  let refNav : AssociationEnd = OclExpressionCS.ast.type.oclAsType (CollectionType).
                elementType.lookupAssociationEnd(simpleNameCS.ast)
    in
        IteratorExpCS.ast.body.oclIsKindOf (AssociationEndCallExp) and
        let body : AssociationEndCallExp = IteratorExpCS.ast.body.oclAsType(AssociationEndCallExp)
        in
            body.source.oclIsKindOf(VariableExp) and
            body.source.oclAsType (VariableExp).referredVariable = IteratorExpCS.ast.iterator and
            body.referredAssociationEnd = refNav and
            body.ast.qualifiers = argumentsCS.ast
  [E] -- 隐式collect的body是‘name’所指的关联类的导航
      let refClass : AssociationClass = OclExpressionCS.ast.type.oclAsType (CollectionType).
                      elementType.lookupAssociationClass(simpleNameCS.ast)
        in
            IteratorExpCS.ast.body.oclIsKindOf (AssociationClassCallExp) and
            let body : AssociationClassCallExp = IteratorExpCS.ast.body.oclAsType(AssociationClassCallExp)
                in
                    body.source.oclIsKindOf(VariableExp) and
                    body.source.oclAsType (VariableExp).referredVariable = IteratorExpCS.ast.iterator and
                    body.referredAssociationClass = refNav and
                    body.ast.qualifiers = argumentsCS

继承的属性

[A] OclExpressionCS[1].env = IteratorExpCS.env
[A] VariableDeclarationCS.env = IteratorExpCS.env
-- 在迭代器表达式中,body在一个包含迭代器变量在内的新环境中被计算
[A] OclExpressionCS[2].env =
        IteratorExpCS.env.nestedEnvironment().addElement(VariableDeclarationCS.ast.varName,
                        VariableDeclarationCS.ast,
                        true)
[B] OclExpressionCS.env = IteratorExpCS.env
[B] argumentsCS.env = IteratorExpCS.env
[C] OclExpressionCS.env = IteratorExpCS.env
[D] OclExpressionCS.env = IteratorExpCS.env

歧义消除规则

[1][A] 当存在变量声明时,不能有初始化表达式。

VariableDeclarationCS->notEmpty() implies VariableDeclarationCS.ast.initExpression->isEmpty()

[2][B] 源必须是一个集合类型。

OclExpressionCS.ast.type.oclIsKindOf(CollectionType)

[3][C] 源必须是一个集合类型。

OclExpressionCS.ast.type.oclIsKindOf(CollectionType)

[4][C] 引用的属性必须存在。

refAtt->notEmpty()

[5][D] 引用的导航必须存在。

refNav->notEmpty()

results matching ""

    No results matching ""