list of dots Digital Research Alliance of Canada logo  NSERC logo  University of Ottawa logo / UniversitĂ© d'Ottawa

User Manual    [Previous]   [Next]   

Umple Grammar

Below is the complete grammar for Umple . This page is generated automatically from the grammar used to parse Umple code.

  • Rules are in blue. You may click on a usage of a rule (underlined and in [[ ]]) anywhere in this manual in order to see the definition.
  • Terminal symbols are in red. These keywords and symbols that are key to Umple's syntax.
  • Identifiers are in green and are surrounded by [ ]. These are places where you can supply a sequence of alphanumeric characters to name a class, attribute or some other entity.
  • Arbitrary input is in yellowish green and surrounded by [** ]. Umple ignores everything until it finds the symbol that terminates the input. This is used for comments and to embed code in a language like Java or PhP. Umple will pass this text to the parser of the underlying language.
  • Comments about the grammar itself are in brown and preceded by //
  • symbols controlling how the grammar is parsed are in black.
      * means zero or more
    • | means 'or'
    • ? means optional
    • Other black items are of interest only to experts

Refer to the Grammar Notation section for more explanation of the EBNF syntax used here.


// The master source of this first part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/umple_core.grammar
// The html rendering is generated from the master and appears in the Umple User manual
// at page http://grammar.umple.org

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// The core of umple is a "program". This is the grammar's 'start symbol'
// Comments and lone semicolons are ignored
program- : [[useProgram]] | [[umpleProgram]]


umpleProgram- : ( [[comment]] | [[directive]] | ; )*


// Directives are the top-level items in an umple file. See manual page TypesofDirectives
// A directive is either used to configure the system or else is
// an actual entity of the system to be modelled or generated
directive- : [[checkForUnintendedBracket]]
    | [[glossary]]
    | [[generate]]
    | [[distribute]]
    | [[generate_path]]
    | [[filter]]
    | [[useStatement]]
    | [[namespace]]
    | [[requirement]]
    | [[reqImplementation]]
    | [[tracerDirective]]
    | [[entity]]
    | [[debug]]
    | [[strictness]]
    | [[toplevelExtracode]]
    | [[toplevelException]]


// A glossary item is used to fine tune pluralization during code generation
glossary : glossary { [[word]]* }

word : [singular] : [plural] ;

distribute : distributable [=distributeTech:RMI
    |WS]? [=distributePattern:0
    |1
    |2
    |3]? [=distributeVal:on
    |off
    |forced] ;

// A high level of strictness will cause warnings to be issued when base language code
// is found, where it might not have been intended. Strictness can also be used
// To either suppress certain messages, or to declare that they should be present.
// NOTE: This is currently under development
strictness- : strictness ( [=strictness:modelOnly|noExtraCode|none]
    | [[strictnessMessage]]
    | [[strictnessDisableAuto]] ) ;

strictnessMessage : [=message:allow|ignore|expect|disallow] [messageNumber]

strictnessDisableAuto : disable [**expression]


// The generate clause can be used to generate multiple outputs
// The --override is used to say that subsequent generate statements will be ignored
generate : generate [=language:Java
    |Nothing
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Python
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvFeatureDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |NuSMVOptimizer
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |StateTables
    |EventSequence
    |Umple
    |UmpleSelf
    |USE
    |Test
    |SimpleMetrics
    |PlainRequirementsDoc
    |Uigu2
    |ExternalGrammar] ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;


generate_path : generate [=language:Java
    |Nothing
    |Php
    |RTCpp
    |SimpleCpp
    |Ruby
    |Python
    |Cpp
    |Json
    |StructureDiagram
    |Yuml
    |Violet
    |Umlet
    |Simulate
    |TextUml
    |Scxml
    |GvStateDiagram
    |GvClassDiagram
    |GvFeatureDiagram
    |GvClassTraitDiagram
    |GvEntityRelationshipDiagram
    |Alloy
    |NuSMV
    |NuSMVOptimizer
    |Papyrus
    |Ecore
    |Xmi
    |Xtext
    |Sql
    |StateTables
    |EventSequence
    |Umple
    |UmpleSelf
    |USE
    |Test
    |SimpleMetrics
    |PlainRequirementsDoc
    |Uigu2
    |ExternalGrammar] " [**output] " [=override:--override
    |--override-all]? ( [=suboptionIndicator:-s
    |--suboption] " [**suboption] " )* ;


// Use statements allow incorporation of other Umple files. See UseStatements
useStatement : use [use] ( , [extraUse] )*


toplevelExtracode : top [top] [[moreCode]]


// Namespaces divide the code into logical groups. See NamespaceDirectives
namespace- : namespace [namespace] [[namespaceoption]]? ;

namespaceoption : [=option:--redefine]


// The main top level elements to be found in an Umple file
entity- : [[mixsetIsFeature]]
    | [[requireStatement]]
    | [[mixsetDefinition]]
    | [[classDefinition]]
    | [[traitDefinition]]
    | [[fixml]]
    | [[interfaceDefinition]]
    | [[externalDefinition]]
    | [[associationDefinition]]
    | [[associationClassDefinition]]
    | [[stateMachineDefinition]]
    | [[templateDefinition]]
    | [[enumerationDefinition]]
    | [[toplevelCodeInjection]]


// Comments follow the same conventions as C-family languages. UmpleComments
comment- : [[inlineComment]] | [[multilineComment]] | [[annotationComment]]

inlineComment- : // [**inlineComment]

multilineComment- : /* [**multilineComment] */


requirement : req [reqIdentifier] [reqLanguage]? { [**reqContent] }

reqImplementation : implementsReq [reqIdentifier] (, [reqIdentifier])* ;


