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
sysmlpy/__init__.py ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ SysML v2 Python Library
5
+
6
+ A pure Python implementation for parsing SysML v2.0 models.
7
+ Uses the ANTLR4 parser for full SysML v2 grammar support.
8
+ """
9
+
10
+ __all__ = [
11
+ "load", "loads", "load_grammar", "load_antlr", "load_grammar_antlr",
12
+ "Searchable",
13
+ "Store", "InMemoryStore", "NetworkXStore", "create_store", "new_id",
14
+ ]
15
+ __author__ = "Jon Fox"
16
+ __version__ = "0.12.1"
17
+
18
+ from sysmlpy.usage import (
19
+ Item, Attribute, Part, Port, Action, Reference, UseCase, Requirement, Interface, Message,
20
+ State, Constraint, Connection, Flow, Calculation, Enumeration,
21
+ Allocation, Metadata, Rendering, Individual, FlowDef,
22
+ View, Viewpoint, Concern,
23
+ Case, AnalysisCase, VerificationCase,
24
+ )
25
+
26
+ from sysmlpy.definition import Model, Package
27
+ from sysmlpy.navigate import Searchable
28
+ from sysmlpy.store import Store, InMemoryStore, NetworkXStore, create_store, new_id
29
+
30
+ from sysmlpy.usage import ureg
31
+
32
+
33
+ def load_grammar(s, debug=False):
34
+ """SysML load from string to dictionary
35
+
36
+ Deserialize a string containing a SysML v2.0 document to a Python dictionary.
37
+
38
+ Parameters
39
+ ----------
40
+ s : str or _io.TextIOWrapper
41
+ String instance of SysML v2.0 document or file pointer
42
+
43
+ Returns
44
+ -------
45
+ dict
46
+ Dictionary version structured utilizing SysML v2.0 grammar
47
+
48
+ Raises
49
+ ------
50
+ TypeError
51
+ Input was not str or file
52
+ """
53
+ import sysmlpy.antlr_visitor as antlr_visitor
54
+ import sysmlpy.antlr_parser as antlr_parser
55
+ import io
56
+
57
+ # Handle file pointer or string
58
+ if isinstance(s, io.TextIOWrapper):
59
+ s = s.read()
60
+ elif not isinstance(s, str):
61
+ raise TypeError(
62
+ f"the SysML object must be str or file, not {s.__class__.__name__}"
63
+ )
64
+
65
+ # Wrap in package if not starting with 'package' for parsing
66
+ s_stripped = s.strip()
67
+ needs_unwrap = not s_stripped.startswith('package')
68
+ if needs_unwrap:
69
+ s = f'package __implicit__ {{ {s_stripped} }}'
70
+
71
+ try:
72
+ result = antlr_visitor.parse_to_dict(s)
73
+
74
+ # If we wrapped, we need to return a format compatible with what the tests expect
75
+ # The grammar classes expect "PackageBodyElement" as the top-level name
76
+ if needs_unwrap:
77
+ # Navigate to Package body ownedRelationship
78
+ pkg_member = result['ownedRelationship'][0]
79
+ pkg_elem = pkg_member['ownedRelatedElement']
80
+ pkg = pkg_elem['ownedRelatedElement']
81
+ body = pkg['body']
82
+
83
+ # Return in PackageBodyElement format (no Package wrapper)
84
+ return {
85
+ "name": "PackageBodyElement",
86
+ "ownedRelationship": body['ownedRelationship']
87
+ }
88
+
89
+ return result
90
+ except antlr_parser.SysMLSyntaxError as e:
91
+ print("ANTLR4 returned the following error: {}".format(e))
92
+ raise
93
+
94
+
95
+ def load(fp):
96
+ """SysML load from file pointer
97
+
98
+ Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
99
+ a SysML v2.0 document) to a Python dictionary object.
100
+
101
+ Parameters
102
+ ----------
103
+ fp : _io.TextIOWrapper
104
+ File pointer to SysML v2.0 document
105
+
106
+ Returns
107
+ -------
108
+ dict
109
+ Dictionary version structured utilizing SysML v2.0 grammar
110
+
111
+ Raises
112
+ ------
113
+ TypeError
114
+ Input was not _io.TextIOWrapper
115
+ """
116
+ import io
117
+
118
+ if not isinstance(fp, io.TextIOWrapper):
119
+ raise TypeError(
120
+ f"the SysML object must be _io.TextIOWrapper, "
121
+ f"not {fp.__class__.__name__}"
122
+ )
123
+
124
+ return loads(fp.read())
125
+
126
+
127
+ def loads(s: str, library=None):
128
+ """Loads a model from string.
129
+
130
+ This shortcut function allows a user to build a model from a string by
131
+ first instantiating a base model class which builds out a default namespace
132
+ and then that model loads all elements underneath.
133
+
134
+ Uses the ANTLR4 parser.
135
+
136
+ Parameters
137
+ ----------
138
+ s : str
139
+ The SysML v2 source code to parse.
140
+ library : str or Path, optional
141
+ Path to SysML v2 library files for resolving imports.
142
+ """
143
+ return Model().load(s, library=library)
144
+
145
+
146
+ def load_grammar_antlr(fp, debug=False, library=None):
147
+ """SysML load from file pointer using ANTLR4 parser.
148
+
149
+ Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
150
+ a SysML v2.0 document) or ``s`` (a ``str`` instance containing a SysML
151
+ v2.0 document) to a Python dictionary object using the ANTLR4 parser.
152
+
153
+ Parameters
154
+ ----------
155
+ fp : _io.TextIOWrapper or str
156
+ File pointer to SysML v2.0 document or string instance of SysML v2.0
157
+ document
158
+ debug : bool
159
+ Enable debug output.
160
+ library : str or Path, optional
161
+ Path to SysML v2 library files for resolving imports.
162
+
163
+ Returns
164
+ -------
165
+ dict
166
+ Dictionary version structured utilizing SysML v2.0 grammar
167
+
168
+ Raises
169
+ ------
170
+ TypeError
171
+ Input was not _io.TextIOWrapper or str
172
+
173
+ """
174
+ import io
175
+ import sysmlpy.antlr_visitor as antlr_visitor
176
+ import sysmlpy.antlr_parser as antlr_parser
177
+
178
+ if isinstance(fp, io.TextIOWrapper):
179
+ s = fp.read()
180
+ elif isinstance(fp, str):
181
+ s = fp
182
+ else:
183
+ raise TypeError(
184
+ f"the SysML object must be _io.TextIOWrapper or str "
185
+ f"not {fp.__class__.__name__}"
186
+ )
187
+
188
+ try:
189
+ return antlr_visitor.parse_to_dict(s, library=library)
190
+ except antlr_parser.SysMLSyntaxError as e:
191
+ print("ANTLR4 returned the following error: {}".format(e))
192
+ raise
193
+
194
+
195
+ def load_antlr(fp):
196
+ """SysML load from file pointer using ANTLR4 parser.
197
+
198
+ Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
199
+ a SysML v2.0 document) to a Python dictionary object.
200
+
201
+ Parameters
202
+ ----------
203
+ fp : _io.TextIOWrapper
204
+ File pointer to SysML v2.0 document
205
+
206
+ Returns
207
+ -------
208
+ dict
209
+ Dictionary version structured utilizing SysML v2.0 grammar
210
+
211
+ Raises
212
+ ------
213
+ TypeError
214
+ Input was not _io.TextIOWrapper
215
+ """
216
+ import io
217
+
218
+ if not isinstance(fp, io.TextIOWrapper):
219
+ raise TypeError(
220
+ f"the SysML object must be _io.TextIOWrapper, "
221
+ f"not {fp.__class__.__name__}"
222
+ )
223
+
224
+ return loads(fp.read())
225
+
226
+
sysmlpy/__main__.py ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """Command line interface for sysmlpy."""
4
+
5
+ import argparse
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ from sysmlpy import loads
10
+
11
+
12
+ def main():
13
+ parser = argparse.ArgumentParser(
14
+ prog="sysmlpy",
15
+ description="Parse SysML v2 files and display their Python representation"
16
+ )
17
+ parser.add_argument(
18
+ "file",
19
+ type=str,
20
+ help="Path to the SysML v2 file to parse"
21
+ )
22
+ parser.add_argument(
23
+ "--python",
24
+ action="store_true",
25
+ help="Display the Python repr() representation of the parsed model"
26
+ )
27
+ parser.add_argument(
28
+ "-l", "--library",
29
+ type=str,
30
+ help="Path to SysML v2 library files to use for parsing"
31
+ )
32
+ parser.add_argument(
33
+ "--dump",
34
+ action="store_true",
35
+ help="Display the SysML text output (dump format)"
36
+ )
37
+ parser.add_argument(
38
+ "--json",
39
+ action="store_true",
40
+ help="Display the dictionary/JSON representation"
41
+ )
42
+
43
+ args = parser.parse_args()
44
+
45
+ file_path = Path(args.file)
46
+ if not file_path.exists():
47
+ print(f"Error: File '{args.file}' not found.", file=sys.stderr)
48
+ sys.exit(1)
49
+
50
+ try:
51
+ with open(file_path, 'r') as f:
52
+ content = f.read()
53
+ except IOError as e:
54
+ print(f"Error reading file: {e}", file=sys.stderr)
55
+ sys.exit(1)
56
+
57
+ try:
58
+ model = loads(content, library=args.library)
59
+ except Exception as e:
60
+ print(f"Error parsing SysML file: {e}", file=sys.stderr)
61
+ sys.exit(1)
62
+
63
+ if args.json:
64
+ from sysmlpy import load_grammar
65
+ grammar_dict = load_grammar(content)
66
+ import json
67
+ print(json.dumps(grammar_dict, indent=2))
68
+ elif args.dump:
69
+ print(model.dump())
70
+ else:
71
+ # Default or --python flag: show repr()
72
+ print(repr(model))
73
+
74
+ if __name__ == "__main__":
75
+ main()
@@ -0,0 +1,146 @@
1
+ # ANTLR4 Parser for SysML v2
2
+
3
+ ## Overview
4
+
5
+ sysmlpy now includes an experimental **ANTLR4-based parser** as an alternative to the textX parser. This provides a pure Python implementation that can parse SysML v2.0 using grammars derived from the official OMG specification.
6
+
7
+ ## Why ANTLR4?
8
+
9
+ The original textX parser requires manual conversion from the official XText grammar (used in the OMG SysML v2 Pilot Implementation). This is labor-intensive and can drift from the official specification.
10
+
11
+ The ANTLR4 approach:
12
+ - Uses grammars auto-generated from the official OMG KEBNF specification
13
+ - Grammar version tracks the OMG release (e.g., v2026.03.0 for 2026-03 release)
14
+ - Provides a pure Python alternative to Java/TypeScript-based SysMLv2 parsers
15
+
16
+ ## Project Structure
17
+
18
+ ```
19
+ src/sysmlpy/
20
+ ├── antlr_parser.py # Core ANTLR4 parsing functions
21
+ ├── antlr_visitor.py # Convert parse tree to Python classes
22
+ ├── antlr/ # Generated ANTLR4 parser (auto-generated)
23
+ │ ├── SysMLv2Lexer.py
24
+ │ ├── SysMLv2Parser.py
25
+ │ ├── SysMLv2ParserVisitor.py
26
+ │ └── ...
27
+ └── grammar/antlr4/ # Grammar source files
28
+ ├── SysMLv2Lexer.g4
29
+ ├── SysMLv2Parser.g4
30
+ └── examples/ # Test files
31
+ ```
32
+
33
+ ## Usage
34
+
35
+ ### Using the ANTLR4 Parser
36
+
37
+ ```python
38
+ from sysmlpy import load_antlr, loads, load_grammar
39
+
40
+ # Load from file
41
+ with open('model.sysml', 'r') as f:
42
+ model = load_antlr(f)
43
+
44
+ # Load from string
45
+ model = loads('''
46
+ package VehicleModel {
47
+ part def Vehicle {
48
+ attribute mass : Real;
49
+ }
50
+ }
51
+ ''')
52
+
53
+ # Get raw grammar dictionary
54
+ grammar_dict = load_grammar('package Test;')
55
+
56
+ # Print the model
57
+ print(model.dump())
58
+ ```
59
+
60
+ ### Round-trip Support
61
+
62
+ The ANTLR4 parser supports round-trip parsing:
63
+
64
+ ```python
65
+ from sysmlpy import loads
66
+
67
+ # Parse SysML
68
+ model = loads('package Test { part def Vehicle; }')
69
+
70
+ # Dump to string
71
+ output = model.dump()
72
+
73
+ # Parse again - should produce identical output
74
+ model2 = loads(output)
75
+ assert output == model2.dump()
76
+ ```
77
+
78
+ ### Choosing the Parser
79
+
80
+ All public API functions now use the ANTLR4 parser:
81
+
82
+ ```python
83
+ from sysmlpy import loads # ANTLR4-based (default)
84
+ ```
85
+
86
+ ## Grammar Sources
87
+
88
+ The ANTLR4 grammar is sourced from [daltskin/sysml-v2-grammar](https://github.com/daltskin/sysml-v2-grammar), which automatically generates ANTLR4 grammars from the OMG SysML v2 specification KEBNF files.
89
+
90
+ - **Current grammar version:** v2026.03.0
91
+ - **OMG release:** 2026-03
92
+ - **Source:** [Systems-Modeling/SysML-v2-Release](https://github.com/Systems-Modeling/SysML-v2-Release)
93
+
94
+ ## What's Supported
95
+
96
+ The following SysML v2 constructs work with the ANTLR4 parser:
97
+
98
+ - Package definitions
99
+ - Part definitions and usages
100
+ - Attribute definitions and usages
101
+ - Item definitions and usages
102
+ - Port definitions and usages
103
+ - Requirement definitions
104
+ - Use case definitions
105
+
106
+ ## Known Limitations
107
+
108
+ 1. **Some complex elements** - Requirements, UseCases, and Ports with full bodies may have partial support
109
+ 2. **Round-trip fidelity** - Some whitespace/formatting differences may occur
110
+ 3. **Grammar drift** - The auto-generated grammar may have minor differences from the official OMG specification
111
+
112
+ ## Updating the Grammar
113
+
114
+ To update to a newer OMG release:
115
+
116
+ ```bash
117
+ # Download the latest grammar release from daltskin/sysml-v2-grammar
118
+ # Or regenerate from the OMG KEBNF specification
119
+
120
+ # Regenerate the Python parser
121
+ java -jar antlr-4.13.2-complete.jar -Xexact-output-dir \
122
+ -o src/sysmlpy/antlr \
123
+ -visitor -listener -Dlanguage=Python3 \
124
+ src/sysmlpy/grammar/antlr4/SysMLv2Lexer.g4 \
125
+ src/sysmlpy/grammar/antlr4/SysMLv2Parser.g4
126
+ ```
127
+
128
+ ## Comparison: textX vs ANTLR4
129
+
130
+ | Feature | textX | ANTLR4 |
131
+ |---------|-------|--------|
132
+ | Grammar source | Manual XText conversion | Auto-generated from OMG KEBNF |
133
+ | Grammar updates | Labor-intensive | Automated |
134
+ | Parse performance | Good | Good |
135
+ | Error messages | Good | Excellent |
136
+ | Python-only | Yes | Yes |
137
+ | Round-trip support | Full | Partial |
138
+ | Specification tracking | Manual | Automatic |
139
+
140
+ ## Future Work
141
+
142
+ 1. Complete support for all SysML v2 constructs
143
+ 2. Improve round-trip fidelity
144
+ 3. Add conformance tests against OMG test suite
145
+ 4. Consider making ANTLR4 the default parser
146
+ 5. Remove textX dependency once ANTLR4 is stable