sysmlpy 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. sysmlpy/__init__.py +226 -0
  2. sysmlpy/__main__.py +75 -0
  3. sysmlpy/antlr/README.md +146 -0
  4. sysmlpy/antlr/SysMLv2Lexer.interp +695 -0
  5. sysmlpy/antlr/SysMLv2Lexer.py +1123 -0
  6. sysmlpy/antlr/SysMLv2Lexer.tokens +444 -0
  7. sysmlpy/antlr/SysMLv2Parser.interp +960 -0
  8. sysmlpy/antlr/SysMLv2Parser.py +40750 -0
  9. sysmlpy/antlr/SysMLv2Parser.tokens +444 -0
  10. sysmlpy/antlr/SysMLv2ParserListener.py +4485 -0
  11. sysmlpy/antlr/SysMLv2ParserVisitor.py +2498 -0
  12. sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +695 -0
  13. sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.py +1123 -0
  14. sysmlpy/antlr/src/sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +444 -0
  15. sysmlpy/antlr_parser.py +185 -0
  16. sysmlpy/antlr_visitor.py +10864 -0
  17. sysmlpy/definition.py +1115 -0
  18. sysmlpy/examples/attribute_values.py +161 -0
  19. sysmlpy/examples/part_attributes.py +139 -0
  20. sysmlpy/examples/tuples_sequences.py +231 -0
  21. sysmlpy/formatting.py +47 -0
  22. sysmlpy/grammar/antlr4/README.md +30 -0
  23. sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 +931 -0
  24. sysmlpy/grammar/antlr4/SysMLv2Lexer.interp +695 -0
  25. sysmlpy/grammar/antlr4/SysMLv2Lexer.py +1123 -0
  26. sysmlpy/grammar/antlr4/SysMLv2Lexer.tokens +444 -0
  27. sysmlpy/grammar/antlr4/SysMLv2Parser.g4 +2432 -0
  28. sysmlpy/grammar/antlr4/SysMLv2Parser.interp +960 -0
  29. sysmlpy/grammar/antlr4/SysMLv2Parser.py +40750 -0
  30. sysmlpy/grammar/antlr4/SysMLv2Parser.tokens +444 -0
  31. sysmlpy/grammar/antlr4/SysMLv2ParserListener.py +4485 -0
  32. sysmlpy/grammar/antlr4/SysMLv2ParserVisitor.py +2498 -0
  33. sysmlpy/grammar/antlr4/desc.xml +7 -0
  34. sysmlpy/grammar/antlr4/examples/camera.sysml +14 -0
  35. sysmlpy/grammar/antlr4/examples/toaster-system.sysml +193 -0
  36. sysmlpy/grammar/antlr4/examples/vehicle-model.sysml +118 -0
  37. sysmlpy/grammar/antlr4/pom.xml +59 -0
  38. sysmlpy/grammar/classes.py +8610 -0
  39. sysmlpy/library/LICENSE +165 -0
  40. sysmlpy/library/README.md +52 -0
  41. sysmlpy/library/__init__.py +0 -0
  42. sysmlpy/library/domain/Analysis/AnalysisTooling.sysml +34 -0
  43. sysmlpy/library/domain/Analysis/SampledFunctions.sysml +119 -0
  44. sysmlpy/library/domain/Analysis/StateSpaceRepresentation.sysml +143 -0
  45. sysmlpy/library/domain/Analysis/TradeStudies.sysml +171 -0
  46. sysmlpy/library/domain/Cause and Effect/CausationConnections.sysml +83 -0
  47. sysmlpy/library/domain/Cause and Effect/CauseAndEffect.sysml +81 -0
  48. sysmlpy/library/domain/Geometry/ShapeItems.sysml +899 -0
  49. sysmlpy/library/domain/Geometry/SpatialItems.sysml +168 -0
  50. sysmlpy/library/domain/Metadata/ImageMetadata.sysml +78 -0
  51. sysmlpy/library/domain/Metadata/ModelingMetadata.sysml +143 -0
  52. sysmlpy/library/domain/Metadata/ParametersOfInterestMetadata.sysml +39 -0
  53. sysmlpy/library/domain/Metadata/RiskMetadata.sysml +100 -0
  54. sysmlpy/library/domain/Quantities and Units/ISQ.sysml +42 -0
  55. sysmlpy/library/domain/Quantities and Units/ISQAcoustics.sysml +439 -0
  56. sysmlpy/library/domain/Quantities and Units/ISQAtomicNuclear.sysml +2726 -0
  57. sysmlpy/library/domain/Quantities and Units/ISQBase.sysml +206 -0
  58. sysmlpy/library/domain/Quantities and Units/ISQCharacteristicNumbers.sysml +1991 -0
  59. sysmlpy/library/domain/Quantities and Units/ISQChemistryMolecular.sysml +1353 -0
  60. sysmlpy/library/domain/Quantities and Units/ISQCondensedMatter.sysml +1223 -0
  61. sysmlpy/library/domain/Quantities and Units/ISQElectromagnetism.sysml +2333 -0
  62. sysmlpy/library/domain/Quantities and Units/ISQInformation.sysml +958 -0
  63. sysmlpy/library/domain/Quantities and Units/ISQLight.sysml +1537 -0
  64. sysmlpy/library/domain/Quantities and Units/ISQMechanics.sysml +1564 -0
  65. sysmlpy/library/domain/Quantities and Units/ISQSpaceTime.sysml +1169 -0
  66. sysmlpy/library/domain/Quantities and Units/ISQThermodynamics.sysml +1256 -0
  67. sysmlpy/library/domain/Quantities and Units/MeasurementRefCalculations.sysml +30 -0
  68. sysmlpy/library/domain/Quantities and Units/MeasurementReferences.sysml +526 -0
  69. sysmlpy/library/domain/Quantities and Units/Quantities.sysml +107 -0
  70. sysmlpy/library/domain/Quantities and Units/QuantityCalculations.sysml +70 -0
  71. sysmlpy/library/domain/Quantities and Units/SI.sysml +378 -0
  72. sysmlpy/library/domain/Quantities and Units/SIPrefixes.sysml +48 -0
  73. sysmlpy/library/domain/Quantities and Units/TensorCalculations.sysml +50 -0
  74. sysmlpy/library/domain/Quantities and Units/Time.sysml +274 -0
  75. sysmlpy/library/domain/Quantities and Units/USCustomaryUnits.sysml +260 -0
  76. sysmlpy/library/domain/Quantities and Units/VectorCalculations.sysml +62 -0
  77. sysmlpy/library/domain/Requirement Derivation/DerivationConnections.sysml +63 -0
  78. sysmlpy/library/domain/Requirement Derivation/RequirementDerivation.sysml +39 -0
  79. sysmlpy/library/kernel/Base.kerml +95 -0
  80. sysmlpy/library/kernel/BaseFunctions.kerml +80 -0
  81. sysmlpy/library/kernel/BooleanFunctions.kerml +22 -0
  82. sysmlpy/library/kernel/Clocks.kerml +156 -0
  83. sysmlpy/library/kernel/CollectionFunctions.kerml +68 -0
  84. sysmlpy/library/kernel/Collections.kerml +147 -0
  85. sysmlpy/library/kernel/ComplexFunctions.kerml +47 -0
  86. sysmlpy/library/kernel/ControlFunctions.kerml +117 -0
  87. sysmlpy/library/kernel/ControlPerformances.kerml +135 -0
  88. sysmlpy/library/kernel/DataFunctions.kerml +43 -0
  89. sysmlpy/library/kernel/FeatureReferencingPerformances.kerml +190 -0
  90. sysmlpy/library/kernel/IntegerFunctions.kerml +43 -0
  91. sysmlpy/library/kernel/KerML.kerml +483 -0
  92. sysmlpy/library/kernel/Links.kerml +67 -0
  93. sysmlpy/library/kernel/Metaobjects.kerml +58 -0
  94. sysmlpy/library/kernel/NaturalFunctions.kerml +27 -0
  95. sysmlpy/library/kernel/NumericalFunctions.kerml +43 -0
  96. sysmlpy/library/kernel/Objects.kerml +212 -0
  97. sysmlpy/library/kernel/Observation.kerml +161 -0
  98. sysmlpy/library/kernel/OccurrenceFunctions.kerml +154 -0
  99. sysmlpy/library/kernel/Occurrences.kerml +992 -0
  100. sysmlpy/library/kernel/Performances.kerml +293 -0
  101. sysmlpy/library/kernel/RationalFunctions.kerml +49 -0
  102. sysmlpy/library/kernel/RealFunctions.kerml +56 -0
  103. sysmlpy/library/kernel/ScalarFunctions.kerml +33 -0
  104. sysmlpy/library/kernel/ScalarValues.kerml +23 -0
  105. sysmlpy/library/kernel/SequenceFunctions.kerml +111 -0
  106. sysmlpy/library/kernel/SpatialFrames.kerml +197 -0
  107. sysmlpy/library/kernel/StatePerformances.kerml +145 -0
  108. sysmlpy/library/kernel/StringFunctions.kerml +25 -0
  109. sysmlpy/library/kernel/Transfers.kerml +281 -0
  110. sysmlpy/library/kernel/TransitionPerformances.kerml +66 -0
  111. sysmlpy/library/kernel/TrigFunctions.kerml +35 -0
  112. sysmlpy/library/kernel/Triggers.kerml +188 -0
  113. sysmlpy/library/kernel/VectorFunctions.kerml +273 -0
  114. sysmlpy/library/kernel/VectorValues.kerml +64 -0
  115. sysmlpy/library/systems/Actions.sysml +552 -0
  116. sysmlpy/library/systems/Allocations.sysml +29 -0
  117. sysmlpy/library/systems/AnalysisCases.sysml +38 -0
  118. sysmlpy/library/systems/Attributes.sysml +25 -0
  119. sysmlpy/library/systems/Calculations.sysml +37 -0
  120. sysmlpy/library/systems/Cases.sysml +71 -0
  121. sysmlpy/library/systems/Connections.sysml +60 -0
  122. sysmlpy/library/systems/Constraints.sysml +44 -0
  123. sysmlpy/library/systems/Flows.sysml +126 -0
  124. sysmlpy/library/systems/Interfaces.sysml +89 -0
  125. sysmlpy/library/systems/Items.sysml +153 -0
  126. sysmlpy/library/systems/Metadata.sysml +32 -0
  127. sysmlpy/library/systems/Parts.sysml +81 -0
  128. sysmlpy/library/systems/Ports.sysml +54 -0
  129. sysmlpy/library/systems/Requirements.sysml +194 -0
  130. sysmlpy/library/systems/StandardViewDefinitions.sysml +123 -0
  131. sysmlpy/library/systems/States.sysml +103 -0
  132. sysmlpy/library/systems/SysML.sysml +539 -0
  133. sysmlpy/library/systems/UseCases.sysml +57 -0
  134. sysmlpy/library/systems/VerificationCases.sysml +103 -0
  135. sysmlpy/library/systems/Views.sysml +164 -0
  136. sysmlpy/navigate.py +272 -0
  137. sysmlpy/store.py +547 -0
  138. sysmlpy/usage.py +2978 -0
  139. sysmlpy-0.1.0.dist-info/METADATA +230 -0
  140. sysmlpy-0.1.0.dist-info/RECORD +143 -0
  141. sysmlpy-0.1.0.dist-info/WHEEL +4 -0
  142. sysmlpy-0.1.0.dist-info/entry_points.txt +3 -0
  143. sysmlpy-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,161 @@
