/
umple_classes.grammar
128 lines (101 loc) · 8.2 KB
/
umple_classes.grammar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// The master of this second part of the Umple grammar is available at
// [*https://github.com/umple/umple/blob/master/cruise.umple/src/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]] | [[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]] | [[innerClass]] | [[mixsetDefinition]] | [[distributable]] | [[proxyPattern]] | [[classDefinition]] | [[trace]] | [[emitMethod]] | [[templateAttributeDefinition]] | [[primitiveDefinition]] | [[portDefinition]] | [[portBindingDefinition]] | [[position]] | [[displayColor]] | [[abstract]] | [[keyDefinition]] | [[softwarePattern]] | [[depend]] | [[symmetricReflexiveAssociation]] | [[attribute]] | [[testCase]] | [[genericTestCase]] | [[testSequence]] | [[stateMachine]] | [[activeMethodDefinition]] | [[inlineAssociation]] | [[concreteMethodDeclaration]] | [[constantDeclaration]] | [[modelConstraint]] | [[invariant]] | ; | [[enumerationDefinition]] | [[exception]] | [[extraCode]]
associationClassContent- : [[comment]] | [[classDefinition]] | [[position]] | [[displayColor]] | [[invariant]] | [[softwarePattern]] | [[depend]] | [[association]] | [[inlineAssociation]] | [[singleAssociationEnd]] | [[attribute]] | [[stateMachine]] | ; | [[extraCode]]
innerClass : [[innerStaticClass]] | [[innerNonStaticClass]]
innerStaticClass : static [[classDefinition]]
innerNonStaticClass : inner [[classDefinition]]
// 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]] | [[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])? ;
//TODO Should we use modifier for concrete methods [=modifier:public|protected|private]?
//TODO Should we use modifier for abstract methods [=modifier:public|protected|abstract|final]?
distributable- : [=distributable:distributable] [=distributeTech:RMI|WS]? ;
proxyPattern- : [=proxyPattern:proxyPattern] ;
moreCode- : [[codeLangs]] { [**code] }
codeLangs- : ([=codeLang:Java|RTCpp|SimpleCpp|Cpp|Php|Ruby|Alloy|UmpleSelf] ( , [=codeLang:Java|Alloy|RTCpp|SimpleCpp|Cpp|Php|Ruby|UmpleSelf] )* )?
// Methods: The code in concrete methods is passed to the base language
// See user manual page [*MethodDefinition*]
concreteMethodDeclaration : [=modifier:public|protected|private]? [=static]? [=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 : OPEN_ROUND_BRACKET ([[parameter]] ( , [[parameter]] )* )? CLOSE_ROUND_BRACKET
parameter : [[typedName]]
testCase : [=isTimed:before|after]? [=isConcrete:JUnit|PhpUnit|RubyUnit]? [=isOverride:override]? test [~testCaseName] { ( [[assertion]] | [[testAction]] | [[testInit]] | [[testInitAtt]] | [[testInitAttWithMethodCall]] | [[comment]] )* }
assertion : [=isTimed:before|after]? [=assertType:assertTrue|assertFalse|assertEqual|assertNull|assertMethod] OPEN_ROUND_BRACKET [**code] CLOSE_ROUND_BRACKET ;
testAction : [~objectName] ( (.)[~methodName] )? OPEN_ROUND_BRACKET [[testActionParameterList]] CLOSE_ROUND_BRACKET ;
testMethodCall : [~objectName] ( (.)[~methodName] )? OPEN_ROUND_BRACKET [[testActionParameterList]] CLOSE_ROUND_BRACKET
testActionParameterList : [[testParameter]]?
testParameter : [[pValue]] ( , [[pValue]] )*
testInit : [~identifier] [~objectName] OPEN_ROUND_BRACKET [[testParameter]]? CLOSE_ROUND_BRACKET ;
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] )* ;
// Generic test case rules
genericTestCase : generic test [~testCaseName] OPEN_ROUND_BRACKET [~genericElement] CLOSE_ROUND_BRACKET { ( [**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]