//Matches all forms of Java annotations including those with parentheses and values in quotes
annotationComment- : [!annotationComment:@[a-zA-Z_][a-zA-Z0-9_-]*(\((("(\w
    |\s
    |CLOSE_ROUND_BRACKET*")
    |\w
    |\s
    |=
    |,
    |\.)*\))?]


// The Debug statement turns on debugging in code generation. For developer use only
debug- : [=debug] ;


// Instructs a class or method to be abstract
abstract- : [=abstract] ;

// The master of this second part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/umple_patterns.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

softwarePattern- : [[isA]] | [[singleton]] | [[immutable]] | [[keyDefinition]] | [[codeInjection]]


// Generalization and inheritance isAclause
isA- : [[singleIsA]] | [[multipleIsA]]

singleIsA- : isA [[isAName]] ( , isA [[isAName]] )* ;

multipleIsA- : isA [[isAName]] ( , [[isAName]] )* ;

isAName- : " [**extendsNames] " [[gTemplateParameter]]?
    | [extendsName] [[gTemplateParameter]]?


gTemplateParameter : < [[AllInclusionExclusionAlias]] >


// A class that can have only one instance SingletonPattern
singleton- : [=singleton] ;


// A class that can't be modified when created ImmutablePattern
immutable- : [=immutable] ;


// For equality and hashing KeysforEqualityandHashing
keyDefinition- : [[defaultKey]] | [[key]]


// Aspect oriented code injection: BeforeandAfterStatements
codeInjection- : [[beforeCode]] | [[afterCode]]


toplevelCodeInjection- : [[toplevelBeforeCode]] | [[toplevelAfterCode]]


parameterTypes : [parameterType] (, [parameterType])*

parameterListing : ( ([[parameterTypes]])? )


injectionOperation : [operationName] ([[parameterListing]])?


beforeCode : ( before | [=around] ) [[aspectBody]]

afterCode : after [[aspectBody]]


toplevelBeforeCode : ( before | [=around] ) {([className])(, [className])*} [[aspectBody]]

toplevelAfterCode : after {([className])(, [className])*} [[aspectBody]]


aspectBody- : ([=operationSource:custom
    |generated
    |all])? ([!codeLabel:\S+:])? [[injectionOperation]] ( , [[injectionOperation]] )* ([[codeLang]] [[codeLangs]])? { [**code] } ( [[moreCode]] )*

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/constraint/umple_constraints.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Constraints in Umple.
// This is currently under development. Constraint capability is being
// developed in agile increments. The first step, described below,
// allows limiting the values of attributes. Code generation is not currently enabled.
// Constraints may appear in classes (including association classes)
// as well as in states.
precondition : [ [name]? pre : [[constraint]] ]

postcondition : [ [name]? post : [[constraint]] ]


invariant : [ ([name] :)? ([[constraint]]) ]

constraintToken : [[constraint]]


// A constraint is an expression optionally be surrounded in round brackets or negated
constraint- : [[constraintBody]] [[linkingOp]]? | [[constraintExpr]] [[linkingOp]]?

//negativeConstraint : ( ! | not ) ( [[constraintName]] | [[constraint]] ) fixed issue1536 'Umple does not parse properly the guards'
negativeConstraint : ( ! | [!constraintNegSymbol:not\s+] ) ( [[constraintName]] | [[constraint]] )


// A constraint body is a constraint expression (possibly with a linking operator such as && or ||).
constraintBody : ( [[constraint]] )

linkingOp- : ( [=andOp:and|&&|&]
    | [[equalityOperator]]
    | [!orOp:(or|\Q||\E)] ) [[linkingOpBody]]

linkingOpBody : [[constraint]]

constraintExpr- : [[statemachineExpr]]
    | [[stringExpr]]
    | [[boolExpr]]
    | [[numExpr]]
    | [[associationExpr]]
    | [[genExpr]]
    | [[loneBoolean]]
    | { [!fakeContraint:[^\n]+] }


loneBoolean : [[constraintVariable]]


//must be a boolean //fixing is here!!!
boolExpr : [[constraintVariable]] [[equalityOperator]] [[boolLiteral]]
    | [[boolLiteral]] [[equalityOperator]] [[constraintVariable]]
    | [[boolLiteral]]

boolLiteral : [=literal:true|false]


//must be string
stringExpr : [[stringExprOperator]] | [[stringExprPlain]]

stringExprPlain- : [[constraintVariable]] [[equalityOperator]] [[stringLiteral]]
    | [[stringLiteral]] [[equalityOperator]] [[constraintVariable]]

stringExprOperator- : [[stringComplexExpression]] [[equalityOperator]] [[stringComplexExpression]]
    | [[stringComplexExpression]] [[equalityOperator]] [[stringName]]
    | [[stringName]] [[equalityOperator]] [[stringComplexExpression]]

stringLiteral- : " [**quote] " | ' [**quote] '

stringName- : [[stringLiteral]] | [[constraintVariable]]

stringComplexExpression : [[stringPlusOperator]]

stringPlusOperator- : [[stringName]] ( [=concat:+] [[stringPlusOperator]] )?


//basically the "other" catagory, contains everything that can be equal to something else
genExpr : [[constraintVariable]] [[equalityOperator]] [[constraintVariable]]


//for floats, doubles and ints
numExpr : [[numberExpression1]]
    | [[numberExpression2]]
    | [[numberExpression3]]
    | [[numberExpression4]]

numberExpression1- : ( [[arithmeticCall]]
    | [[numberName]] ) [[ordinalOp]] ( [[arithmeticCall]]
    | [[numberName]] )

numberExpression2- : ( [[arithmeticCall]]
    | [[constraintVariable]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[numberLiteral]] )

numberExpression3- : ( [[arithmeticCall]]
    | [[numberLiteral]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[constraintVariable]] )

numberExpression4- : ( [[arithmeticCall]]
    | [[numberLiteral]] ) [[equalityOperator]] ( [[arithmeticCall]]
    | [[numberLiteral]] )

numberLiteral- : [!number:-?[0-9]+([\\.][0-9]+)?]

numberName- : [[numberLiteral]] | [[constraintVariable]]

arithmeticCall : ( ( [[lowArithmeticOperatorCall]]
    | [[highArithmeticOperatorCall]] ) )

lowArithmeticOperatorCall- : ( [[highArithmeticOperatorCall]]
    | [[arithmeticResolve]] )? [=operator:+|-|>>|<<] ( [[arithmeticCall]]
    | [[arithmeticResolve]] )

highArithmeticOperatorCall- : [[arithmeticResolve]] [=operator:*|/|^|%] ( [[highArithmeticOperatorCall]]
    | [[arithmeticResolve]] )

arithmeticResolve- : ( [[arithmeticCall]] ) | [[numberName]]


equalityOperator- : [=equalsOp:==|equals] | [=notequalsOp:!=|/=|=!|=/=]

ordinalOp- : [=greaterOp:greater|>=|=>|=>=]
    | [=lessOp:less|<=|=<|=<=]
    | [=moreOp:larger|>]
    | [=smallerOp:smaller|<]


associationExpr : [[constraintVariable]] [[associationOperators]] [[associationLiteral]]

associationOperators- : [=firstOp:cardinality|has] ( [[ordinalOp]] | [[equalityOperator]] | [=all] )?

associationLiteral : [[constraintParameter]] ( , [[associationLiteral]] )?


statemachineExpr : [[constraintVariable]] [[statemachineOperators]] [[statemachineLiteral]]

statemachineOperators- : [=isInOp:is|state] [=ignore:==|in]
    | [=isNotInOp:is|state] ( [=ignore:!=]
    | [=ignore:not] [=ignore:in] )

statemachineLiteral- : [=state]? [~stateName]


constraintVariable- : [[negativeConstraint]] | [[constraintName]]

constraintName : [=new]? [!name:[a-zA-Z_][a-zA-Z0-9_-]*] [[constraintIndexOperator]]* [[constraintParameterList]]? [[constraintScopeOperator]]?

constraintIndexOperator- : [ [!index:[0-9]+] ]

constraintScopeOperator : ( . | -> ) [[constraintVariable]]

constraintParameterList : ( ([[constraintParameter]] ([=comma:,] [[constraintParameter]])*)? )

constraintParameter : [=boolLit:true|false]
    | [[stringLiteral]]
    | [[constraintVariable]]
    | [[numberLiteral]]


modelConstraint- : [ model : [[modelConstraintBody]] ]

modelConstraintBody : ( [[modelConstraintBody]] ) [[modelLinkingOp]]?
    | [[modelExpr]] [[modelLinkingOp]]?

modelLinkingOp : ( [=and:&|&&|and|,] | [!or:([|][|]?|or|;)] ) [[modelConstraintBody]]

modelExpr : [~source]? [[modelRelationOp]] [~target]

modelRelationOp- : [[modelRelationOpAssociation]]
    | [[modelRelationOpAttribute]]
    | [[modelRelationOpInheritance]]

modelRelationOpInheritance : [=subclass:isA]
    | [=subclass:subclass|child|>>] ( of )?
    | [=subclass:inherits] ( from )?
    | [=superclass:parent|superclass|<<] ( of )?

modelRelationOpAttribute : [=op:has] ( attribute | attr )? [=classification:named|of]?

modelRelationOpAssociation : [[modelRelationAssociationEnd]]? [=op:--
    |->
    |<-
    |-<@>
    |<@>-] [[modelRelationAssociationEnd]]?

modelRelationAssociationEnd : [!bound:(\d+|[**])] ( .. [!bound:(\d+|[**])] )?



// NOTE: Additional grammar parts deleted while testing is ongoing.
// The master of this second part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/umple_exceptions.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

misnamedAttribute : [name] ; | [type] [name] ;

malformedConstraint : [ [!stuff:[^\]]*] ]