1
+ """Examples: Attribute Values, Types, and Complex Objects
2
+
3
+ This document explains how sysmlpy handles different types of attribute values:
4
+ - Simple values (strings, numbers)
5
+ - Pint quantities with units
6
+ - Tuples and lists (partial support)
7
+ """
8
+
9
+ from sysmlpy import loads, Part, Attribute
10
+ from sysmlpy.usage import ureg
11
+
12
+ # =============================================================================
13
+ # 1. Simple Values
14
+ # =============================================================================
15
+
16
+ # Strings
17
+ model = loads('''
18
+ package Example {
19
+ attribute name : String = "Tesla";
20
+ }
21
+ ''')
22
+ attr = model.children[0].children[0]
23
+ print(f"String: {attr.name} = {attr.get_value()}")
24
+
25
+ # Integers
26
+ model = loads('''
27
+ package Example {
28
+ attribute count : Integer = 42;
29
+ }
30
+ ''')
31
+ attr = model.children[0].children[0]
32
+ print(f"Integer: {attr.name} = {attr.get_value()}")
33
+
34
+ # Reals
35
+ model = loads('''
36
+ package Example {
37
+ attribute price : Real = 49999.99;
38
+ }
39
+ ''')
40
+ attr = model.children[0].children[0]
41
+ print(f"Real: {attr.name} = {attr.get_value()}")
42
+
43
+ # =============================================================================
44
+ # 2. Pint Quantities with Units
45
+ # =============================================================================
46
+
47
+ model = loads('''
48
+ package Example {
49
+ part def Vehicle {
50
+ attribute mass : Real = 1000 [kilogram];
51
+ attribute speed : Real = 60 [mile/hour];
52
+ attribute height : Real = 1.5 [meter];
53
+ }
54
+ }
55
+ ''')
56
+
57
+ vehicle = model.children[0].children[0]
58
+
59
+ for attr in vehicle.children:
60
+ val = attr.get_value()
61
+ print(f"{attr.name} = {val}")
62
+ if hasattr(val, 'magnitude'):
63
+ print(f" magnitude: {val.magnitude}")
64
+ print(f" units: {val.units}")
65
+
66
+ # =============================================================================
67
+ # 3. Setting Values Programmatically
68
+ # =============================================================================
69
+
70
+ attr = Attribute()
71
+ attr._set_name("weight")
72
+
73
+ # With pint Quantity
74
+ attr.set_value(1500 * ureg.kilogram)
75
+ print(f"\nAfter setting: {attr.get_value()}")
76
+
77
+ # =============================================================================
78
+ # 4. Tuples and Lists (LIMITED SUPPORT)
79
+ # =============================================================================
80
+
81
+ # NOTE: The ANTLR4 grammar has partial support for sequences.
82
+ # Curly braces {} with commas do not currently parse.
83
+ # Workaround: Use multiple single-value attributes and combine in code.
84
+
85
+ # Workaround approach:
86
+ model = loads('''
87
+ package Example {
88
+ part def Vehicle {
89
+ attribute color1 : String = "red";
90
+ attribute color2 : String = "green";
91
+ attribute color3 : String = "blue";
92
+ }
93
+ }
94
+ ''')
95
+
96
+ vehicle = model.children[0].children[0]
97
+ colors = []
98
+ for child in vehicle.children:
99
+ if isinstance(child, Attribute):
100
+ try:
101
+ colors.append(child.get_value())
102
+ except:
103
+ pass
104
+ print(f"\nColors as list: {colors}")
105
+
106
+ # =============================================================================
107
+ # 5. Type Resolution
108
+ # =============================================================================
109
+
110
+ # The type is stored in the grammar structure.
111
+ # typedby may not be populated during load_from_grammar (known issue).
112
+
113
+ model = loads('''
114
+ package Example {
115
+ part def Vehicle {
116
+ attribute mass : Real;
117
+ attribute name : String;
118
+ }
119
+ }
120
+ ''')
121
+
122
+ vehicle = model.children[0].children[0]
123
+
124
+ for attr in vehicle.children:
125
+ # Access grammar to see type info
126
+ print(f"{attr.name}: grammar type = {type(attr.grammar).__name__}")
127
+
128
+ # =============================================================================
129
+ # 6. Attribute Multiplicity
130
+ # =============================================================================
131
+
132
+ # Attributes can have multiplicity like Real[3] for arrays
133
+ # The type information is stored in the grammar but not yet exposed via Python API
134
+
135
+ model = loads('''
136
+ package Example {
137
+ attribute coords : Real[3];
138
+ }
139
+ ''')
140
+ attr = model.children[0].children[0]
141
+ print(f"\nAttribute: {attr.name}")
142
+
143
+ # =============================================================================
144
+ # 7. Nested Attribute Bodies
145
+ # =============================================================================
146
+
147
+ # Attributes can contain nested elements (rare but valid)
148
+ model = loads('''
149
+ package Example {
150
+ part def Vehicle {
151
+ attribute sensors {
152
+ attribute temperature : Real;
153
+ attribute pressure : Real;
154
+ }
155
+ }
156
+ }
157
+ ''')
158
+
159
+ vehicle = model.children[0].children[0]
160
+ sensors = vehicle.children[0]
161
+ print(f"\n{sensors.name} children: {[c.name for c in sensors.children]}")
@@ -0,0 +1,139 @@
1
+ """Examples: Checking Attributes of a Part
2
+
3
+ NOTE: Currently, children are only loaded for 'part def' (definitions).
4
+ Using 'part' (usage) may not load nested children - this is a known limitation.
5
+ """
6
+
7
+ from sysmlpy import loads, Part, Attribute
8
+ from sysmlpy.usage import ureg
9
+
10
+ # =============================================================================
11
+ # 1. Basic Attribute Access
12
+ # =============================================================================
13
+
14
+ model = loads('''
15
+ package Example {
16
+ part def Vehicle {
17
+ attribute maxSpeed : Real;
18
+ attribute mass : Real;
19
+ part Engine { }
20
+ }
21
+ }
22
+ ''')
23
+
24
+ vehicle = model.children[0].children[0]
25
+
26
+ print("All children:", vehicle.children)
27
+
28
+ # Filter for attributes
29
+ attrs = [c for c in vehicle.children if isinstance(c, Attribute)]
30
+ print("Attributes:", [a.name for a in attrs])
31
+
32
+ # Filter for nested parts
33
+ nested_parts = [c for c in vehicle.children if isinstance(c, Part)]
34
+ print("Nested parts:", [p.name for p in nested_parts])
35
+
36
+ # =============================================================================
37
+ # 2. Attribute Properties
38
+ # =============================================================================
39
+
40
+ model = loads('''
41
+ package Example {
42
+ part def Vehicle {
43
+ attribute maxSpeed : Real;
44
+ attribute mass : Real = 1000 [kilogram];
45
+ }
46
+ }
47
+ ''')
48
+
49
+ vehicle = model.children[0].children[0]
50
+
51
+ for attr in vehicle.children:
52
+ print(f"\nAttribute: {attr.name}")
53
+ print(f" is_definition: {type(attr.grammar).__name__ == 'AttributeDefinition'}")
54
+ print(f" grammar type: {type(attr.grammar).__name__}")
55
+
56
+ # =============================================================================
57
+ # 3. Working with Values (Single Values)
58
+ # =============================================================================
59
+
60
+ # NOTE: get_value() requires the attribute to have been set with a value
61
+ # and the valuepart to exist in the grammar. This is still being improved.
62
+
63
+ model = loads('''
64
+ package Example {
65
+ part def Vehicle {
66
+ attribute mass : Real = 1000 [kilogram];
67
+ attribute name : String = "Tesla";
68
+ }
69
+ }
70
+ ''')
71
+
72
+ vehicle = model.children[0].children[0]
73
+
74
+ for attr in vehicle.children:
75
+ try:
76
+ val = attr.get_value()
77
+ print(f"{attr.name} = {val}")
78
+ except Exception as e:
79
+ print(f"{attr.name}: get_value() needs valuepart - {type(e).__name__}")
80
+
81
+ # =============================================================================
82
+ # 4. Setting Values Programmatically
83
+ # =============================================================================
84
+
85
+ attr = Attribute()
86
+ attr._set_name("weight")
87
+
88
+ # Set with pint Quantity (recommended)
89
+ attr.set_value(1500 * ureg.kilogram)
90
+ print(f"\nAfter setting: {attr.get_value()}")
91
+
92
+ # NOTE: Setting with strings has a known bug where get_value() fails to parse.
93
+ # This will be fixed in a future update.
94
+ # attr.set_value("1200 [kilogram]") # BUG: get_value() fails after string assignment
95
+
96
+ # =============================================================================
97
+ # 5. Checking Type
98
+ # =============================================================================
99
+
100
+ # NOTE: typedby is populated during load_from_grammar but may need verification
101
+
102
+ model = loads('''
103
+ package Example {
104
+ part def Vehicle {
105
+ attribute mass : Real;
106
+ attribute name : String;
107
+ }
108
+ }
109
+ ''')
110
+
111
+ vehicle = model.children[0].children[0]
112
+
113
+ for attr in vehicle.children:
114
+ if attr.typedby:
115
+ print(f"{attr.name} : {attr.typedby.name}")
116
+ else:
117
+ # Access type from grammar structure
118
+ print(f"{attr.name} : (type in grammar, typedby not populated)")
119
+
120
+ # =============================================================================
121
+ # 6. Nested Parts
122
+ # =============================================================================
123
+
124
+ model = loads('''
125
+ package Example {
126
+ part def Vehicle {
127
+ attribute mass : Real;
128
+ part Engine {
129
+ attribute displacement : Real;
130
+ }
131
+ }
132
+ }
133
+ ''')
134
+
135
+ vehicle = model.children[0].children[0]
136
+ engine = vehicle.children[1] # Engine
137
+
138
+ print(f"\n{vehicle.name} contains: {[c.name for c in vehicle.children]}")
139
+ print(f"{engine.name} contains: {[c.name for c in engine.children]}")
@@ -0,0 +1,231 @@
1
+ """Examples: Tuples and Sequences in SysML v2
2
+
3
+ SysML v2 supports tuples/sequences for collections. This document explains
4
+ the syntax and current status in sysmlpy.
5
+ """
6
+
7
+ from sysmlpy import loads, Part, Attribute
8
+ from sysmlpy.usage import ureg
9
+
10
+ # =============================================================================
11
+ # 1. Tuple Syntax in SysML v2
12
+ # =============================================================================
13
+
14
+ # SysML v2 uses parentheses with commas for tuples:
15
+ # attribute point : Anything[2] = (10, 20);
16
+ # attribute rgb : Anything[3] = (255, 128, 0);
17
+
18
+ # =============================================================================
19
+ # 2. Using Collections Library Types
20
+ # =============================================================================
21
+
22
+ # The Collections library (kernel/Collections.kerml) provides:
23
+ # - Array: Fixed-size multi-dimensional collection
24
+ # - List: Variable-size ordered collection
25
+ # - Set: Variable-size unordered unique collection
26
+ # - Bag: Variable-size unordered non-unique collection
27
+ # - Map: Collection of key-value pairs
28
+ # - KeyValuePair: A tuple of (key, value)
29
+
30
+ print("=" * 60)
31
+ print("Tuples and Sequences in SysML v2 - sysmlpy")
32
+ print("=" * 60)
33
+
34
+ # =============================================================================
35
+ # 3. Current Status
36
+ # =============================================================================
37
+
38
+ print("\n3. Current Status")
39
+ print("-" * 40)
40
+
41
+ # Simple values: WORKING
42
+ print("\nSimple values (Integer, Real, String, Boolean):")
43
+ model = loads('''
44
+ package Example {
45
+ attribute count : Integer = 42;
46
+ attribute price : Real = 19.99;
47
+ attribute name : String = "Widget";
48
+ attribute mass : Real = 100 [kilogram];
49
+ }
50
+ ''')
51
+ pkg = model.children[0]
52
+ for attr in pkg.children:
53
+ try:
54
+ val = attr.get_value()
55
+ print(f" {attr.name} = {val}")
56
+ except Exception as e:
57
+ print(f" {attr.name}: ERROR - {type(e).__name__}")
58
+
59
+ # Tuples: PARTIAL (parse succeeds but value extraction needs work)
60
+ print("\nTuples like (10, 20):")
61
+ try:
62
+ model = loads('''
63
+ package Example {
64
+ attribute point : Real[2] = (10, 20);
65
+ }
66
+ ''')
67
+ print(" SUCCESS - tuple parsing works!")
68
+ except Exception as e:
69
+ print(f" FAILED - {type(e).__name__}")
70
+ print(" (Known limitation: tuple syntax not yet fully supported)")
71
+
72
+ # =============================================================================
73
+ # 4. Recommended Workaround: Use Parts Instead of Tuples
74
+ # =============================================================================
75
+
76
+ print("\n4. Recommended Workaround: Use Parts with Named Fields")
77
+ print("-" * 40)
78
+
79
+ # Instead of tuples, use parts with named attributes:
80
+ model = loads('''
81
+ package Example {
82
+ /** A 2D position using a Part */
83
+ part def Position2D {
84
+ attribute x : Real = 10;
85
+ attribute y : Real = 20;
86
+ }
87
+
88
+ /** RGB Color using a Part */
89
+ part def RGBColor {
90
+ attribute red : Integer = 255;
91
+ attribute green : Integer = 128;
92
+ attribute blue : Integer = 0;
93
+ }
94
+
95
+ /** A vehicle with position and color */
96
+ part def Vehicle {
97
+ attribute mass : Real = 1000 [kilogram];
98
+ part position : Position2D;
99
+ part bodyColor : RGBColor;
100
+ }
101
+ }
102
+ ''')
103
+
104
+ # Get parts directly
105
+ parts = [c for c in model.children[0].children if isinstance(c, Part)]
106
+ print("\nPackage contents:")
107
+ for part in parts:
108
+ print(f" Part: {part.name}")
109
+
110
+ # Find Vehicle
111
+ vehicle = next((p for p in parts if p.name == 'Vehicle'), None)
112
+ if vehicle:
113
+ print(f"\nVehicle '{vehicle.name}':")
114
+ for child in vehicle.children:
115
+ if isinstance(child, Attribute):
116
+ try:
117
+ print(f" {child.name} = {child.get_value()}")
118
+ except Exception as e:
119
+ print(f" {child.name}: (get_value pending)")
120
+ elif isinstance(child, Part):
121
+ print(f" {child.name}:")
122
+ for subchild in child.children:
123
+ if isinstance(subchild, Attribute):
124
+ try:
125
+ print(f" {subchild.name} = {subchild.get_value()}")
126
+ except:
127
+ pass
128
+
129
+ # =============================================================================
130
+ # 5. Alternative: Use Multiple Attributes
131
+ # =============================================================================
132
+
133
+ print("\n5. Alternative: Use Multiple Single-Value Attributes")
134
+ print("-" * 40)
135
+
136
+ model = loads('''
137
+ package Example {
138
+ part def TemperatureReading {
139
+ attribute reading1 : Real;
140
+ attribute reading2 : Real;
141
+ attribute reading3 : Real;
142
+ }
143
+
144
+ part sensor1 : TemperatureReading {
145
+ reading1 = 22.5 [degC];
146
+ reading2 = 23.0 [degC];
147
+ reading3 = 21.5 [degC];
148
+ }
149
+ }
150
+ ''')
151
+
152
+ pkg = model.children[0]
153
+ parts = [c for c in pkg.children if isinstance(c, Part)]
154
+ sensor = next((p for p in parts if p.name == 'sensor1'), None)
155
+ if sensor:
156
+ print(f"\nTemperature readings for '{sensor.name}':")
157
+ for attr in sensor.children:
158
+ if isinstance(attr, Attribute):
159
+ try:
160
+ print(f" {attr.name} = {attr.get_value()}")
161
+ except:
162
+ pass
163
+
164
+ # =============================================================================
165
+ # 6. Collections Library Reference
166
+ # =============================================================================
167
+
168
+ print("\n6. Collections Library Reference")
169
+ print("-" * 40)
170
+
171
+ print("""
172
+ The kernel/Collections.kerml library provides these types:
173
+
174
+ datatype Collection - Base collection type with 'elements' feature
175
+ datatype OrderedCollection - Ordered collections
176
+ datatype UniqueCollection - Collections with unique elements
177
+
178
+ datatype Array - Fixed-size multi-dimensional collection
179
+ - Use 'dimensions' to specify shape
180
+ - Use 'elements' for flattened access
181
+
182
+ datatype List - Variable-size ordered collection
183
+ datatype Set - Variable-size unordered unique collection
184
+ datatype Bag - Variable-size unordered non-unique collection
185
+
186
+ datatype Map - Collection of key-value pairs
187
+ datatype KeyValuePair - A tuple of (key, value)
188
+
189
+ datatype OrderedMap - Ordered map
190
+
191
+ Example usage in SysML:
192
+ import Collections::*;
193
+
194
+ attribute measurements : List = #("temp1", "temp2", "temp3");
195
+ attribute dataPoint : KeyValuePair = (key = "x", val = 10);
196
+ """)
197
+
198
+ # =============================================================================
199
+ # 7. Summary
200
+ # =============================================================================
201
+
202
+ print("\n" + "=" * 60)
203
+ print("Summary: Tuple/Sequence Support in sysmlpy")
204
+ print("=" * 60)
205
+ print("""
206
+ +---------------------------+------------+
207
+ | Feature | Status |
208
+ +---------------------------+------------+
209
+ | Simple values | WORKS |
210
+ | Integer, Real, String | |
211
+ | Pint quantities | WORKS |
212
+ | Real = 100 [kilogram] | |
213
+ | Tuples | PARTIAL |
214
+ | (10, 20, 30) | (parses) |
215
+ | Lists with #() | NOT YET |
216
+ | #("a", "b", "c") | |
217
+ +---------------------------+------------+
218
+
219
+ Workarounds:
220
+ 1. Use structured types (parts) instead of tuples
221
+ 2. Use multiple single-value attributes
222
+ 3. Use Parts with named fields for complex data
223
+
224
+ Recommended pattern:
225
+ part def Position2D {
226
+ attribute x : Real;
227
+ attribute y : Real;
228
+ }
229
+
230
+ part origin : Position2D { x = 10; y = 20; }
231
+ """)
sysmlpy/formatting.py ADDED
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Created on Wed May 31 13:26:53 2023
5
+
6
+ @author: christophercox
7
+ """
8
+
9
+ from sysmlpy.grammar.classes import RootNamespace
10
+
11
+
12
+ def remove_classes(model):
13
+ """An example docstring for a class definition."""
14
+ if type(model) == type(dict()):
15
+ output = {}
16
+ for element in model:
17
+ if not "_" in element[0] and not "parent" in element:
18
+ # Remove internal parsing elements
19
+ output[element] = remove_classes(model[element])
20
+ elif type(model) == type(list()):
21
+ # List of classes
22
+ output = []
23
+ for member in model:
24
+ output.append(remove_classes(member))
25
+ elif type(model) == type(None):
26
+ return None
27
+ elif type(model) == type(bool()) or type(model) == type(str()):
28
+ return model
29
+ else:
30
+ output = {"name": model.__class__.__name__}
31
+ model_out = remove_classes(model.__dict__)
32
+ output.update(model_out)
33
+
34
+ return output
35
+
36
+
37
+ def reformat(model):
38
+ """An example docstring for a class definition."""
39
+ # Convert to dictionary format
40
+ model_out = {"name": model.__class__.__name__}
41
+ model_out.update(remove_classes(model.__dict__))
42
+
43
+ return model_out
44
+
45
+
46
+ def classtree(model):
47
+ return RootNamespace(model)
@@ -0,0 +1,30 @@
1
+ # SysML v2 — ANTLR4 Grammar
2
+
3
+ ANTLR4 grammar for the [SysML v2](https://www.omg.org/spec/SysML/2.0) textual
4
+ notation, automatically generated from the OMG specification grammar (KEBNF
5
+ format).
6
+
7
+ ## Source
8
+
9
+ - **Specification**: [Systems-Modeling/SysML-v2-Release](https://github.com/Systems-Modeling/SysML-v2-Release)
10
+ - **Release tag**: `2026-03`
11
+ - **Generator**: [daltskin/sysml-v2-grammar](https://github.com/daltskin/sysml-v2-grammar)
12
+
13
+ ## Grammar Structure
14
+
15
+ | File | Description |
16
+ |------|-------------|
17
+ | `SysMLv2Lexer.g4` | Lexer grammar — keywords, operators, literals, whitespace |
18
+ | `SysMLv2Parser.g4` | Parser grammar — full SysML v2 textual syntax |
19
+
20
+ ## Entry Point
21
+
22
+ The start rule is `rootNamespace`.
23
+
24
+ ## License
25
+
26
+ MIT — Copyright (c) 2026 J Dalton
27
+
28
+ The SysML v2 specification grammar is owned by the Object Management Group
29
+ (OMG). This project provides a derived ANTLR4 translation of the official
30
+ KEBNF grammar.