-
-
Notifications
You must be signed in to change notification settings - Fork 202
Expand file tree
/
Copy pathumple_classes.grammar
More file actions
145 lines (113 loc) · 9.24 KB
/
umple_classes.grammar
File metadata and controls
145 lines (113 loc) · 9.24 KB
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// 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:
// [*https://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_ROUND_BRACKET | CLOSE_ROUND_BRACKET | 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])? ;
//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|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 : 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]] | [[reqImplementation]] | [[ifStatement]] | [[forStatement]] )* }
assertion : [=isTimed:before|after]? [=assertType:assertTrue|assertFalse|assertEqual|assertNull|assertMethod] [**code] ;
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] )* ;
//top-level initialization
testClassInit : test init { [**code] }
// Generic test case rules
genericTestCase : generic test [~testCaseName] OPEN_ROUND_BRACKET [[genericElement]] CLOSE_ROUND_BRACKET { ( [**code] )* }
genericElement- : [elementType] [=genericElement:attribute|method|association] [[elementFix]]? [[genericMethodParameters]]?
genericMethodParameters- : [~elementType] ( , [~elementType] )*
elementFix : (.) [=fixType:prefix|suffix|regex] OPEN_ROUND_BRACKET [fixValue] CLOSE_ROUND_BRACKET
//testcase if statement
ifStatement : if OPEN_ROUND_BRACKET [**condition] CLOSE_ROUND_BRACKET { [**code] } [[ifElseStatement]]* [[elseStatement]]?
ifElseStatement : if else OPEN_ROUND_BRACKET [**condition] CLOSE_ROUND_BRACKET { [**code] }
elseStatement : else { [**code] }
// for statement
forStatement : for OPEN_ROUND_BRACKET [**forCode] 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]