malformedStatement1 : [!stuff:[^\\{\\};]*] ( [!stuff:[^\\{\\};]*] )* ;

malformedStatemachine1 : [!stuff:[^\\{\\}\\(\\) ]*] { [**innerstuff] }

malformedStatement2 : [!stuff:[^\\{\\};]*] ( [!stuff:[^\\{\\};]*] )* { [**innerstuff] } ;

malformedStatemachine2 : [!stuff:[^\\{\\}\\(\\)]*] ( [!stuff:[^\\{\\}\\(\\)]*] )* { [**innerstuff] }

malformedMethod : [!stuff:[^\\{\\}\\(\\)]*] ( [!stuff:[^\\{\\}]*] )* { [**innerstuff] }

exception : [[misnamedAttribute]]
    | [[malformedStatement1]]
    | [[malformedStatemachine1]]
    | [[malformedStatement2]]
    | [[malformedStatemachine2]]
    | [[malformedConstraint]]
    | [[malformedMethod]]


toplevelException : [[toplevelExceptionMain]] ( { [**extraStuff] } )? ( " [**quotedStuff] " )? ( ; )?

toplevelExceptionMain : [=access:public
    |private
    |protected]? [identifier] [=queued]? [name]? [[inheritanceException]]? [name]*

inheritanceException : ( [=level:extends|implements]? [name] ( , [name] )* )+

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// beginning of use.grammar

// This is essentially rewriting the grammar rules present in the USE compiler, which exist in a similar format.

useProgram : model [id] ([[useGeneralClassDefinition]]
    | [[useInlineComment]]
    | [[useAssociation]])*


useGeneralClassDefinition- : [[useClassDefinition]]


useClassDefinition : (abstract)? class [id] [[useAttributes]]? end


useAttributes : attributes [[useAttributeDefinition]]*


useAttributeDefinition : [id] : [[useType]] (;)?


useType- : [[useSimpleType]]


useSimpleType : [id]


useInlineComment- : (-- [**inlineComment]) | (// [**inlineComment])


useAssociation : association [name] between [[useAssociationEnd]] [[useAssociationEnd]] end


useAssociationEnd : [name] [ [[useMultiplicity]] ]


useMultiplicity- : [[useMultiplicityRange]]


useMultiplicityRange : [[useMultiplicitySpec]] (.. [[useMultiplicitySpec]])?


useMultiplicitySpec : [integerSpec:\d+|[**]]

// The master of this second part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/class/umple_classes.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Classes are the most common elements in Umple.
// See user manual page ClassDefinition
classDefinition : class [name] { [[classContent]]* }


//The external keyword declares a class that is defined in a different
// compilation unit
externalDefinition : external [=interface]? [name] { [[classContent]]* }


// An Interface can only contain method. See interfaceDefinition
interfaceDefinition : interface [name] { [[depend]]* [[interfaceBody]] }


// Associations can be declared outside the body of classes.
// See user manual page IndependentlyDefinedAssociations
associationDefinition : association [name]? { ([[comment]]
    | [[reqImplementation]]
    | [[mixsetDefinition]]
    | [[association]])* }


// Associations that would be many-many can also become full-fledged classes too
// See user manual page AssociationClassDefinition
associationClassDefinition : associationClass [name] { [[associationClassContent]]* }


// Enumerations can be declared outside the body of classes
// See user manual page EnumerationDefinition
enumerationDefinition : enum [name] { [enumValue](, [enumValue])* }


// The following items can be found inside the body of classes or association classes
classContent- : [[comment]]
    | [[reqImplementation]]
    | [[innerClass]]
    | [[mixsetDefinition]]
    | [[distributable]]
    | [[proxyPattern]]
    | [[strictness]]
    | [[classDefinition]]
    | [[trace]]
    | [[emitMethod]]
    | [[templateAttributeDefinition]]
    | [[primitiveDefinition]]
    | [[portDefinition]]
    | [[portBindingDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[testCase]]
    | [[genericTestCase]]
    | [[testSequence]]
    | [[testClassInit]]
    | [[stateMachine]]
    | [[activeMethodDefinition]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[constantDeclaration]]
    | [[modelConstraint]]
    | [[invariant]]
    | ;
    | [[enumerationDefinition]]
    | [[exception]]
    | [[extraCode]]

associationClassContent- : [[comment]]
    | [[reqImplementation]]
    | [[classDefinition]]
    | [[position]]
    | [[displayColor]]
    | [[invariant]]
    | [[softwarePattern]]
    | [[depend]]
    | [[association]]
    | [[inlineAssociation]]
    | [[singleAssociationEnd]]
    | [[attribute]]
    | [[stateMachine]]
    | [[enumerationDefinition]]
    | ;
    | [[extraCode]]

innerClass : [[innerStaticClass]] | [[innerNonStaticClass]]

innerStaticClass : static [[classDefinition]]

innerNonStaticClass : inner [[classDefinition]]


checkForUnintendedBracket : (
    | )
    | OPEN_CURLY_BRACKET
    | CLOSE_CURLY_BRACKET


// Interfaces: Note that if the format of an abstractMethodDeclaration is not
// followed, then the body will extraCode and passed to the base language
// See user manual page interfaceDefinition
interfaceBody- : [[interfaceMemberDeclaration]]*

interfaceMemberDeclaration : [[comment]]
    | [[reqImplementation]]
    | [[constantDeclaration]]
    | [[constantDeclarationDeprecated]]
    | [[abstractMethodDeclaration]]
    | [[position]]
    | [[displayColor]]
    | [[isA]]
    | [[interfaceTest]]
    | [[distributableInterface]]
    | [[exception]]
    | [[extraCode]]

distributableInterface : [[distributable]]

// Constants in interfaces (e.g. const String ACONSTANT="aValue";)
// Note: in Classes const is a modifier
constantDeclarationDeprecated : constant [[typedName]] (= [**value])? ;

constantDeclaration : [=internal]? const [[typedName]] (= [**value])? ;



distributable- : [=distributable:distributable] [=distributeTech:RMI|WS]? ;

proxyPattern- : [=proxyPattern:proxyPattern] ;

moreCode- : [[codeLangs]] { [**code] }

codeLangs- : ([=codeLang:Java
    |RTCpp
    |SimpleCpp
    |Cpp
    |Php
    |Ruby
    |Python
    |Alloy
    |UmpleSelf] ( , [=codeLang:Java
    |Alloy
    |RTCpp
    |SimpleCpp
    |Cpp
    |Php
    |Ruby
    |Python
    |UmpleSelf] )* )?


// Methods: The code in concrete methods is passed to the base language
// See user manual page MethodDefinition
concreteMethodDeclaration : [=modifier:public|protected|private]? [=static]? [=synchronized]? [=queued]? [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? [[methodBody]]
    | [=modifier:public|protected]? [=abstract] [type]? [[methodDeclarator]] [[methodThrowsExceptions]]? ;

abstractMethodDeclaration : [type] [[methodDeclarator]] ;

//queuedMethodDeclaration- : queued [[methodDeclarator]] [[methodThrowsExceptions]]? [[methodBody]]
methodBody- : ( [[codeLangs]] { ( [[precondition]]
    | [[postcondition]]
    | [[assertion]]|[[testCase]] )* [**code] } )+

methodDeclarator : [methodName] [[parameterList]]

methodThrowsExceptions : throws [~exception] ( , [~exception] )*

parameterList : ( ([[parameter]] ( , [[parameter]] )* )? )

parameter : [[typedName]]


testCase : [=isTimed:before|after]? [=isConcrete:JUnit|PhpUnit|RubyUnit]? [=isOverride:override]? test [~testCaseName] { ( [[assertion]]
    | [[testAction]]
    | [[testInit]]
    | [[testInitAtt]]
    | [[testInitAttWithMethodCall]]
    | [[comment]]
    | [[reqImplementation]]
    | [[ifStatement]]
    | [[forStatement]] )* }

assertion : [=isTimed:before
    |after]? [=assertType:assertTrue
    |assertFalse
    |assertEqual
    |assertNull
    |assertMethod] [**code] ;

testAction : [~objectName] ( (.)[~methodName] )? ( [[testActionParameterList]] ) ;

testMethodCall : [~objectName] ( (.)[~methodName] )? ( [[testActionParameterList]] )

testActionParameterList : [[testParameter]]?

testParameter : [[pValue]] ( , [[pValue]] )*

testInit : [~identifier] [~objectName] ( [[testParameter]]? ) ;

testInitAtt : [~identifier]? [~attributeName] = [[pValue]] ;

testInitAttWithMethodCall : [~identifier]? [~attributeName] = [[testMethodCall]] ;

//paraTestAction : [~methodName] OPEN_ROUND_BRACKET ( [[pValue]] ( , [[pValue]] ) )* CLOSE_ROUND_BRACKET
pValue- : ( [name] | "[name]" )

interfaceTest : test [~testName] ;

testSequence : testSequence [~sequenceName] { [[testSequenceEntry]] }

testSequenceEntry : [~name] ( -> [~name] )* ;


//top-level initialization

testClassInit : test init { [**code] }



// Generic test case rules
genericTestCase : generic test [~testCaseName] ( [[genericElement]] ) { ( [**code] )* }

genericElement- : [elementType] [=genericElement:attribute
    |method
    |association] [[elementFix]]? [[genericMethodParameters]]?

genericMethodParameters- : [~elementType] ( , [~elementType] )*

elementFix : (.) [=fixType:prefix
    |suffix
    |regex] ( [fixValue] )


//testcase if statement
ifStatement : if ( [**condition] ) { [**code] } [[ifElseStatement]]* [[elseStatement]]?

ifElseStatement : if else ( [**condition] ) { [**code] }

elseStatement : else { [**code] }


// for statement
forStatement : for ( [**forCode] ) { [**code] }





// Details of associations: See manual page AssociationDefinition

association : [=modifier:immutable]? [[associationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

symmetricReflexiveAssociation : [[multiplicity]] self [roleName] ;

inlineAssociation : [=modifier:immutable]? [[inlineAssociationEnd]] [=arrow:--
    |->
    |<-
    |><
    |<@>-
    |-<@>] [[associationEnd]] ;

inlineAssociationEnd : [[multiplicity]] [~roleName]? [[isSorted]]?

singleAssociationEnd : [[multiplicity]] ( ( [otherEndroleName] [type] [roleName] )
    | ( [type] [~roleName]? ) ) ;


associationEnd : [[multiplicity]] [type] [~roleName]? [[isSorted]]?

multiplicity- : [!lowerBound:\d+|[**]] .. [!upperBound:\d+|[**]] | [!bound:\d+|[**]]

isSorted- : sorted { [priority] }


// Details of attributes. See user manual page AttributeDefinition
attribute : [[simpleAttribute]]
    | [[autouniqueAttribute]]
    | [[multivaluedAttribute]]
    | [[derivedAttribute]]
    | [[complexAttribute]]

simpleAttribute- : [~name] ;

autouniqueAttribute- : [=autounique] [~name] ;

multivaluedAttribute- : [=unique]? [=lazy]? [=ivar]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [type]? [[list]] [~name] (= { [**value] })? ;

derivedAttribute- : [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] = ( [[moreCode]] )+

complexAttribute- : [=unique]? [=lazy]? [=ivar]? [=modifier:immutable
    |settable
    |internal
    |defaulted
    |const
    |fixml]? [[typedName]] (= [**value])? ;



// Keys are used to define quality and hash codes, plus Sql keys.
// See user manual page KeysforEqualityandHashing
defaultKey : key { }

key : key { [keyId] ( , [keyId] )* }


// Depend clause. See user manual page Dependclause
depend- : depend [depend] ;


// Anything inside a class that is not parsable by Umple is passed on to the base language
// compiler. To raise warnings when this occurs, use the strictness directive.
extraCode- : [**extraCode]


list- : [!list:\[\s*\]]

baseType- : [!baseType:[a-zA-Z0-9_$]+]

nestedType- : [[baseType]] ( < [[argType]] > )?

argType- : ( ? | [[nestedType]] [[list]]? ) ( , [[argType]] )?

type : [[nestedType]] ( ... )?

typedName- : [[type]]? [[list]]? [~name]

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/trait/umple_traits.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

traitDefinition : trait [name] [[traitParameters]]? { [[traitContent]]* }

traitContent- : [[mixsetDefinition]]
    | [[testCase]]
    | [[requiredModelElements]]
    | [[comment]]
    | [[reqImplementation]]
    | [[traitDefinition]]
    | [[trace]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[stateMachine]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[abstractMethodDeclaration]]
    | [[constantDeclaration]]
    | [[invariant]]
    | ;
    | [[exception]]
    | [[extraCode]]

traitParameters : < [[traitFullParameters]] ( , [[traitFullParameters]] )* >

traitFullParameters : [~parameter] ([[traitParametersInterface]])? ( = [~defaultType] )?

traitParametersInterface- : isA [~tInterface]( & [~tInterface])*

requiredModelElements : require ([[requiredState]] | [[requiredEvent]])

requiredState : [smName] ;

//.[~stateName](.[~stateName])* ;
requiredEvent : [smName] ( ( [parameter] ( , [parameter] )* )? ) ;

//.[~stateName](.[~stateName])*


//iE = Include Exclude
AllInclusionExclusionAlias- : [[InclusionExclusionAlias]] ( , [[InclusionExclusionAlias]] )*

InclusionExclusionAlias- : [[functionIncludeExcludeAlias]] | [[StateMachineIncludeExcludeAlias]]

functionIncludeExcludeAlias- : [[functionInExAlias]] ( , [[functionInExAlias]] )*

functionInExAlias- : [[functionAliasName]] | [[iEFunction]] | [[traitAppliedParameters]]

iEFunction : [=modifier:+|-] [~methodName] [[iEParameterList]]

iEParameterList : ( ( [parameter] ( , [parameter] )* )? )

functionAliasName : [=modifier:+]? ( ( [~smName]
    | [!smPattern:\d+|[**]]) .)? [~methodName] [[iEParameterList]] as [[IEVisibilityAlias]]


IEVisibilityAlias- : ([[IEVisibility]] [~aliasName]?) | ([~aliasName])

IEVisibility- : [=iEVisibility:public|private|protected]

traitAppliedParameters : [~pName] = [~rName]


StateMachineIncludeExcludeAlias- : [[ StateMachineInExAlias]] ( , [[StateMachineInExAlias]] )*

StateMachineInExAlias- : [[StateMachineAliasName]] | [[iEStateMachine]]

//| [[StateMachineTransitionAlias]]
StateMachineAliasName : ([=iEStateMachineModifier:+])? [~smName] ([[StateNames]])? as [~smDesName] ([[DesStateNames]])?

StateNames : . [~sName] ( [[StateNamesPassing]] )*

DesStateNames :[[StateNames]]

StateNamesPassing : [[StateNames]]

//iEStateMachine : [=iEStateMachineModifier:+|-] [~smName] [[StateNames]]?
iEStateMachine : [=modifier:+|-] [~smName] ( [[StateNames]] ( ( [[iEParameterList]] [[guardOption]]? )
    | ( . [[guardOption]] ) )? )?

guardOption : [[guard]] | []

//This is for events in state machines
//StateMachineTransitionAlias : ( [~smName] | [!smPattern:\d+|[*]]) . [~eventName] [[iEParameterList]] as [~AliasName]
// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/fixml/umple_fixml.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

//This is Umple's grammar for parsing fixml documents (add add-on feature)
fixml : [[fixmlDefinition]] | [[fixmComment]] | [[fixmlDoc]]

fixmlDoc : <! [**value] >

fixmComment : <?xml [[tagDefinition]]* ?>

fixmlDefinition : <FIXML> [[fixmlContent]]* </FIXML>

fixmlContent : [[endContent]] | [[ extendContent ]]

endContent : < [~name] ( [[tagDefinition]] )* />

extendContent : < [~name] ( [[tagDefinition]] )* > ( [[endContent]]
    | [[extendContent]]
    | [[attContent]])* < ( / ) [~name] >

tagDefinition : [name] = "[**value]"

attContent : < [~name] > [**value:\<] < ( / ) [~name] >

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/strcture/umple_structure.grammar
//@author Ahmed M.Orabi {@link ahmedvc@hotmail.com}
//@author Mahmoud M.Orabi {@link mahmoud_3rabi@hotmail.com}

primitiveDefinition : primitive [name] { [[primitiveBody]]* }

primitiveBody- : [[isA]] | [[constraint]]


// Port Definition
portName : ( [~classname] . )? [name]

portMultiplicity : [!portMultiplicity:\[[0-9]+\]]


typedPortName : [~type]? [~portName] [[portMultiplicity]]?


portDefinition : [[portClass]] | [[portDeclaration]]

portClass- : [=port] ;

portDeclaration : [=modifier:public
    |protected
    |private]? [=inverse:conjugated]? [!direction:(in
    |out
    |port)\s] ( [[typedPortName]] ) ;


// Port Connectors
portBindingDefinition : ( [~fromClassname] . )? [fromPort] -> ( [~toClassname] . )? [toPort] [[bindinHandler]]

bindinHandler : { [**code] } | ;


// Port Watchlist Definition
portWatch- : ( [[constraintList]] | [[comment]] | [[reqImplementation]] )*


// Active Method Definition
activeMethodDefinition : [[portWatch]]? [=modifier:public
    |protected
    |private]? [type]? [=activeType:atomic
    |synchronous
    |intercept]? [=active] [[activeMethodDeclarator]] [[activeMethodBody]]+

activeMethodDeclarator : [~methodName] [[parameterList]]?


//activeMethodBody : [[activeDirectionHandler]] { ( [[activeTrigger]] )* [**code] }
activeMethodBody : [[activeMethodBodyContent]] [[inverseDirectionHandler]]?

inverseDirectionHandler : -> [[portWatch]]? [[activeMethodDeclarator]] [[activeMethodBodyContent]]

activeMethodBodyContent : { ( [[comment]] | [[reqImplementation]] | [[activeTrigger]] | [**code] )* }


activeTrigger : [[hitchConstraint]]? [[constraintList]]? [=trigger:/] [[activeTriggerBody]] [[thenDefinition]]? [[resolveDefinition]]?

activeTriggerBody- : ( [[deferredList]] | [[activeTriggerDefinition]] )

deferredList : [ [[activeTriggerDefinition]] ( , [[activeTriggerDefinition]] )* ]

activeTriggerDefinition- : [[anonymousTriggerBody]] | [[invoke]]


thenDefinition : .then ( [[anonymousTriggerBody]]? )

resolveDefinition : .resolve ( [[anonymousTriggerBody]]? )


hitchConstraint : [=clause:after|poll] ( [timer] )

constraintList : [ [[basicConstraint]] ( , [[basicConstraint]] )* ]

basicConstraint- : [[timeConstraint]] | [[messageConstraint]] | [[constraint]]

timeConstraint : [=clause:latency|period|timeout] ( [timer] )

messageConstraint : [=clause:priority] ( [priorityValue] )

invoke : ( [~classname] . )? [name] ( ( [parameter] ( , [parameter] )* )? ) ;

anonymousTriggerBody : { [**code] }


// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/template/umple_template.grammar
//@author Ahmed M.Orabi {@link ahmedvc@hotmail.com}
//@author Mahmoud M.Orabi {@link mahmoud_3rabi@hotmail.com}

// Template capabilities are a sublanguage of Umple.
// See user manual page: BasicTemplates

templateDefinition : template [name] { [[templateContent]]* }

templateContent- : [[comment]]
    | [[emitMethod]]
    | [[templateAttributeDefinition]]
    | [[trace]]
    | [[position]]
    | [[displayColor]]
    | [[abstract]]
    | [[keyDefinition]]
    | [[softwarePattern]]
    | [[depend]]
    | [[symmetricReflexiveAssociation]]
    | [[attribute]]
    | [[templateAttribute]]
    | [[stateMachine]]
    | [[inlineAssociation]]
    | [[concreteMethodDeclaration]]
    | [[constantDeclaration]]
    | [[invariant]]
    | ; |[[exception]]
    | [[extraCode]]



templateAttributeDefinition : [[templateName]] [[templateAttribute]]

templateName : ( [~classname] . )? [name] [[templateParameters]]?

templateParameters : ( [[templateParameter]] ( , [[templateParameter]] )* )

templateParameter- : [parameter] | " [**parameter] "


emitMethod : [=modifier:public
    |protected
    |private]? [=static]? [type]? [=emit] [[methodDeclarator]] [[templateList]]?;

templateList- : ( ( [[templateName]] ( , [[templateName]] )* )? )


templateAttribute# : <<! [[templateAttributeContent]]* !>>

templateAttributeContent- : [[templateExpression]]
    | [[templateComment]]
    | [[templateCodeBlock]]
    | [[templateExactSpaces]]
    | [[templateInclude]]
    | [[templateText]]

templateText# : [**templateTextContent:<<(=|#|/[*]|$|@)]


templateComment# : <</* [**templateCommentContent] */>>

templateExpression# : <<= ( [[templateExpression]]
    | [**templateExpressionContent:<<(=|#|/[*]|$|@)] )+ >>

templateCodeBlock# : <<# ( [[templateExpression]] | [**templateLanguageCode:<<(=|#|/[*]|$|@)] )* #>>

templateExactSpaces# : <<$ [**templateExactSpacesContent] >>

templateInclude# : <<@ [[templateName]] >>

//templateOpen- : <
//templateClose- : !>>

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/stateMachine/umple_state_machines.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// State machine elements in Umple. See user manual page: BasicStateMachines
stateMachineDefinition : statemachine [=queued]? [=pooled]? [name] { [[state]]* }

stateMachine : [[enum]]
    | [[inlineStateMachine]]
    | [[referencedStateMachine]]
    | [[activeDefinition]]


activeDefinition : [=active] [[codeLangs]] [name]? [[moreCode]]+


//Issue 148
inlineStateMachine : [=queued]? [=pooled]? [~name] { ( [[comment]]
    | [[state]]
    | [[trace]]
    | [[mixsetDefinition]]
    | [=||]
    | [[standAloneTransition]])* }

referencedStateMachine : [name] as [definitionName] ( { [[extendedStateMachine]] } | ; )


//Issue 547 and 148
extendedStateMachine# : ( [[comment]]
    | [=changeType:+| - |- |*]? [[state]]
    | [[standAloneTransition]] )*


// An enum is a state machine that has no events
// stateName is prefixed with ~ to match alphanumeric names only.
// This is needed to solve issue 399, which is cause when a terminating } is parsed as part of the statename.
enum : [~name:key] { [~stateName]? (, [~stateName])* }


state : [=final]? [stateName] { [[stateInternal]]* }


//Issue 547 and 148
stateInternal-# : [[comment]]
    | [=changeType:+| - |- |*]? [[stateEntity]]
    | [[standAloneTransition]]
    | [[concreteMethodDeclaration]]
    | [**extraCode]

stateEntity- : [=||]
    | [[mixsetDefinition]]
    | [[entryOrExitAction]]
    | [[autoTransition]]
    | [[transition]]
    | [[activity]]
    | [[state]]
    | [[displayColor]]
    | [[trace]]
    | ;


autoTransition : [[activity]]? [[autoTransitionBlock]]


// Autotransitions have no event. The transition is immediately taken
// or taken after the do activity ends[[guard]]? -> [[action]]?
// The action can come before or after the arrow
autoTransitionBlock- : [[guard]]? ( [[action]] -> | -> [[action]] | -> ) [stateName] ;


// A transition guard can come before or after the arrow
// The order of guard and event definition can also be interchanged
transition : ( [[eventDefinition]] [[guard]]
    | [[guard]] [[eventDefinition]]
    | [=unspecified]? [[guard]]
    | [[eventDefinition]])? ( [[action]] ->
    | -> [[action]]
    | -> ) [stateName] ;


//Issue148
standAloneTransition : ( [[eventDefinition]] [[guard]]
    | [[guard]] [[eventDefinition]]
    | [=unspecified]? [[guard]]
    | [[eventDefinition]])? [~fromState] ( [[action]] ->
    | -> [[action]]
    | -> ) [~toState] ;


eventDefinition- : [[afterEveryEvent]] | [[afterEvent]] | [~event] ( [[parameterList]] )?


// The timer in a timed event can be an number, variable, function() or function(num)
afterEveryEvent- : afterEvery ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )

afterEvent- : after ( [!timer:[+*/a-zA-Z0-9_\.-]+(\([0-9\.]*\))?] )


// An action can be executed on a transition, or on entry or exit
action : / [[moreCode]]+

entryOrExitAction : [=type:entry|exit] [[guardCode]]? / [[moreCode]]+


guardCode :[ [**code] ]


// A do activity is long-lasting and can be interrupted
activity : do [[moreCode]]+


guard : [ [[constraint]] ]

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/trace/umple_traces.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Trace capabilities of the MOTL sublanguage of Umple.
// See user manual page: ModelOrientedTracingLanguage(MOTL)

// ======= TRACER
// ======= grammar rules - The tool to output the trace: Tracers
tracerDirective : tracer [tracerType] [[tracerOptions]] ;

tracerOptions- : [[logConfig]]* [[traceMessageHeader]]? [tracerArgument]?

logConfig : (root = [rootLevel])
    | (monitorInterval = [monitorInterval])
    | ( [logLevel] ( , [logLevel] )* = [logAppender] ( , [logAppender] )* )

traceMessageHeader : [=switch:on|off] : [option] ( , [option] )*


// ======= TRACE
// ======= grammar rules

trace : [[traceDirective]] | [[traceCase]]


traceDirective : trace [[Prefix]]? [[traceEntity]] [[Postfix]] ;


traceEntity- : [traceEntity] (()? ())? ( , [traceEntity] (()? ())? )*


Prefix : [[PrefixOption]] ( , [[PrefixOption]] )*

PrefixOption- : [=option:set|get|in|out|entry|exit|cardinality|add|remove]


Postfix- : ( [[traceCondition]]
    |[[traceFor]]
    |[[tracePeriod]]
    |[[traceDuring]]
    |[[traceLevel]]
    |[[traceRecord]]
    |[[executeClause]]
    |[[logLevel]]
    |[[traceCaseActivation]] )*

traceCondition : [=conditionType:where|until|after|giving]? [ [[constraintToken]] ]

traceFor- : for [traceFor]

tracePeriod- : period [tracePeriod]

traceDuring- : during [traceDuration]

traceLevel- : level [traceLevel]

traceRecord- : record [[recordEntity]]

recordEntity- : ( only )? ( " [**recordString] " | [traceRecord] ) ( , [traceRecord] )*

logLevel- : logLevel [[logLevelOption]] ( , [[logLevelOption]] )*

logLevelOption- : [=logLevel:trace
    |debug
    |info
    |warn
    |error
    |fatal
    |all
    |finest
    |finer
    |fine
    |config
    |warning
    |severe]

executeClause- : execute { [**traceExecute] }


traceCase : [[traceCaseDef]] | [[traceCaseActivation]] | [[traceCaseDeactivation]]

traceCaseDef- : tracecase [tracecase_name] { [[traceDirective]]* }

traceCaseActivation- : activate [tracecase_act_name] (onAllObjects | onThisThreadOnly)? ;

traceCaseDeactivation- : deactivate [tracecase_deact_name] onThisObject [[deActivateFor]]? ;

deActivateFor- : for [deactivate_for]



//--------- Old rules (left as reference) ---------
//++Tracer
//traceType : tracer [tracerType] ( [=onoff:on|off] : [[tracerOptions]] ( , [[tracerOptions]] )* )* ( [=verbisty:verbose] )? ( [tracerArgument] )* [[log4jConfig]]* ([[tracerOptions]])* ;
//traceType : tracer [tracerType] ( , [tracerType] )* [[log4jConfig]]* ([[tracerOptions]])* ;
//traceType : tracer [=tracerType:Console|File|String|Visual] ( , [=tracerType:Console|File|String|Visual] )* ( [=onoff:on|off] : [[tracerOptions]] ( , [[tracerOptions]] )* )* ( [=verbisty:verbose] )? ( [tracerArgument] )* ;
//tracerOptions- : [[tracerOn]]? [=option:Time|time|Thread|thread|File|file|Line|line|Trace|trace|Trigger|trigger|TraceFile|tracefile|TraceLine|traceline|TriggerLine|triggerline|TriggerFile|triggerfile|Class|class|Object|object|Operation|operation|Name|name|Value|value] [=option:Time|time|Thread|thread|File|file|Line|line|Trace|trace|Trigger|trigger|TraceFile|tracefile|TraceLine|traceline|TriggerLine|triggerline|TriggerFile|triggerfile|Class|class|Object|object|Operation|operation|Name|name|Value|value]*
//tracerOn : on:|off:
//log4jConfig : (root = [rootLevel]) | (monitorInterval = [monitorInterval]) | (OPEN_ROUND_BRACKET) [log4jLevel] ( , [log4jLevel] )* (CLOSE_ROUND_BRACKET) = (OPEN_ROUND_BRACKET) [log4jAppender] ( , [log4jAppender] )* (CLOSE_ROUND_BRACKET)
//--------------------------------------------------
// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/layout/umple_layout.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// Layout elements are injected into classes as mixins by diagramming tools such
// as UmpleOnline. Programmers can tweak the layout textually.
position- : [[associationPosition]] | [[elementPosition]]

elementPosition : position [x] [y] [width] [height] ;

associationPosition : position.association [name] [[coordinate]] [[coordinate]] ;

coordinate : [x] , [y]

displayColor : ( displayColor | displayColour ) [**colorValue] ;

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/filter/umple_filter.grammar
//
// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

// This feature allows drawing diagrams of part of a model

filter : filter ( [filterName] )? { ([[filterStatement]])* }


filterStatement- : [[filterCombinedValue]] | [[filterNamespace]] | [[filterValue]] | [[hops]]


hops- : hops {([[super]] | [[sub]] | [[association]])*}


filterValue : include ([classname]) ( , [classname] )*;


super : super [superNum];


sub : sub [subNum];


association : association [associationNum];


filterNamespace : namespace [Namespace] (, [Namespace])* ;


filterCombinedValue : includeFilter ([filterName]) ( , [filterName] )*;

// The master of this part of the Umple grammar is available at
// https://github.com/umple/umple/blob/master/cruise.umple/src/mixset/umple_mixsets.grammar

// Copyright: All contributors to the Umple Project
// This file is made available subject to the open source license found at:
// http://umple.org/license

//Mixsets allow creation of mixins composed from multiple locations plus some constraints regarding usage of these mixins.
// See user manual page BasicMixsets

mixsetDefinition : mixset [mixsetName] ( [[mixsetInnerContent]]
    | [[requirement]]
    | [[mixsetInlineDefinition]] )

mixsetInnerContent- : { [[extraCode]] | [[reqImplementation]] }


mixsetInlineDefinition- : ( [entityType] [entityName] ( [[mixsetInnerContent]]
    | [entityOneElement] )
    | [oneElement] )


// Specialize a mixset to be a feature.
mixsetIsFeature : isFeature


// require statement allows adding dependencies between mixsets.

requireStatement : require ( [=subfeature] )? [[requireBody]]


requireBody- : [(([[requireLinkingOptNot]])? (()* [[requireTerminal]] [[requireList]])]


requireList- : ([[requireLinkingOp]] (()* [[requireTerminal]] ())* )*


requireLinkingOp : ([[requireLinkingOptNot]]
    | [=and:&|&&|and|,]
    | [!or:([|][|]?|or|;)]
    | [=xor:xor|XOR])


requireLinkingOptNot- : ([=opt:opt] | [=not:not] )


requireTerminal : [~targetMixsetName] | [[multiplicityTerminal]]


multiplicityTerminal- : [[multiplicity]] of { [~targetMixsetName] (, [~targetMixsetName] )* }