├── .gitignore ├── LICENSE ├── LICENSE.html ├── PySysML Project Report Final.pdf ├── PySysML2_notebook.ipynb ├── README.md ├── Updated Workflow 20240805.md ├── environment.yaml ├── examples ├── export_models.py └── models │ ├── model_test_1.sysml2 │ ├── model_test_2.sysml2 │ └── simplified_beagleplay.sysml2 ├── poetry.lock ├── pyproject.toml ├── pysysml2 ├── __init__.py ├── cli │ ├── __init__.py │ ├── __main__.py │ └── ui.py ├── grammar │ ├── .antlr │ │ ├── SysML2.interp │ │ ├── SysML2.tokens │ │ ├── SysML2BaseListener.java │ │ ├── SysML2Lexer.interp │ │ ├── SysML2Lexer.java │ │ ├── SysML2Lexer.tokens │ │ ├── SysML2Listener.java │ │ └── SysML2Parser.java │ ├── SysML2.g4 │ ├── SysML2_grammar.g4 │ ├── __init__.py │ ├── antlr4_helper.py │ ├── distj │ │ ├── SysML2.interp │ │ ├── SysML2.tokens │ │ ├── SysML2BaseListener.class │ │ ├── SysML2BaseListener.java │ │ ├── SysML2BaseVisitor.class │ │ ├── SysML2BaseVisitor.java │ │ ├── SysML2Lexer.class │ │ ├── SysML2Lexer.interp │ │ ├── SysML2Lexer.java │ │ ├── SysML2Lexer.tokens │ │ ├── SysML2Listener.class │ │ ├── SysML2Listener.java │ │ ├── SysML2Parser$CommentContext.class │ │ ├── SysML2Parser$Comment_namedContext.class │ │ ├── SysML2Parser$Comment_named_aboutContext.class │ │ ├── SysML2Parser$Comment_unnamedContext.class │ │ ├── SysML2Parser$DocContext.class │ │ ├── SysML2Parser$Doc_namedContext.class │ │ ├── SysML2Parser$Doc_unnamedContext.class │ │ ├── SysML2Parser$ElementContext.class │ │ ├── SysML2Parser$FeatureContext.class │ │ ├── SysML2Parser$Feature_actor_specializesContext.class │ │ ├── SysML2Parser$Feature_attribute_defContext.class │ │ ├── SysML2Parser$Feature_attribute_redefinesContext.class │ │ ├── SysML2Parser$Feature_item_defContext.class │ │ ├── SysML2Parser$Feature_item_refContext.class │ │ ├── SysML2Parser$Feature_part_specializesContext.class │ │ ├── SysML2Parser$Feature_part_specializes_subsetsContext.class │ │ ├── SysML2Parser$Import_packageContext.class │ │ ├── SysML2Parser$ModelContext.class │ │ ├── SysML2Parser$NamespaceContext.class │ │ ├── SysML2Parser$Objective_defContext.class │ │ ├── SysML2Parser$PartContext.class │ │ ├── SysML2Parser$Part_blkContext.class │ │ ├── SysML2Parser$Part_defContext.class │ │ ├── SysML2Parser$Part_def_specializesContext.class │ │ ├── SysML2Parser$Part_objective_blkContext.class │ │ ├── SysML2Parser$Part_specializesContext.class │ │ ├── SysML2Parser$StatementContext.class │ │ ├── SysML2Parser$Sysml2_packageContext.class │ │ ├── SysML2Parser$Use_case_blkContext.class │ │ ├── SysML2Parser$Use_case_defContext.class │ │ ├── SysML2Parser.class │ │ ├── SysML2Parser.java │ │ ├── SysML2Visitor.class │ │ └── SysML2Visitor.java │ ├── distpy │ │ ├── SysML2.interp │ │ ├── SysML2.tokens │ │ ├── SysML2Lexer.interp │ │ ├── SysML2Lexer.py │ │ ├── SysML2Lexer.tokens │ │ ├── SysML2Listener.py │ │ ├── SysML2Parser.py │ │ ├── SysML2Visitor.py │ │ ├── __init__.py │ │ ├── old │ │ │ ├── SysML2.interp │ │ │ ├── SysML2.tokens │ │ │ ├── SysML2Lexer.interp │ │ │ ├── SysML2Lexer.py │ │ │ ├── SysML2Lexer.tokens │ │ │ ├── SysML2Listener.py │ │ │ ├── SysML2Parser.py │ │ │ └── SysML2Visitor.py │ │ └── old2 │ │ │ ├── SysML2.interp │ │ │ ├── SysML2.tokens │ │ │ ├── SysML2Lexer.interp │ │ │ ├── SysML2Lexer.py │ │ │ ├── SysML2Lexer.tokens │ │ │ ├── SysML2Listener.py │ │ │ ├── SysML2Parser.py │ │ │ └── SysML2Visitor.py │ ├── requirements.txt │ └── sysml2_model_visitor.py └── modeling │ ├── __init__.py │ ├── element.py │ └── model.py ├── sandbox └── helloworld.py ├── setup.py ├── simulation ├── context_builder.py └── sim_engine.py ├── template.tex ├── test.py └── tests ├── __init__.py ├── conftest.py ├── grammar ├── __init__.py └── test_antlr4_helper.py ├── modeling ├── __init__.py ├── data │ ├── expect │ │ └── output │ │ │ ├── model_1.csv │ │ │ ├── model_1.dot │ │ │ ├── model_1.json │ │ │ ├── model_1.png │ │ │ ├── model_1.txt │ │ │ ├── model_1.xlsx │ │ │ ├── model_2.csv │ │ │ ├── model_2.dot │ │ │ ├── model_2.json │ │ │ ├── model_2.png │ │ │ ├── model_2.txt │ │ │ └── model_2.xlsx │ └── models │ │ ├── model_1.sysml2 │ │ └── model_2.sysml2 └── test_model.py └── utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Files 2 | beagleplay_set1.sysml2 3 | beagleplay.sysml2 4 | simplified_beagleplay.sysml 5 | simplified_beagleplayX.sysml 6 | simplified_beagleplay.xlsx 7 | 8 | # Local files 9 | local/ 10 | 11 | # macOS 12 | .DS_Store 13 | .AppleDouble 14 | .LSOverride 15 | 16 | # Byte-compiled / optimized / DLL files 17 | __pycache__/ 18 | *.py[cod] 19 | *$py.class 20 | 21 | # C extensions 22 | *.so 23 | 24 | # Distribution / packaging 25 | .Python 26 | env/ 27 | build/ 28 | develop-eggs/ 29 | dist/ 30 | !/docker/jocasta/dist/ 31 | downloads/ 32 | eggs/ 33 | .eggs/ 34 | lib/ 35 | lib64/ 36 | parts/ 37 | sdist/ 38 | var/ 39 | wheels/ 40 | *.egg-info/ 41 | .installed.cfg 42 | *.egg 43 | 44 | # PyInstaller 45 | # Usually these files are written by a python script from a template 46 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 47 | *.manifest 48 | *.spec 49 | 50 | # Installer logs 51 | pip-log.txt 52 | pip-delete-this-directory.txt 53 | 54 | # Unit test / coverage reports 55 | htmlcov/ 56 | .tox/ 57 | .coverage 58 | .coverage.* 59 | .cache 60 | nosetests.xml 61 | coverage.xml 62 | *.cover 63 | .hypothesis/ 64 | .pytest_cache/ 65 | 66 | # Translations 67 | *.mo 68 | *.pot 69 | 70 | # Django stuff: 71 | *.log 72 | local_settings.py 73 | 74 | # Flask stuff: 75 | instance/ 76 | .webassets-cache 77 | 78 | # Scrapy stuff: 79 | .scrapy 80 | 81 | # Sphinx documentation 82 | docs/_build/ 83 | 84 | # PyBuilder 85 | target/ 86 | 87 | # Jupyter Notebook 88 | .ipynb_checkpoints 89 | 90 | # pyenv 91 | .python-version 92 | 93 | # celery beat schedule file 94 | celerybeat-schedule 95 | 96 | # SageMath parsed files 97 | *.sage.py 98 | 99 | # dotenv 100 | .env 101 | 102 | # virtualenv 103 | .venv 104 | venv/ 105 | ENV/ 106 | 107 | # Spyder project settings 108 | .spyderproject 109 | .spyproject 110 | 111 | # Rope project settings 112 | .ropeproject 113 | 114 | # mkdocs documentation 115 | /site 116 | 117 | # mypy 118 | .mypy_cache/ 119 | 120 | # IDE settings 121 | .vscode/ 122 | .idea/ 123 | 124 | # mkdocs build dir 125 | site/ 126 | -------------------------------------------------------------------------------- /LICENSE.html: -------------------------------------------------------------------------------- 1 | Copyright 2022 Keith L. Lucas 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /PySysML Project Report Final.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/PySysML Project Report Final.pdf -------------------------------------------------------------------------------- /PySysML2_notebook.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "This code block demonstrates the following:\n", 8 | "- Reading a SysML 2.0 textual model and building a Python `Model` object\n", 9 | "- Generating outputs, both for serialization (i.e. portability) and model analysis\n", 10 | " - `.JSON` supports model portability between programming languages and tools\n", 11 | " - `.dot` supports graph theory based analysis\n", 12 | " - `.csv` and `.xlsx` support analysis of the model in a tabular view\n", 13 | " - `.txt` is a simple view of the model heirarchy\n", 14 | " - `.png` is a graphical view generated by GraphViz" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "execution_count": 1, 20 | "metadata": {}, 21 | "outputs": [ 22 | { 23 | "name": "stdout", 24 | "output_type": "stream", 25 | "text": [ 26 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n", 27 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n", 28 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n", 29 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n", 30 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n", 31 | "ANTLR runtime and generated code versions disagree: 4.10!=4.13.2\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "import os\n", 37 | "from pysysml2.modeling import Model\n", 38 | "\n", 39 | "\n", 40 | "in_dir = \"./examples/models\"\n", 41 | "out_dir = \"./examples/output\"\n", 42 | "in_sysml2 = [f for f in os.listdir(in_dir) if f.endswith(\".sysml2\")]\n", 43 | "\n", 44 | "# Looping through all model files in the input directory\n", 45 | "for in_f in in_sysml2:\n", 46 | " in_f = os.path.join(in_dir, in_f) # Set filename\n", 47 | " model = Model() # Create Model object\n", 48 | " model.from_sysml2_file(in_f) # Parse the textual model\n", 49 | " model.to_dot(out_dir) # Tranform model to a .dot file\n", 50 | " model.to_png(out_dir) # Export PNG of tree graph\n", 51 | " model.to_excel(out_dir) # Convert to tabular format\n", 52 | " model.to_csv(out_dir) # Export tabular view to CSV\n", 53 | " model.to_JSON(out_dir) # Serialize Model object to JSON\n", 54 | " model.to_txt(out_dir) # Output string representation" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": 7, 60 | "metadata": {}, 61 | "outputs": [ 62 | { 63 | "name": "stderr", 64 | "output_type": "stream", 65 | "text": [ 66 | "line 148:20 extraneous input 'port' expecting {, 'actor', 'attribute', 'comment', 'doc', 'import', 'item', 'package', 'part', 'ref', 'use', COMMENT_LONG}\n", 67 | "line 164:25 token recognition error at: ''openssh-'\n", 68 | "line 164:40 token recognition error at: '' :'\n", 69 | "line 173:25 token recognition error at: ''openssh-'\n", 70 | "line 173:40 token recognition error at: '' :'\n", 71 | "line 182:25 token recognition error at: ''libssl1.'\n", 72 | "line 182:35 token recognition error at: '' :'\n", 73 | "line 194:48 token recognition error at: ''openssh-'\n", 74 | "line 194:63 token recognition error at: ''.'\n", 75 | "line 195:28 token recognition error at: ''openssh-'\n", 76 | "line 195:43 token recognition error at: ''.'\n", 77 | "line 200:29 token recognition error at: '.'\n", 78 | "line 200:56 token recognition error at: '.'\n", 79 | "line 201:29 token recognition error at: '.'\n", 80 | "line 201:38 token recognition error at: ''BLE/'\n", 81 | "line 201:47 token recognition error at: '';'\n", 82 | "line 202:29 token recognition error at: '.'\n", 83 | "line 203:29 token recognition error at: '.'\n", 84 | "line 204:29 token recognition error at: '.'\n", 85 | "line 205:29 token recognition error at: '.'\n", 86 | "line 206:29 token recognition error at: '.'\n", 87 | "line 206:37 token recognition error at: ''USB-'\n", 88 | "line 206:43 token recognition error at: '';'\n", 89 | "line 207:29 token recognition error at: '.'\n", 90 | "line 207:37 token recognition error at: ''USB-'\n", 91 | "line 207:43 token recognition error at: '';'\n", 92 | "line 210:21 token recognition error at: ''USB-'\n", 93 | "line 210:27 token recognition error at: '-'\n", 94 | "line 210:34 token recognition error at: '' :'\n", 95 | "line 213:21 token recognition error at: ''USB-'\n", 96 | "line 213:27 token recognition error at: '-'\n", 97 | "line 213:34 token recognition error at: '' :'\n", 98 | "line 218:21 token recognition error at: ''USB-'\n", 99 | "line 218:27 token recognition error at: '-'\n", 100 | "line 218:34 token recognition error at: '' ='\n", 101 | "line 218:38 token recognition error at: ''USB-'\n", 102 | "line 218:44 token recognition error at: ''.'\n", 103 | "line 219:21 token recognition error at: ''USB-'\n", 104 | "line 219:27 token recognition error at: '-'\n", 105 | "line 219:34 token recognition error at: '' ='\n", 106 | "line 219:38 token recognition error at: ''USB-'\n", 107 | "line 219:44 token recognition error at: ''.'\n", 108 | "line 220:29 token recognition error at: '.'\n", 109 | "line 221:50 token recognition error at: '.'\n", 110 | "line 237:38 token recognition error at: '.'\n", 111 | "line 237:56 token recognition error at: '.'\n", 112 | "line 238:38 token recognition error at: '.'\n", 113 | "line 238:65 token recognition error at: '.'\n", 114 | "line 244:28 token recognition error at: '.'\n", 115 | "line 244:55 token recognition error at: '.'\n", 116 | "line 245:28 token recognition error at: '.'\n", 117 | "line 253:56 token recognition error at: '.'\n", 118 | "line 254:32 token recognition error at: '.'\n", 119 | "line 254:59 token recognition error at: '.'\n", 120 | "line 264:1 token recognition error at: '/\\r'\n", 121 | "line 157:37 no viable alternative at input 'part'default image'defined'\n", 122 | "line 211:41 mismatched input 'USB_Type' expecting TYPE\n", 123 | "line 214:41 mismatched input 'USB_Type' expecting TYPE\n", 124 | "line 230:16 extraneous input '}' expecting {, 'actor', 'attribute', 'comment', 'doc', 'import', 'item', 'package', 'part', 'ref', 'use', COMMENT_LONG}\n" 125 | ] 126 | }, 127 | { 128 | "data": { 129 | "text/plain": [ 130 | "" 131 | ] 132 | }, 133 | "execution_count": 7, 134 | "metadata": {}, 135 | "output_type": "execute_result" 136 | } 137 | ], 138 | "source": [ 139 | "import os\n", 140 | "from pysysml2.modeling import Model\n", 141 | "\n", 142 | "\n", 143 | "in_f = \"./examples/updated_test/beagleplay_set1.sysml2\"\n", 144 | "# in_f = \"./examples/models/model_test_1.sysml2\"\n", 145 | "model = Model() # Create Model object\n", 146 | "model.from_sysml2_file(in_f) # Parse the textual model" 147 | ] 148 | } 149 | ], 150 | "metadata": { 151 | "kernelspec": { 152 | "display_name": "base", 153 | "language": "python", 154 | "name": "python3" 155 | }, 156 | "language_info": { 157 | "codemirror_mode": { 158 | "name": "ipython", 159 | "version": 3 160 | }, 161 | "file_extension": ".py", 162 | "mimetype": "text/x-python", 163 | "name": "python", 164 | "nbconvert_exporter": "python", 165 | "pygments_lexer": "ipython3", 166 | "version": "3.9.12" 167 | }, 168 | "orig_nbformat": 4 169 | }, 170 | "nbformat": 4, 171 | "nbformat_minor": 2 172 | } 173 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PySysML2 2 | 3 | PySysML2 is a Python-based parser for the SysML 2.0 textual modeling language. Its main purpose is to parse a SysML 2.0 textual model into a Python object, and then transform that model into various data structures useful for data science and analysis. 4 | 5 | ## Dependencies 6 | 7 | PySysML2 has the following dependencies: 8 | 9 | - anytree: provides the tree data structure, the basis for the Python model class 10 | - graphviz: renders images of graphs 11 | - numpy: numerical analysis package 12 | - pandas: data analysis package, provides the DataFrame data structure 13 | - openpyxl: allows Pandas to export to Excel 14 | - antlr4: provides the language parsing workbench 15 | 16 | Note that some of these packages (specifically Anytree, Graphviz, and Antlr4) are not available on Anaconda. Also, Pandas does not automatically install the required OpenPyxl module for exporting Excel, so that must be done separately. 17 | 18 | ## Installation 19 | 20 | See the [Development section](#development) for installation instructions if you are a developer. 21 | 22 | ### Install From Source 23 | 24 | ```console 25 | git clone git@github.com:TrekkieByDay/PySysML2.git 26 | 27 | cd PySysML2/ 28 | 29 | pip install . 30 | ``` 31 | 32 | ## Usage 33 | 34 | ### CLI 35 | 36 | After installation, the `pysysml2` CLI tool should be available. The following demonstrates using the `pysysml2 export` command to export the SysML 2.0 textual model file to various output file formats. 37 | ```console 38 | ❯ pysysml2 export examples/models/model_test_1.sysml2 --output-dir out/ --format json,txt,csv,xlsx,dot,png 39 | Using output directory: /Users/delannmt/Workspace/Projects/react/sysml/PySysML2/tmp 40 | Exporting to JSON... 41 | Exporting to txt... 42 | Exporting to csv... 43 | Exporting to xlsx... 44 | Exporting to dot... 45 | Exporting to png... 46 | ``` 47 | 48 | For more information about the `pysysml2 export` command, use the `--help` option: 49 | ```console 50 | ❯ pysysml2 export --help 51 | Usage: pysysml2 export [OPTIONS] MODEL_FILE 52 | 53 | Export a SysML v2 model to various file formats. 54 | 55 | Arguments: 56 | MODEL_FILE The sysml2 model file. [required] 57 | 58 | Options: 59 | --format TEXT One or more comma-separated output file formats. 60 | Supported formats: json,txt,csv,xlsx,dot,png 61 | [default: json] 62 | -o, --output-dir PATH The output directory for the generated file(s). 63 | Defaults to current directory. 64 | --help Show this message and exit. 65 | ``` 66 | 67 | ### Python API Examples 68 | 69 | The `examples/` directory contains an example Python script using `pysysml2` to export sample SysML 2.0 textual models to various output file formats. 70 | 71 | ### Jupyter Notebook 72 | 73 | PySysML2 can be used through Jupyter notebooks. Check the [PySysML2_notebook.ipynb](PySysML2_notebook.ipynb) notebook to test the parsing functionality using the provided SysML 2.0 models. 74 | 75 | ## Project Structure 76 | 77 | The `pysysml2` directory contains all the code. It is divided into the `grammar` and `modeling` packages. 78 | 79 | The `grammar` package contains all the Antlr4 parsing code. The primary artifact of interest is the `SysML.g4` grammar source file, which defines the basic elements of SysML 2.0 that PySysML2 implements. This file is used by the stand-alone Antlr4 command-line application that generates the language parsing Python code. Everything in the `distpy`, `.antlr`, and `distj` directories is auto-generated, and only `distpy` is required for PySysML2. The `sysml2_model_visitor.py` module is an extension of the generated `SysML2Visitor.py` and is the interface between the language parse tree from the textual model and the PySysML2 toolset. 80 | 81 | The `modeling` package contains the SysML 2.0 modeling implementation and export tools. The `element` module implements model elements, and the `model` module implements a SysML 2.0 model class built from element objects. All export functions are in `model.py`. 82 | 83 | ## Development 84 | 85 | ### Setup Poetry 86 | 87 | To use PySysML2 with Poetry, follow these steps: 88 | 89 | 1. Install Poetry by following the instructions in the [official documentation](https://python-poetry.org/docs/#installation). **TLDR:** run the following command: 90 | ``` 91 | curl -sSL https://install.python-poetry.org | python3 - 92 | ``` 93 | 94 | 2. In the root directory of the project repository, run the following command to install all the required dependencies: 95 | ``` 96 | poetry install 97 | ``` 98 | 99 | This will install the main dependencies specified in the `pyproject.toml` file. 100 | 101 | #### Development Group 102 | 103 | PySysML2 has a `dev` group in its `pyproject.toml` file that contains the dependencies required for development and testing. To install these dependencies, run the following command in the root directory of the cloned repository: 104 | 105 | ``` 106 | poetry install --group=dev 107 | ``` 108 | 109 | This will install the development dependencies, including packages such as `pytest`. 110 | 111 | ### Using Poetry 112 | 113 | By default, Poetry creates a virtual environment for each project, so all the 114 | dependencies are installed locally to that environment. This ensures that different 115 | projects can have different dependencies and versions installed without interfering 116 | with each other. 117 | 118 | To execute a command inside the virtual environment, use the `poetry run` command. 119 | For instance, to run the tests for this project, run the following command: 120 | ``` 121 | poetry run pytest 122 | ``` 123 | 124 | To activate the virtual environment, run the following command: 125 | ``` 126 | poetry shell 127 | ``` 128 | 129 | To exit the virtual environment, use `exit`: 130 | ``` 131 | exit 132 | ``` 133 | 134 | ### Bumping Project Version 135 | 136 | The native `poetry version` command only updates the version in `pyproject.toml`. However, the 137 | `__version__` variable in `pysysml2/__init__.py` must also be updated. To ensure the updates 138 | are done in sync, developers should use the [poetry-bumpversion](https://pypi.org/project/poetry-bumpversion/) 139 | plugin for Poetry. 140 | ``` 141 | poetry self add poetry-bumpversion 142 | ``` 143 | 144 | The `poetry version` command can then be used, and both versions will be updated 145 | together. For example to bump the patch version: 146 | ```console 147 | ❯ poetry version patch 148 | Bumping version from 0.1.0 to 0.1.1 149 | poetry-bumpversion: processed file: pysysml2/__init__.py 150 | ``` 151 | 152 | ### poetry2setup 153 | 154 | For the convenience of users installing from source without Poetry, developers can 155 | generate the `setup.py` file from the `pyproject.toml` using the `poetry2setup` tool 156 | (requires [Poetry dev group installation](#development-group)): 157 | ``` 158 | poetry run poetry2setup > setup.py 159 | ``` 160 | 161 | ### poetry2conda 162 | 163 | To support Anaconda distribution, developers can generate the conda environment file 164 | from the `pyproject.toml` using the `poetry2conda` 165 | (requires [Poetry dev group installation](#development-group)): 166 | ``` 167 | poetry run poetry2conda pyproject.toml environment.yaml 168 | ``` 169 | 170 | ### Why use Poetry? 171 | 172 | Poetry is a Python packaging and dependency management tool that helps simplify the process of building, packaging, and distributing Python projects. It provides a simple and intuitive way to manage project dependencies, handle virtual environments, and create distributable packages. 173 | 174 | Using Poetry has several benefits: 175 | 176 | - **Dependency management**: Poetry simplifies dependency management by allowing you to easily install, uninstall, and upgrade packages, and automatically resolving dependencies between packages. 177 | - **Virtual environments**: Poetry creates and manages virtual environments for each project, ensuring that different projects can have different dependencies and versions installed without interfering with each other. 178 | - **Package building and publishing**: Poetry provides a simple way to build and publish packages to PyPI, as well as other package indexes such as your company's private package index. 179 | - **PEP standards compliance**: Poetry is designed to comply with the Python Enhancement Proposal (PEP) standards, which helps ensure compatibility with other Python tools and libraries. 180 | 181 | ### How Poetry helps follow PEP standards 182 | 183 | PEP standards are a set of guidelines and recommendations for how to structure, package, and distribute Python code. These standards help ensure that Python packages are well-designed, easy to use, and compatible with other Python tools and libraries. 184 | 185 | Poetry is designed to follow the PEP standards, which makes it easier to create Python packages that are compliant with these guidelines. Here are some ways in which Poetry helps follow PEP standards: 186 | 187 | - [PEP 517](https://peps.python.org/pep-0517/)/[518](https://peps.python.org/pep-0518/) compliance: Poetry uses the PEP 517/518 standards for building and packaging Python projects, including build isolation to ensure that builds are reproducible and do not rely on the developer's environment. These standards help ensure compatibility with other Python tools such as pip and setuptools. 188 | - [pyproject.toml](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/): Poetry uses a pyproject.toml configuration file to manage project settings and dependencies. This file conforms to the [PEP 621](https://peps.python.org/pep-0621/) standard, which provides a standard way to define project metadata and dependencies. 189 | - [PEP 440](https://peps.python.org/pep-0440/) versioning: Poetry uses the PEP 440 standard for versioning packages, which provides a standard way to version and compare package versions. 190 | - [PEP 508](https://peps.python.org/pep-0508/) dependencies: Poetry supports PEP 508-style dependencies, which allows you to specify dependencies with more detail and flexibility than standard requirements.txt files. -------------------------------------------------------------------------------- /Updated Workflow 20240805.md: -------------------------------------------------------------------------------- 1 | # Workflow for Adding New Syntax Elements 2 | 3 | ## Tips: 4 | 5 | - Don't work with the complicated file directly (or its simplified version) 6 | - Take it one language element at a time by starting from a clean slate with one of the working models, e.g. model_test_2.sysml2 7 | - I made model_test_3.sysml2 for this purpose 8 | - Paste in new language elements, get that working, then move on 9 | - Doing it this way makes it much easier to debug as you're working through Antlr4 grammar and coding 10 | 11 | ## Example One: Keyword "port" 12 | 13 | ### Examples of "port" Usage 14 | 15 | Can appear in `package` or `block` scope 16 | 17 | #### SysMLv2 Code 18 | 19 | - `port 'socket 1';` 20 | - ```sysml 21 | port 'USB-A-Socket' { 22 | attribute 'usb_type' : String; 23 | } 24 | ``` 25 | 26 | #### ANTLR4 Rules 27 | 28 | **GOTCHA**: Note that keywords like "import" and "port" will collide since "port" is a substring of "import". To accommodate this, per ANTLR4 "longest match" rule, keywords that contain substrings that match other keywords MUST be defined first. 29 | 30 | ```antlr4 31 | // An element is anything that can be a part of a model 32 | element : namespace 33 | | feature 34 | | comment 35 | | doc 36 | | statement 37 | | port 38 | ; 39 | // A namespace is an element with a scope defined by curly braces 40 | namespace : sysml2_package 41 | | part 42 | | use_case_def 43 | | comment 44 | | doc 45 | | port 46 | ; 47 | part_blk: (feature | comment | doc | part | port | connect | connection); 48 | // Ports 49 | port: (port_def | port_blk); 50 | // e.g. port 'socket 1'; 51 | port_def: KW_PORT ID ';' | (KW_PORT ID '{' port_blk* '}'); 52 | port_blk: (feature | comment | doc ); 53 | KW_PORT: 'port'; 54 | ``` 55 | 56 | 57 | 58 | ### Workflow 59 | 60 | 1. **Update SysML2.g4 (ANTLR4 file)** 61 | 2. **Run the ANTLR4 command line tool to generate the Python modules in `distpy` from within the `grammar` directory** 62 | - Command line args: `antlr4 -Dlanguage=Python3 SysML2.g4 -visitor -o distpy` 63 | 3. **Verify the updated .py files in `distpy`**: 64 | - Check the date of creation. 65 | - Note that ANTLR4 will provide decent feedback for incorrect ANTLR4 syntax and even logic. It doesn't catch everything though! Learning about the "longest match" rule the hard way is common. 66 | 4. **Run the test script** to ensure that the target .sysml2 file is parsed without errors. Note that at this stage you should NOT expect any change in your output .xlsx spreadsheet because no related Python code has been updated. 67 | 5. **Update Python modules `sysml2_model_visitor.py`, `element.py`, `model.py`**: 68 | - **`sysml2_model_visitor.py`**: This extends the `SysML2Visitor.py` module generated by ANTLR4. 69 | 1. For relationships, specialized code is required... please consult. 70 | 2. Elements are straightforward. Extend the appropriate visitor function, e.g., `visitPort_def`, which was automatically generated in `SysML2Visitor.py`: 71 | ```python 72 | # Visit a parse tree produced by SysML2Parser#part_def. 73 | def visitPort_def(self, ctx: SysML2Parser.Port_defContext): 74 | setattr(ctx, _SYSML2_TYPE_NAME, _SML2_KWS.KW_PORT.value) 75 | self._model_table_builder(ctx) 76 | return self.visitChildren(ctx) 77 | ``` 78 | If your code was generated correctly, the linter should recognize `SysML2Parser.Port_defContext`. The function name MUST MATCH the function you're extending. For elements, this code will all be the same (until specialized code is required for each one. Probably future updates). 79 | - **`element.py`**: This implements the concept of an element. Add the appropriate class with code like this: 80 | ```python 81 | class Port(Element, NodeMixin): 82 | def __init__(self, name=None, parent=None, **kwargs): 83 | super(Port, self).__init__(name=name, parent=parent, **kwargs) 84 | self.sysml2_layer = ArchitectureLayers.systems_element.value 85 | ``` 86 | - **`model.py`**: This implements the concept of a model as a tree data structure. 87 | 1. Update the import statement, i.e., `from pysysml2.modeling.element import (Attribute, Port)` etc. Recommend not to import `*` for readability and maintainability purposes. 88 | 2. Update the `elif` block in the `for` loop in `from_sysml2_file` function, e.g.: 89 | ```python 90 | elif v["sysml2_type"] == smv._SML2_KWS.KW_PORT.value: 91 | Port(**v) 92 | ``` 93 | 6. **Run the test and check the resulting table**. Debug accordingly. 94 | 95 | ## Example 2: Keywords "connect" and "connection" 96 | 97 | TODO: Write updated workflow for relationships. -------------------------------------------------------------------------------- /environment.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # NOTE: This file has been auto-generated by poetry2conda 3 | # poetry2conda version = 0.3.0 4 | # date: Thu Mar 2 23:28:02 2023 5 | ############################################################################### 6 | # If you want to change the contents of this file, you should probably change 7 | # the pyproject.toml file and then use poetry2conda again to update this file. 8 | # Alternatively, stop using (ana)conda. 9 | ############################################################################### 10 | name: sysml2-env 11 | dependencies: 12 | - python>=3.8,<4.0 13 | - numpy>=1.24.2,<2.0.0 14 | - pandas>=1.5.3,<2.0.0 15 | - openpyxl>=3.1.1,<4.0.0 16 | - typer>=0.7.0,<0.8.0 17 | - pip 18 | - pip: 19 | - anytree>=2.8.0,<3.0.0 20 | - graphviz>=0.20.1,<0.21.0 21 | - antlr4-python3-runtime==4.10 22 | -------------------------------------------------------------------------------- /examples/export_models.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pysysml2.modeling.model import Model 3 | 4 | EXAMPLES_DIR = os.path.dirname(os.path.abspath(__file__)) 5 | 6 | # Use this file to perform a quick test of the package. However, it is better 7 | # to use the Jupiter notebook for testing in the main directory. 8 | 9 | in_dir = os.path.join(EXAMPLES_DIR, "models") 10 | out_dir = os.path.join(EXAMPLES_DIR, "output") 11 | 12 | in_sysml2 = [f for f in os.listdir(in_dir) if f.endswith(".sysml2")] 13 | 14 | # Looping through all model files in the input directory 15 | for in_f in in_sysml2: 16 | in_f = os.path.join(in_dir, in_f) 17 | model = Model() 18 | model.from_sysml2_file(in_f) 19 | model.to_csv(out_dir) 20 | model.to_JSON(out_dir) 21 | model.to_txt(out_dir) 22 | model.to_excel(out_dir) 23 | model.to_dot(out_dir) 24 | model.to_png(out_dir) 25 | -------------------------------------------------------------------------------- /examples/models/model_test_1.sysml2: -------------------------------------------------------------------------------- 1 | package Model{ 2 | doc /* This is the documentation for the Model package*/ 3 | /* This is a comment */ 4 | // This is a note 1 5 | comment Comment_1 /* This is a named comment */ 6 | package Structure{ 7 | 8 | part def 'WiFi Card' {} // This is a note 2 9 | part def 'Bluetooth Card' {} 10 | part def 'Icon'; 11 | part def 'Controller Board' { 12 | part 'wifi card' : 'WiFi Card' [1..2]; 13 | part 'bluetooth card' : 'Bluetooth Card'; 14 | attribute 'RAM' : Integer; 15 | attribute 'Primary Interface' : String; 16 | attribute 'Secondary Interface' : String; 17 | attribute 'WiFi Frequency' : Real; 18 | attribute 'WiFi Protocol' : String; 19 | attribute 'Bluetooth Capable' : Boolean; 20 | // This is a note 3 21 | } 22 | part def 'LCD Display' {} 23 | part def 'Battery' {// This is a note 4 24 | } 25 | part def 'Raspberry Pi Pico Wireless' specializes 'Controller Board' { 26 | attribute redefines 'RAM' = 264; 27 | attribute redefines 'Bluetooth Capable' = false; 28 | attribute redefines 'Primary Interface' = "USB 1.1"; 29 | attribute redefines 'Secondary Interface' = "SPI"; 30 | attribute redefines 'WiFi Protocol' = "Wireless (802.11n)"; 31 | attribute redefines 'WiFi Frequency' = 2.4; // Another note 4 32 | // Another note 5 33 | } 34 | part def 'Bicool Round LCD IPS Display GC9A01' specializes 'LCD Display' {} 35 | 36 | part def 'TTRPG eToken System' { 37 | part 'controller board' : 'Controller Board'; 38 | part 'lcd display' : 'LCD Display'; 39 | part 'battery' : 'Battery'; 40 | } 41 | part def 'TTRPG eToken System Prototype' { 42 | part 'controller board' : 'Raspberry Pi Pico Wireless'; 43 | part 'lcd display' : 'Bicool Round LCD IPS Display GC9A01'; 44 | } 45 | } 46 | package Behavior{ 47 | 48 | part def 'User' {} 49 | use case def 'Change displayed image on eToken'{ 50 | actor 'user' : 'User'; 51 | objective { 52 | doc /*The user changes the displayed image on the eToken to one that is currently stored in storage*/ 53 | } 54 | } 55 | use case def 'Remove existing image form eToken'{ 56 | objective { 57 | doc /*The user deletes an image from the eToken currently stored in storage*/ 58 | } 59 | actor 'user' : 'User'; 60 | } 61 | use case def 'Load new image to eToken'{ 62 | objective { 63 | doc /*The user uploads a new image to the eToken's storage*/ 64 | } 65 | actor 'user' : 'User'; 66 | } 67 | use case def 'Use eToken as game piece'{ 68 | objective { 69 | doc /*The user places the eToken on the board to use as a game piece*/ 70 | } 71 | actor 'user' : 'User'; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /examples/models/model_test_2.sysml2: -------------------------------------------------------------------------------- 1 | // Be aware that anything after double forward slash on a single line is completely ignored and not part of the model. [1]: pg 16 2 | // My convention will be to annotate features of the SysML2 language with notes, along with references. 3 | // I will also include meta commentary on the PySysML2 reader in notes. 4 | 5 | // References ------------------------------------------------------------------------------------------------------------------------------------------------ 6 | // [1]: Intro to the SysML v2 Language-Textual Notation.pdf (https://github.com/Systems-Modeling/SysML-v2-Release/tree/master/doc) 7 | 8 | import ISQ::*; 9 | import ISQSpaceTime; 10 | import ScalarValues::*; 11 | 12 | package TTRPGeToken{ 13 | // These are examples of documentation style comments, regular comments, both named and unamed, along with Notes. 14 | // Be aware that any comment style text NOT blocked by double slashes is actually part of the model. [1]: pg 16 15 | // This is an example of a named documentation. [1]: pg 16 16 | doc overview /* The TTRPGeToken is a device used for displaying NPC/PC avatars in a physical token that can be used in a Table Top RPG game. */ 17 | 18 | // This is an example of unnamed documentation. [1]: pg 16 19 | doc /* TODO: include links to remotely hosted images */ 20 | 21 | doc // This is an exmple of an element ignoring whitespace and using a Note as an inline comment 22 | /* TODO: include links to public facing documentation */ 23 | 24 | // Named comment example. Also demonstrating carriage reteruns in comments. [1]: pg 16 25 | comment RevComment_1 /* TO: Maatlock: Please evaluate your vigorous use of commenting in the TTRPGeToken model. 26 | * Comment variety in the language seems... excessive. Don't get carried away! 27 | */ 28 | package Structure{ 29 | 30 | doc overview /* The structure package will contain all structural elements of the model */ 31 | 32 | // Note here that another doc comment named 'overview' has been created. These have unique names in the background, but 33 | // PySysML will have to replicate this behavior through implementation of fully qualified names, uids, auto-generated names 34 | // for unnamed elements 35 | 36 | // This is an example of composite structures, [1] pg. 16 37 | part def 'WiFi Component'; 38 | part def 'Bluetooth Component'; 39 | part def 'Integrated Wireless Chip' { 40 | attribute name : String; 41 | part wifiComponent : 'WiFi Component' { 42 | attribute 'WiFi Frequency' : Real; 43 | attribute 'WiFi Protocol' : String; 44 | } 45 | part btComponent : 'Bluetooth Component'{ 46 | attribute 'Bluetooth Protocol' : String; 47 | } 48 | } 49 | part def 'Controller Board' { 50 | 51 | part def 'wChip' specializes 'Integrated Wireless Chip'; 52 | attribute 'RAM_kb' : Integer; 53 | attribute 'Primary Interface' : String; 54 | attribute 'Secondary Interface' : String; 55 | attribute 'Bluetooth Capable' : Boolean; 56 | 57 | } 58 | part def 'LCD Display' {} 59 | part def 'Battery' { 60 | 61 | attribute isRechargeable : Boolean; 62 | attribute 'Battery Type' : String; 63 | attribute name : String; 64 | attribute avg_voltage_V : Real; 65 | attribute avg_capacity_mAh : Real; 66 | } 67 | part def 'Raspberry Pi Pico Wireless' specializes 'Controller Board' { 68 | doc info /*https://en.wikipedia.org/wiki/Raspberry_Pi*/ 69 | part def wChip_PiPicoW :> wChip{ 70 | attribute redefines name : String = "Infineon CYW43439"; 71 | part wifiComponet_PiPicoW :> wifiComponent{ 72 | attribute redefines 'WiFi Frequency': Real = 2.4; 73 | attribute :> 'WiFi Protocol': String = "IEEE 802.11 b/g/n wireless LAN"; 74 | } 75 | part btComponet_PiPicoW :> btComponent{ 76 | attribute redefines 'Bluetooth Protocol' : String = "Bluetooth 5.2"; 77 | } 78 | } 79 | attribute :> 'RAM_kb' = 264; 80 | attribute :> 'Bluetooth Capable' = true; 81 | attribute :> 'Primary Interface' = "USB 1.1"; 82 | attribute redefines 'Secondary Interface' = "SPI"; 83 | } 84 | 85 | part def 'AA Battery Duracell Quantum' specializes 'Battery' { 86 | attribute :> isRechargeable : Boolean = false; 87 | attribute :> 'Battery Type' : String = "AA"; 88 | attribute :> name : String = "Duracell Quantum"; 89 | attribute :> avg_voltage_V : Real = 1.5; 90 | attribute :> avg_capacity_mAh : Real = 2350.0; 91 | } 92 | // Specialize using the "subset" symbol 93 | part def 'Bicool Round LCD IPS Display GC9A01' :> 'LCD Display' {} 94 | 95 | part def 'TTRPG eToken System' { 96 | part 'controller board' : 'Controller Board'; 97 | part 'lcd display' : 'LCD Display'; 98 | part 'battery' : 'Battery'[1..2]; 99 | } 100 | part def 'TTRPG eToken System Prototype' { 101 | part 'controller board' : 'Raspberry Pi Pico Wireless'; 102 | part 'lcd display' : 'Bicool Round LCD IPS Display GC9A01'; 103 | part 'battery' : 'AA Battery Duracell Quantum'; 104 | } 105 | } 106 | package Behavior{ 107 | 108 | part def 'User' {} 109 | use case def 'Change displayed image on eToken'{ 110 | actor 'user' : 'User'; 111 | objective { 112 | doc /*The user changes the displayed image on the eToken to one that is currently stored in storage*/ 113 | } 114 | } 115 | use case def 'Remove existing image form eToken'{ 116 | objective { 117 | doc /*The user deletes an image from the eToken currently stored in storage*/ 118 | } 119 | actor 'user' : 'User'; 120 | } 121 | use case def 'Load new image to eToken'{ 122 | objective { 123 | doc /*The user uploads a new image to the eToken's storage*/ 124 | } 125 | actor 'user' : 'User'; 126 | } 127 | use case def 'Use eToken as game piece'{ 128 | objective { 129 | doc /*The user places the eToken on the board to use as a game piece*/ 130 | } 131 | actor 'user' : 'User'; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /examples/models/simplified_beagleplay.sysml2: -------------------------------------------------------------------------------- 1 | import ScalarValues::*; 2 | 3 | package SimplifiedModel { 4 | /* 5 | DoorMonitor is a model of a student project that uses the BeaglePlay to connect a USB Webcam to a Python script and upload 6 | selected footage to Twitch.io. 7 | https://elinux.org/ECE434_Project_-_IOT_Entry_Way_Camera 8 | */ 9 | part def Software; 10 | part def Hardware; 11 | part def Person; 12 | 13 | 14 | part BeaglePlay { 15 | /* 16 | The BeaglePlay model describes the hardware and software components of the BeaglePlay Single Board Computer (SBC) 17 | https://docs.beagle.cc/latest/boards/beagleplay/index.html 18 | https://docs.beagleboard.org/latest/beagleplay.pdf 19 | */ 20 | // External interface 21 | part HDMI_Transmitter { 22 | // HDMI can be considered part of the attack surface! 23 | port data; 24 | } 25 | part USB_A { 26 | port socket; 27 | } 28 | part USB_C { 29 | port socket; 30 | } 31 | part Ethernet_Connector { 32 | port ethernet; 33 | } 34 | part Button { 35 | port button; 36 | } 37 | part User_LED ; 38 | 39 | // Internal microchip components and memory 40 | part WiFI_chip; 41 | part BLE_SubG; // software defined radio 42 | part DDR4_8Gb_16bit; 43 | part Micro_SD_Card_Socket { 44 | port socket; 45 | } 46 | part AM62x { 47 | attribute manufacturer = "Texas Instruments"; 48 | comment RoleComment /* Main microprocessor */ 49 | port USB; 50 | port GPIO; // general purpose in/out pins 51 | port MSDC; // micro SD card 52 | port HDMI; 53 | 54 | } 55 | 56 | // Software 57 | part default_image { 58 | /* 59 | The default image included with the BeaglePlay, flashed Feb 2023 60 | Could be extracted from inside the BeaglePlay part 61 | */ 62 | part debian { 63 | attribute version = "11"; 64 | part Linux_Kernel ; 65 | // There are 1300 packages installed with the default image. A subset will need to be chosen 66 | } 67 | part openssh_server { 68 | attribute version = "8.4"; 69 | in port ssh_port { 70 | attribute protocol = "TCP"; 71 | attribute port_number = 22; 72 | } 73 | } 74 | part openssh_client { 75 | attribute version = "8.4"; 76 | out port ssh_port { 77 | attribute protocol = "TCP"; 78 | attribute port_number = 22; 79 | } 80 | } 81 | part libssl1_1; 82 | part python3 { 83 | attribute version = "3.9.2"; 84 | } 85 | part systemctl ; 86 | 87 | port external_network; // An abstraction to cleanly connect external interfaces like Ethernet 88 | port internal_network; // An abstraction to cleanly connect internal interfaces like openssh-server or applications 89 | 90 | connect external_network to internal_network; // could be through iptables or similar 91 | connect internal_network to openssh_server.ssh_port; 92 | connect openssh_client.ssh_port to internal_network; 93 | } 94 | 95 | 96 | // Internal Connections 97 | connect AM62x.HDMI to HDMI_Transmitter.data; 98 | connect AM62x.GPIO to BLE_SubG; // software-defined radio 99 | connect AM62x.GPIO to WiFI_chip; 100 | connect AM62x.MSDC to Micro_SD_Card_Socket; 101 | // connect AM62x.GPIO to 'User Button'; 102 | connect AM62.x.GPIO to Button.button; 103 | connect AM62x.GPIO to User_LED; 104 | connect AM62x.USB to USB_C; 105 | connect AM62x.USB to USB_A; 106 | 107 | // External Connections 108 | // port 'USB-A-Socket' { 109 | // attribute usb_type = "A"; 110 | // } 111 | // port 'USB-C-Socket' { 112 | // attribute usb_type = "C"; 113 | // } 114 | // port 'User Button'; 115 | // port 'Micro SD Socket' ; 116 | // bind 'USB-A-Socket' = USB_A.socket; 117 | // bind 'USB-C-Socket' = USB_C.socket; 118 | // bind Button.button = 'User Button'; 119 | // bind 'Micro SD Socket' = Micro_SD_Card_Socket.socket; 120 | 121 | connect default_image to AM62x; 122 | 123 | // Internet connections 124 | connection USB_C_internet { 125 | end part physical; 126 | end part network; 127 | attribute IP = "192.168.6.2"; 128 | } 129 | connect USB_C_internet.physical to AM62x.USB; 130 | connect USB_C_internet.network to default_image.external_network; 131 | 132 | connection WiFi { 133 | end part physical; 134 | end part network; 135 | } 136 | connect WiFi.network to default_image.external_network; 137 | connect WiFi.physical to WiFI_chip; 138 | 139 | connection Ethernet { 140 | end part physical; 141 | end part network; 142 | attribute IP = "192.168.7.2"; 143 | } 144 | 145 | connect Ethernet_Connector to Ethernet.physical; 146 | connect Ethernet.network to default_image.external_network; 147 | } 148 | 149 | part twitch_io { 150 | in port api_port { 151 | attribute protocol = "TCP"; 152 | attribute port_number = 443; 153 | } 154 | } 155 | 156 | part email_provider; 157 | 158 | part Webcam { 159 | port USB_A_plug; 160 | attribute image : String; 161 | } 162 | part Micro_SD_Card; 163 | connect Webcam.USB_A_plug to BeaglePlay.USB_A.socket; 164 | connect Micro_SD_Card to BeaglePlay.Micro_SD_Card_Socket.socket; 165 | part entrycam_script { 166 | part entrycam ; 167 | part imageProcessing ; 168 | part config { 169 | attribute Twitch_credentials : String; 170 | attribute email_credentials : String; 171 | attribute recipient_address : String; 172 | } 173 | part messaging ; 174 | connect entrycam to imageProcessing; 175 | connect entrycam to config; 176 | connect imageProcessing to config; 177 | connect imageProcessing to messaging; 178 | connect messaging to config; 179 | 180 | out port api_call { 181 | attribute protocol = "TCP"; 182 | attribute port_number = 443; 183 | } 184 | } 185 | part subprocess_python; 186 | part ffmpeg ; 187 | part cv2 ; 188 | 189 | connect entrycam_script.entrycam to cv2; 190 | connect entrycam_script.entrycam to subprocess_python; 191 | connect entrycam_script.imageProcessing to cv2; 192 | 193 | 194 | connect entrycam_script.imageProcessing to ffmpeg; 195 | 196 | // The application has three software connections: 197 | // it is loaded as a service through systemctl 198 | // it is invoked through python3 199 | // it makes outbound connections to the internet through the internal network 200 | connect BeaglePlay.default_image.systemctl to entrycam_script; 201 | connect BeaglePlay.default_image.python3 to entrycam_script; 202 | connect entrycam_script.api_call to BeaglePlay.default_image.internal_network; 203 | 204 | // Here's something interesting. Use this package to directly connect two other packages 205 | connect BeaglePlay.default_image.external_network to twitch_io.api_port; 206 | 207 | use case Monitor_Video_Telemetry { 208 | // Primary Mission 209 | subject system = BeaglePlay; 210 | // subject system; 211 | doc /* The system provides an uninterrupted stream of video telemetry via an online platform. */ 212 | actor monitoring_user : Person; 213 | 214 | // get telemetry from web cam 215 | include Stream_video_from_webcam { 216 | actor :>> script = entrycam_script; 217 | message of Webcam.image from Webcam to entrycam_script.imageProcessing; 218 | } 219 | // process telemetry with ffmpeg 220 | include Process_telemetry { 221 | actor software = entrycam_script; 222 | message of Webcam.image from entrycam_script.imageProcessing to subprocess_python; 223 | message of Webcam.image from subprocess_python to 'ffmpeg'; 224 | } 225 | 226 | use case Stream_to_Twitch { 227 | subject service = twitch_io; 228 | actor software = entrycam_script; 229 | actor viewer = monitoring_user; 230 | message of entrycam_script.config.Twitch_credentials from software to service; 231 | message of Webcam.image from 'ffmpeg' to service; 232 | } 233 | } 234 | 235 | use case Alert_on_Detected_Intruders { 236 | // Primary Mission 237 | subject system = BeaglePlay; 238 | doc /* The system sends an email alert when a human is detected in the video telemetry. */ 239 | actor monitoring_user : Person; 240 | actor intruder : Person; 241 | 242 | // get telemetry from web cam 243 | include Stream_video_from_webcam { 244 | actor :>> script = entrycam_script; 245 | message of Webcam.image from Webcam to script; 246 | } 247 | 248 | use case Detect_face { 249 | subject face_detector = cv2; 250 | actor script = entrycam_script; 251 | actor face = intruder; 252 | } 253 | 254 | use case Send_alert_message { 255 | subject service = email_provider; 256 | actor script = entrycam_script; 257 | actor recipient = monitoring_user; 258 | message of entrycam_script.config.email_credentials from script to service; 259 | message of entrycam_script.config.recipient_address from script to service; 260 | } 261 | 262 | } 263 | 264 | use case Stream_video_from_webcam { 265 | subject camera = Webcam; 266 | actor script : Software; 267 | } 268 | 269 | use case Process_telemetry { 270 | subject library = 'ffmpeg'; 271 | actor script : Software; 272 | } 273 | 274 | 275 | } -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "pysysml2" 3 | version = "0.1.1" 4 | description = "Python based parser for the SysML 2.0 textual modeling language." 5 | authors = ["Keith Lucas "] 6 | readme = "README.md" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.8" 10 | anytree = "^2.8.0" 11 | graphviz = "^0.20.1" 12 | numpy = "^1.24.2" 13 | pandas = "^2.0.1" 14 | openpyxl = "^3.1.1" 15 | antlr4-python3-runtime = "4.10" 16 | typer = "^0.7.0" 17 | 18 | 19 | [tool.poetry.group.dev.dependencies] 20 | pytest = "^7.2.1" 21 | jupyter = "^1.0.0" 22 | pytest-datadir = "^1.4.1" 23 | poetry2setup = "^1.1.0" 24 | poetry2conda = "^0.3.0" 25 | 26 | [tool.poetry.scripts] 27 | pysysml2 = "pysysml2.cli.__main__:app" 28 | 29 | [build-system] 30 | requires = ["poetry-core"] 31 | build-backend = "poetry.core.masonry.api" 32 | 33 | [tool.poetry_bumpversion.file."pysysml2/__init__.py"] 34 | search = '__version__ = "{current_version}"' 35 | replace = '__version__ = "{new_version}"' 36 | 37 | [tool.poetry2conda] 38 | name = "sysml2-env" 39 | 40 | [tool.poetry2conda.dependencies] 41 | anytree = { channel = "pip" } 42 | graphviz = { channel = "pip" } 43 | antlr4-python3-runtime = { channel = "pip" } 44 | -------------------------------------------------------------------------------- /pysysml2/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "0.1.1" 2 | -------------------------------------------------------------------------------- /pysysml2/cli/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/cli/__init__.py -------------------------------------------------------------------------------- /pysysml2/cli/__main__.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | from typing import Optional 4 | from typer import Argument, Option, Typer 5 | 6 | from pysysml2 import __version__ 7 | from pysysml2.modeling import Model 8 | from pysysml2.cli.ui import console 9 | 10 | app = Typer() 11 | 12 | 13 | @app.callback() 14 | def main(): 15 | """PySysML2 CLI tools.""" 16 | pass 17 | 18 | 19 | @app.command() 20 | def export( 21 | input: Path = Argument( 22 | ..., 23 | metavar="MODEL_FILE", 24 | help="The sysml2 model file.", 25 | exists=True, 26 | readable=True, 27 | resolve_path=True, 28 | ), 29 | format: str = Option( 30 | "json", 31 | "--format", 32 | help="One or more comma-separated output file formats. " 33 | "Supported formats: json,txt,csv,xlsx,dot,png", 34 | ), 35 | out_dir: Optional[Path] = Option( 36 | None, 37 | "-o", 38 | "--output-dir", 39 | help="The output directory for the generated file(s). Defaults to current " 40 | "directory.", 41 | resolve_path=True, 42 | ), 43 | ): 44 | """Export a SysML v2 model to various file formats.""" 45 | model = Model() # Create Model object 46 | model.from_sysml2_file(input) # Parse the textual model 47 | 48 | # Create output directory if not exist 49 | out_dir = out_dir or Path.cwd() 50 | os.makedirs(out_dir, exist_ok=True) 51 | 52 | console.print(f"Using output directory: {out_dir}") 53 | 54 | fmts = _parse_format_arg(format) 55 | for fmt in fmts: 56 | _serialize_model(model, fmt, out_dir) 57 | 58 | 59 | def _parse_format_arg(format: str): 60 | return format.split(",") 61 | 62 | 63 | def _serialize_model(model: Model, format: str, out_dirpath: Path): 64 | format = format.lower() 65 | out_dir = str(out_dirpath) 66 | 67 | if format == "json": 68 | console.print(f"Exporting to JSON...") 69 | model.to_JSON(out_dir) 70 | 71 | elif format == "csv": 72 | console.print(f"Exporting to csv...") 73 | model.to_csv(out_dir) 74 | 75 | elif format == "txt": 76 | console.print(f"Exporting to txt...") 77 | model.to_txt(out_dir) 78 | 79 | elif format in ("excel", "xlsx"): 80 | console.print(f"Exporting to xlsx...") 81 | model.to_excel(out_dir) 82 | 83 | elif format == "png": 84 | 85 | try: 86 | console.print(f"Exporting to png...") 87 | model.to_png(out_dir) 88 | 89 | except FileNotFoundError as e: 90 | if "No such file or directory: 'dot'" in str(e): 91 | console.error( 92 | message="Unable to export to png. " 93 | "Graphviz `dot` command not found." 94 | ) 95 | else: 96 | raise e 97 | 98 | elif format == "dot": 99 | console.print(f"Exporting to dot...") 100 | model.to_dot(out_dir) 101 | 102 | else: 103 | raise ValueError(f"Unknown format '{format}'") 104 | -------------------------------------------------------------------------------- /pysysml2/cli/ui.py: -------------------------------------------------------------------------------- 1 | from typing import Optional 2 | import click 3 | 4 | try: 5 | import rich 6 | import rich.console 7 | 8 | except ImportError: # pragma: nocover 9 | rich = None # type: ignore 10 | 11 | 12 | class Console: 13 | def __init__(self): 14 | if rich: 15 | self._rconsole = rich.console.Console() 16 | else: 17 | self._rconsole = None 18 | 19 | def print(self, message: Optional[str] = None, nl: bool = True, err: bool = False): 20 | if self._rconsole: 21 | self._rconsole.print(message) 22 | else: 23 | click.echo(message, nl=nl, err=err) 24 | 25 | def error(self, ename: str = "Error", message: str = ""): 26 | if self._rconsole: 27 | message = f"[red]{ename}:[/red] {message}" 28 | self._rconsole.print(message) 29 | else: 30 | message = f"{ename}: {message}" 31 | click.echo(message, err=True) 32 | 33 | 34 | console = Console() 35 | -------------------------------------------------------------------------------- /pysysml2/grammar/.antlr/SysML2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | KW_ABOUT=9 10 | KW_ACTOR=10 11 | KW_ATTRIBUTE=11 12 | KW_CASE=12 13 | KW_COMMENT=13 14 | KW_CONNECTION=14 15 | KW_CONNECT=15 16 | KW_DEF=16 17 | KW_DOC=17 18 | KW_FROM=18 19 | KW_END=19 20 | KW_IMPORT=20 21 | KW_INCLUDE=21 22 | KW_ITEM=22 23 | KW_MESSAGE=23 24 | KW_OBJECTIVE=24 25 | KW_PACKAGE=25 26 | KW_PART=26 27 | KW_PORT=27 28 | KW_REF=28 29 | KW_REDEFINES=29 30 | KW_SPECIALIZES=30 31 | KW_SUBJECT=31 32 | KW_SUBSETS=32 33 | KW_SYM_FQN=33 34 | KW_SYM_REDEFINES=34 35 | KW_SYM_SUBSETS=35 36 | KW_TO=36 37 | KW_USE=37 38 | KW_IN=38 39 | KW_OUT=39 40 | KW_OF=40 41 | CONSTANT=41 42 | TYPE=42 43 | ID=43 44 | INTEGER=44 45 | REAL=45 46 | BOOL=46 47 | STRING=47 48 | MULTIPLICITY=48 49 | NULL=49 50 | WS=50 51 | NOTE=51 52 | COMMENT_LONG=52 53 | '{'=1 54 | '}'=2 55 | ';'=3 56 | ','=4 57 | '='=5 58 | '.'=6 59 | ':'=7 60 | '*'=8 61 | 'about'=9 62 | 'actor'=10 63 | 'attribute'=11 64 | 'case'=12 65 | 'comment'=13 66 | 'connection'=14 67 | 'connect'=15 68 | 'def'=16 69 | 'doc'=17 70 | 'from'=18 71 | 'end'=19 72 | 'import'=20 73 | 'include'=21 74 | 'item'=22 75 | 'message'=23 76 | 'objective'=24 77 | 'package'=25 78 | 'part'=26 79 | 'port'=27 80 | 'ref'=28 81 | 'redefines'=29 82 | 'specializes'=30 83 | 'subject'=31 84 | 'subsets'=32 85 | '::'=33 86 | ':>>'=34 87 | ':>'=35 88 | 'to'=36 89 | 'use'=37 90 | 'in'=38 91 | 'out'=39 92 | 'of'=40 93 | 'null'=49 94 | -------------------------------------------------------------------------------- /pysysml2/grammar/.antlr/SysML2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | KW_ABOUT=9 10 | KW_ACTOR=10 11 | KW_ATTRIBUTE=11 12 | KW_CASE=12 13 | KW_COMMENT=13 14 | KW_CONNECTION=14 15 | KW_CONNECT=15 16 | KW_DEF=16 17 | KW_DOC=17 18 | KW_FROM=18 19 | KW_END=19 20 | KW_IMPORT=20 21 | KW_INCLUDE=21 22 | KW_ITEM=22 23 | KW_MESSAGE=23 24 | KW_OBJECTIVE=24 25 | KW_PACKAGE=25 26 | KW_PART=26 27 | KW_PORT=27 28 | KW_REF=28 29 | KW_REDEFINES=29 30 | KW_SPECIALIZES=30 31 | KW_SUBJECT=31 32 | KW_SUBSETS=32 33 | KW_SYM_FQN=33 34 | KW_SYM_REDEFINES=34 35 | KW_SYM_SUBSETS=35 36 | KW_TO=36 37 | KW_USE=37 38 | KW_IN=38 39 | KW_OUT=39 40 | KW_OF=40 41 | CONSTANT=41 42 | TYPE=42 43 | ID=43 44 | INTEGER=44 45 | REAL=45 46 | BOOL=46 47 | STRING=47 48 | MULTIPLICITY=48 49 | NULL=49 50 | WS=50 51 | NOTE=51 52 | COMMENT_LONG=52 53 | '{'=1 54 | '}'=2 55 | ';'=3 56 | ','=4 57 | '='=5 58 | '.'=6 59 | ':'=7 60 | '*'=8 61 | 'about'=9 62 | 'actor'=10 63 | 'attribute'=11 64 | 'case'=12 65 | 'comment'=13 66 | 'connection'=14 67 | 'connect'=15 68 | 'def'=16 69 | 'doc'=17 70 | 'from'=18 71 | 'end'=19 72 | 'import'=20 73 | 'include'=21 74 | 'item'=22 75 | 'message'=23 76 | 'objective'=24 77 | 'package'=25 78 | 'part'=26 79 | 'port'=27 80 | 'ref'=28 81 | 'redefines'=29 82 | 'specializes'=30 83 | 'subject'=31 84 | 'subsets'=32 85 | '::'=33 86 | ':>>'=34 87 | ':>'=35 88 | 'to'=36 89 | 'use'=37 90 | 'in'=38 91 | 'out'=39 92 | 'of'=40 93 | 'null'=49 94 | -------------------------------------------------------------------------------- /pysysml2/grammar/SysML2.g4: -------------------------------------------------------------------------------- 1 | // References 2 | // [1]: Intro to the SysML v2 Language-Textual Notation.pdf 3 | 4 | // When using Antlr4 command line tool, use the following example commands: 5 | // antlr4 SysML2.g4 -visitor -o distj 6 | // antlr4 -Dlanguage=Python3 SysML2.g4 -visitor -o distpy 7 | // // Switch to distj and compile 8 | // javac -classpath %ANTLR4_HOME%\lib\antlr-4.10.1-complete.jar; *.java 9 | // // Run GUI 10 | // grun SysML2 model -gui D:\GitHub\PySysML2\test_models\model_test_2.sysml2 11 | 12 | // Language Declaration 13 | grammar SysML2; 14 | 15 | // A model is a set of elements that runs until the end of the file 16 | model: element* EOF; 17 | // An element is anything that can be a part of a model 18 | element : namespace 19 | | feature 20 | | comment 21 | | doc 22 | | statement 23 | | port 24 | ; 25 | 26 | // A namespace is an element with a scope defined by curly braces 27 | namespace : sysml2_package 28 | | part 29 | | use_case_def 30 | | comment 31 | | doc 32 | | port 33 | | connect 34 | ; 35 | //------------------------------------------------------------------------------ 36 | sysml2_package: KW_PACKAGE ID '{' namespace* '}'; 37 | part_blk: (feature | comment | doc | part | port | connect | connection); 38 | part: (part_def | part_def_specializes); 39 | // part_def: ((KW_PART KW_DEF ID '{' part_blk* '}')|(KW_PART KW_DEF ID';')); 40 | part_def: ((KW_PART KW_DEF? ID '{' part_blk* '}') | (KW_PART KW_DEF? ID ';')); 41 | 42 | 43 | 44 | // e.g. part def wChip specializes 'Integrated Wireless Chip'; 45 | // e.g. part def 'Bicool Round LCD IPS Display GC9A01' specializes 'LCD Display' {} 46 | // e.g. part def 'Raspberry Pi Pico Wireless' specializes 'Controller Board' 47 | part_def_specializes: KW_PART KW_DEF? ID (KW_SPECIALIZES | KW_SYM_SUBSETS) ID (',' ID)*? ('{' part_blk* '}' | ';'); 48 | 49 | 50 | // Ports 51 | port: (port_def | port_blk); 52 | // e.g. port 'socket 1'; 53 | port_def: (KW_IN | KW_OUT)? KW_PORT ID ';' | ((KW_IN | KW_OUT)? KW_PORT ID '{' port_blk* '}'); 54 | port_blk: (feature | comment | doc ); 55 | 56 | 57 | // Use Cases [1] pg. 95 58 | use_case_blk : part_blk 59 | | objective_def 60 | | subject_def 61 | | include 62 | | use_case_def 63 | | message 64 | ; 65 | use_case_def: KW_USE KW_CASE KW_DEF? ID '{' use_case_blk* '}'; 66 | 67 | // Objective Definition [1] pg. 95 68 | part_objective_blk: doc; 69 | objective_def: KW_OBJECTIVE '{' part_objective_blk '}'; 70 | 71 | // Subject Definition 72 | subject_def: KW_SUBJECT ID '=' ID ';'; 73 | 74 | // Include blk 75 | include: KW_INCLUDE ID '{' include_blk* '}'; 76 | include_blk: part_blk 77 | | objective_def 78 | | subject_def 79 | | message 80 | ; 81 | message: (KW_MESSAGE KW_OF message_expr KW_FROM message_expr KW_TO message_expr ';')| 82 | (KW_MESSAGE KW_OF message_expr KW_FROM message_expr KW_TO message_expr '{' feature* '}') ; 83 | message_expr: ID ('.' ID)*?; 84 | 85 | // A feature is an element that is part of a namespace, e.g. package or part, 86 | // usually defined with a semicolon ending the line 87 | feature : feature_attribute_def 88 | | feature_attribute_redefines 89 | | feature_part_specializes 90 | | feature_part_specializes_subsets 91 | | feature_item_def 92 | | feature_item_ref 93 | | feature_actor_specializes 94 | ; 95 | //------------------------------------------------------------------------------ 96 | 97 | // Connections 98 | connection: KW_CONNECTION ID '{' connection_blk* '}'; 99 | connection_blk: (end_part | feature_attribute_def); 100 | end_part: KW_END KW_PART ID ';'; 101 | 102 | 103 | // Connect relationships 104 | connect: KW_CONNECT connect_expr KW_TO connect_expr ';'; 105 | connect_expr: ID ('.' ID)*?; 106 | // connect: KW_CONNECT ID ('.' ID)? KW_TO ID ('.' ID)? ';'; 107 | 108 | // Attributes 109 | // feature_attribute_def: KW_ATTRIBUTE ID ':' TYPE ';'; 110 | feature_attribute_def: KW_ATTRIBUTE ID ':' TYPE ';' | KW_ATTRIBUTE ID '=' CONSTANT ';'; 111 | 112 | // E.g. attribute :> 'WiFi Protocol': String = "IEEE 802.11 b/g/n wireless LAN"; 113 | // E.g. attribute redefines 'Primary Interface' = "USB 1.1"; 114 | // E.g. attribute :> 'WiFi Protocol': String = "IEEE 802.11 b/g/n wireless LAN"; 115 | feature_attribute_redefines: KW_ATTRIBUTE (KW_REDEFINES | KW_SYM_REDEFINES | KW_SYM_SUBSETS) ID (':' TYPE)? '=' CONSTANT ';'; 116 | // Part specializations and subsets 117 | feature_part_specializes: KW_PART ID ':' ID MULTIPLICITY? (';' | '{' part_blk* '}'); 118 | feature_part_specializes_subsets: KW_PART ID ':' ID MULTIPLICITY? (KW_SUBSETS | KW_SYM_SUBSETS) ID';'; 119 | // Items, [1] pg. 17 120 | feature_item_def: KW_ITEM ID';'; 121 | // The "ref" kw is optional. It's presented as maybe different in text, but visualized the same way 122 | // In other words, "item driver : Person" is the same as "ref item driver : Person" 123 | // Note that this appears to be a specialization, but the "specialize" kw doesn't work 124 | // as it does with part redefinititons, nor the :> symbol. Super quirky! 125 | feature_item_ref: KW_REF? KW_ITEM ID ':' ID';'; 126 | // Actors, [1] pg. 95 127 | // Actors are (referential) part usages and so must have part definitions 128 | feature_actor_specializes: KW_ACTOR KW_SYM_REDEFINES? ID (':' ID | '=' ID) MULTIPLICITY? ';'; 129 | 130 | 131 | 132 | // SysML2 "comments" are part of the model propper. 133 | // Notes, on the other hand, are comments in the 134 | // traditional sense, i.e. ignored by parser 135 | comment : comment_unnamed 136 | | comment_named 137 | | comment_named_about 138 | ; 139 | //------------------------------------------------------------------------------ 140 | // An unnamed comment, e.g. 141 | // /* This is a comment */ 142 | comment_unnamed: COMMENT_LONG; 143 | // A named comment, owned by element defined in, e.g. 144 | // comment CommentName /* This is a comment */ 145 | comment_named: KW_COMMENT ID COMMENT_LONG; 146 | // A named comment, owned by element specified in, e.g. 147 | // comment CommentName about OwningElement /* This is a comment */ 148 | comment_named_about: KW_COMMENT KW_ABOUT ID COMMENT_LONG; 149 | 150 | // Documentation are special comments directly owned by the element they document 151 | doc : doc_unnamed 152 | | doc_named 153 | ; 154 | //------------------------------------------------------------------------------ 155 | // Unamed documentation comment, owned by an element, e.g. 156 | // doc /* This is a document */ 157 | doc_unnamed: KW_DOC COMMENT_LONG; 158 | // Named documentation comment, owned by an element, e.g. 159 | // doc DocName /* This is a named document */ 160 | doc_named: KW_DOC ID COMMENT_LONG; 161 | 162 | // Statements 163 | // Statements are lines of code that execute an action like importing a package 164 | // A Statement can occur anywhere, even outside of a package or part. This type 165 | // of behavior is makes a statement part of the element grammar definition. 166 | //------------------------------------------------------------------------------ 167 | statement : import_package; 168 | import_package: KW_IMPORT ID (KW_SYM_FQN ID)* (KW_SYM_FQN '*')? ';'; 169 | 170 | 171 | // Keywords 172 | // Per Antrl4 "longest match" rule, keywords that contain substrings that match 173 | // other keywords MUST be defined first. For example, 'import' must be defined 174 | // before 'port' because 'import' contains 'port' 175 | //------------------------------------------------------------------------------ 176 | KW_ABOUT: 'about'; 177 | KW_ACTOR: 'actor'; 178 | KW_ATTRIBUTE: 'attribute'; 179 | KW_CASE: 'case'; 180 | KW_COMMENT: 'comment'; 181 | KW_CONNECTION: 'connection'; // 'connection' before 'connect', per Antlr4 "longest match" rule 182 | KW_CONNECT: 'connect'; 183 | KW_DEF: 'def'; 184 | KW_DOC: 'doc'; 185 | // Update 186 | KW_FROM: 'from'; 187 | KW_END: 'end'; 188 | KW_IMPORT: 'import'; // 'import' before 'port', per Antlr4 "longest match" rule 189 | // Include 190 | KW_INCLUDE: 'include'; 191 | KW_ITEM: 'item'; 192 | // Update 193 | KW_MESSAGE: 'message'; 194 | KW_OBJECTIVE: 'objective'; 195 | KW_PACKAGE: 'package'; 196 | KW_PART: 'part'; 197 | KW_PORT: 'port'; 198 | KW_REF: 'ref'; 199 | KW_REDEFINES: 'redefines'; 200 | KW_SPECIALIZES: 'specializes'; 201 | KW_SUBJECT: 'subject'; 202 | KW_SUBSETS: 'subsets'; 203 | KW_SYM_FQN: '::'; 204 | KW_SYM_REDEFINES: ':>>'; 205 | KW_SYM_SUBSETS: ':>'; 206 | KW_TO: 'to'; 207 | KW_USE: 'use'; 208 | // Update 209 | KW_IN: 'in'; 210 | // Update 211 | KW_OUT: 'out'; 212 | KW_OF: 'of'; 213 | 214 | // Tokens 215 | CONSTANT: INTEGER | REAL | BOOL | STRING | NULL; 216 | TYPE: 'Integer' | 'Real' | 'Boolean' | 'String'; 217 | ID: '\'' [ a-zA-Z_][ a-zA-Z0-9_/-]* '\'' | [a-zA-Z_][a-zA-Z0-9_/-]*; 218 | INTEGER: [0-9]+; 219 | REAL: [0-9]+ '.' [0-9]+; 220 | BOOL: 'true' | 'false'; 221 | // TYPE: 'Integer' | 'Real' | 'Boolean' | 'String' | 'Type'; 222 | STRING: '"' (ESC | ~ ["\\])* '"'; 223 | //STRING2: '\'' (ESC | ~ ["\\])* '\''; 224 | MULTIPLICITY: '[' INTEGER '..' INTEGER ']'; 225 | fragment ESC: '\\' (["\\/bfnrt] | UNICODE); 226 | fragment UNICODE: 'u' HEX HEX HEX HEX; 227 | fragment HEX: [0-9a-fA-F]; 228 | NULL: 'null'; 229 | WS: [ \t\r\n]+ -> skip; 230 | // Notes are special comments that are ignored and not part of the model 231 | //------------------------------------------------------------------------------ 232 | NOTE: '//' ~[\r\n]* -> skip; 233 | COMMENT_LONG: '/*'.*?'*/'; 234 | -------------------------------------------------------------------------------- /pysysml2/grammar/SysML2_grammar.g4: -------------------------------------------------------------------------------- 1 | grammar SysML2; 2 | 3 | // A model is a set of elements that runs until the end of the file 4 | model: element* EOF; 5 | // An element is anything that can be a part of a model 6 | element : namespace | feature | comment | doc | statement; 7 | 8 | // A namespace is an element with a scope defined by curly braces 9 | namespace : sysml2_package | part | use_case_def | comment | doc; 10 | //------------------------------------------------------------------------------ 11 | sysml2_package: KW_PACKAGE ID '{' namespace* '}'; 12 | 13 | // Parts 14 | part_blk: (feature | comment | doc | part_def_specializes); 15 | part: (part_def | part_def_specializes); 16 | part_def: ((KW_PART KW_DEF ID '{' part_blk* '}')|(KW_PART KW_DEF ID';')); 17 | part_def_specializes: KW_PART KW_DEF? ID (KW_SPECIALIZES 18 | | KW_SYM_SUBSETS) ID (',' ID)*? 19 | ('{' part_blk* '}' | ';'); 20 | 21 | // Use Cases 22 | use_case_blk: part_blk | objective_def; 23 | use_case_def: KW_USE KW_CASE KW_DEF ID '{' use_case_blk* '}'; 24 | part_objective_blk: doc; 25 | objective_def: KW_OBJECTIVE '{' part_objective_blk '}'; 26 | 27 | // A feature is an element that is part of a namespace 28 | feature : feature_attribute_def | feature_attribute_redefines 29 | | feature_part_specializes 30 | | feature_part_specializes_subsets 31 | | feature_item_def 32 | | feature_item_ref 33 | | feature_actor_specializes 34 | ; 35 | 36 | // Attributes 37 | feature_attribute_def: KW_ATTRIBUTE ID ':' TYPE ';'; 38 | feature_attribute_redefines: KW_ATTRIBUTE (KW_REDEFINES | KW_SYM_REDEFINES | KW_SYM_SUBSETS) ID (':' TYPE)? '=' CONSTANT ';'; 39 | feature_part_specializes: KW_PART ID ':' ID MULTIPLICITY? (';' | '{' part_blk* '}'); 40 | feature_part_specializes_subsets: KW_PART ID ':' ID MULTIPLICITY? (KW_SUBSETS | KW_SYM_SUBSETS) ID';'; 41 | feature_item_def: KW_ITEM ID';'; 42 | feature_item_ref: KW_REF? KW_ITEM ID ':' ID';'; 43 | feature_actor_specializes: KW_ACTOR ID ':' ID MULTIPLICITY?';'; 44 | 45 | // SysML2 "comments" 46 | comment : comment_unnamed | comment_named | comment_named_about; 47 | comment_unnamed: COMMENT_LONG; 48 | comment_named: KW_COMMENT ID COMMENT_LONG; 49 | comment_named_about: KW_COMMENT KW_ABOUT ID COMMENT_LONG; 50 | 51 | // Documentation 52 | doc : doc_unnamed | doc_named; 53 | doc_unnamed: KW_DOC COMMENT_LONG; 54 | doc_named: KW_DOC ID COMMENT_LONG; 55 | 56 | // Statements 57 | statement : import_package; 58 | import_package: KW_IMPORT ID (KW_SYM_FQN ID)* (KW_SYM_FQN '*')? ';'; 59 | 60 | // Keywords 61 | KW_ABOUT: 'about'; 62 | KW_ACTOR: 'actor'; 63 | KW_ATTRIBUTE: 'attribute'; 64 | KW_CASE: 'case'; 65 | KW_COMMENT: 'comment'; 66 | KW_DEF: 'def'; 67 | KW_DOC: 'doc'; 68 | KW_IMPORT: 'import'; 69 | KW_ITEM: 'item'; 70 | KW_OBJECTIVE: 'objective'; 71 | KW_PACKAGE: 'package'; 72 | KW_PART: 'part'; 73 | KW_REDEFINES: 'redefines'; 74 | KW_REF: 'ref'; 75 | KW_SPECIALIZES: 'specializes'; 76 | KW_SUBJECT: 'subject'; 77 | KW_SUBSETS: 'subsets'; 78 | KW_USE: 'use'; 79 | KW_SYM_FQN: '::'; 80 | KW_SYM_REDEFINES: ':>>'; 81 | KW_SYM_SUBSETS: ':>'; 82 | 83 | // Tokens 84 | CONSTANT: INTEGER | REAL | BOOL | STRING | NULL; 85 | TYPE: 'Integer' | 'Real' | 'Boolean' | 'String'; 86 | ID: '\'' [ a-zA-Z_][ a-zA-Z0-9_]* '\'' | [a-zA-Z_][a-zA-Z0-9_]*; 87 | INTEGER: [0-9]+; 88 | REAL: [0-9]+ '.' [0-9]+; 89 | BOOL: 'true' | 'false'; 90 | STRING: '"' (ESC | ~ ["\\])* '"'; 91 | MULTIPLICITY: '[' INTEGER '..' INTEGER ']'; 92 | fragment ESC: '\\' (["\\/bfnrt] | UNICODE); 93 | fragment UNICODE: 'u' HEX HEX HEX HEX; 94 | fragment HEX: [0-9a-fA-F]; 95 | NULL: 'null'; 96 | WS: [ \t\r\n]+ -> skip; 97 | NOTE: '//' ~[\r\n]* -> skip; 98 | COMMENT_LONG: '/*'.*?'*/'; 99 | -------------------------------------------------------------------------------- /pysysml2/grammar/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/__init__.py -------------------------------------------------------------------------------- /pysysml2/grammar/antlr4_helper.py: -------------------------------------------------------------------------------- 1 | from antlr4 import Lexer, Parser 2 | from enum import Enum 3 | 4 | 5 | def build_lexer_literal_enum(lexer: Lexer, enum_name, prefix="KW_"): 6 | dd = { 7 | k: lexer.literalNames[getattr(lexer, k)].strip("'") 8 | for k in dir(lexer) 9 | if k.startswith(prefix) 10 | } 11 | return Enum(enum_name, dd) 12 | 13 | 14 | def build_parser_context_names_enum(parser: Parser, enum_name, contains="Context"): 15 | 16 | dd = {k: k for k in dir(parser) if contains in k and k[0].isupper()} 17 | return Enum(enum_name, dd) 18 | 19 | 20 | def get_overridden_methods(cls): 21 | """_summary_ 22 | Get all overridden methods of a class 23 | Source: https://stackoverflow.com/questions/58540997/get-overridden-functions-of-subclass 24 | Returns: 25 | _type_: _description_ 26 | """ 27 | # collect all attributes inherited from parent classes 28 | parent_attrs = set() 29 | for base in cls.__bases__: 30 | parent_attrs.update(dir(base)) 31 | 32 | # find all methods implemented in the class itself 33 | methods = {name for name, thing in vars(cls).items() if callable(thing)} 34 | 35 | # return the intersection of both 36 | return parent_attrs.intersection(methods) 37 | -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_PORT=20 21 | KW_REDEFINES=21 22 | KW_REF=22 23 | KW_SPECIALIZES=23 24 | KW_SUBJECT=24 25 | KW_SUBSETS=25 26 | KW_USE=26 27 | KW_SYM_FQN=27 28 | KW_SYM_REDEFINES=28 29 | KW_SYM_SUBSETS=29 30 | CONSTANT=30 31 | TYPE=31 32 | ID=32 33 | INTEGER=33 34 | REAL=34 35 | BOOL=35 36 | STRING=36 37 | MULTIPLICITY=37 38 | NULL=38 39 | WS=39 40 | NOTE=40 41 | COMMENT_LONG=41 42 | '{'=1 43 | '}'=2 44 | ';'=3 45 | ','=4 46 | ':'=5 47 | '='=6 48 | '*'=7 49 | 'about'=8 50 | 'actor'=9 51 | 'attribute'=10 52 | 'case'=11 53 | 'comment'=12 54 | 'def'=13 55 | 'doc'=14 56 | 'import'=15 57 | 'item'=16 58 | 'objective'=17 59 | 'package'=18 60 | 'part'=19 61 | 'port'=20 62 | 'redefines'=21 63 | 'ref'=22 64 | 'specializes'=23 65 | 'subject'=24 66 | 'subsets'=25 67 | 'use'=26 68 | '::'=27 69 | ':>>'=28 70 | ':>'=29 71 | 'null'=38 72 | -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2BaseListener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2BaseListener.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2BaseVisitor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2BaseVisitor.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2BaseVisitor.java: -------------------------------------------------------------------------------- 1 | // Generated from SysML2.g4 by ANTLR 4.13.2 2 | import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor; 3 | 4 | /** 5 | * This class provides an empty implementation of {@link SysML2Visitor}, 6 | * which can be extended to create a visitor which only needs to handle a subset 7 | * of the available methods. 8 | * 9 | * @param The return type of the visit operation. Use {@link Void} for 10 | * operations with no return type. 11 | */ 12 | @SuppressWarnings("CheckReturnValue") 13 | public class SysML2BaseVisitor extends AbstractParseTreeVisitor implements SysML2Visitor { 14 | /** 15 | * {@inheritDoc} 16 | * 17 | *

The default implementation returns the result of calling 18 | * {@link #visitChildren} on {@code ctx}.

19 | */ 20 | @Override public T visitModel(SysML2Parser.ModelContext ctx) { return visitChildren(ctx); } 21 | /** 22 | * {@inheritDoc} 23 | * 24 | *

The default implementation returns the result of calling 25 | * {@link #visitChildren} on {@code ctx}.

26 | */ 27 | @Override public T visitElement(SysML2Parser.ElementContext ctx) { return visitChildren(ctx); } 28 | /** 29 | * {@inheritDoc} 30 | * 31 | *

The default implementation returns the result of calling 32 | * {@link #visitChildren} on {@code ctx}.

33 | */ 34 | @Override public T visitNamespace(SysML2Parser.NamespaceContext ctx) { return visitChildren(ctx); } 35 | /** 36 | * {@inheritDoc} 37 | * 38 | *

The default implementation returns the result of calling 39 | * {@link #visitChildren} on {@code ctx}.

40 | */ 41 | @Override public T visitSysml2_package(SysML2Parser.Sysml2_packageContext ctx) { return visitChildren(ctx); } 42 | /** 43 | * {@inheritDoc} 44 | * 45 | *

The default implementation returns the result of calling 46 | * {@link #visitChildren} on {@code ctx}.

47 | */ 48 | @Override public T visitPart_blk(SysML2Parser.Part_blkContext ctx) { return visitChildren(ctx); } 49 | /** 50 | * {@inheritDoc} 51 | * 52 | *

The default implementation returns the result of calling 53 | * {@link #visitChildren} on {@code ctx}.

54 | */ 55 | @Override public T visitPart(SysML2Parser.PartContext ctx) { return visitChildren(ctx); } 56 | /** 57 | * {@inheritDoc} 58 | * 59 | *

The default implementation returns the result of calling 60 | * {@link #visitChildren} on {@code ctx}.

61 | */ 62 | @Override public T visitPart_def(SysML2Parser.Part_defContext ctx) { return visitChildren(ctx); } 63 | /** 64 | * {@inheritDoc} 65 | * 66 | *

The default implementation returns the result of calling 67 | * {@link #visitChildren} on {@code ctx}.

68 | */ 69 | @Override public T visitPart_def_specializes(SysML2Parser.Part_def_specializesContext ctx) { return visitChildren(ctx); } 70 | /** 71 | * {@inheritDoc} 72 | * 73 | *

The default implementation returns the result of calling 74 | * {@link #visitChildren} on {@code ctx}.

75 | */ 76 | @Override public T visitPort(SysML2Parser.PortContext ctx) { return visitChildren(ctx); } 77 | /** 78 | * {@inheritDoc} 79 | * 80 | *

The default implementation returns the result of calling 81 | * {@link #visitChildren} on {@code ctx}.

82 | */ 83 | @Override public T visitPort_def(SysML2Parser.Port_defContext ctx) { return visitChildren(ctx); } 84 | /** 85 | * {@inheritDoc} 86 | * 87 | *

The default implementation returns the result of calling 88 | * {@link #visitChildren} on {@code ctx}.

89 | */ 90 | @Override public T visitPort_blk(SysML2Parser.Port_blkContext ctx) { return visitChildren(ctx); } 91 | /** 92 | * {@inheritDoc} 93 | * 94 | *

The default implementation returns the result of calling 95 | * {@link #visitChildren} on {@code ctx}.

96 | */ 97 | @Override public T visitUse_case_blk(SysML2Parser.Use_case_blkContext ctx) { return visitChildren(ctx); } 98 | /** 99 | * {@inheritDoc} 100 | * 101 | *

The default implementation returns the result of calling 102 | * {@link #visitChildren} on {@code ctx}.

103 | */ 104 | @Override public T visitUse_case_def(SysML2Parser.Use_case_defContext ctx) { return visitChildren(ctx); } 105 | /** 106 | * {@inheritDoc} 107 | * 108 | *

The default implementation returns the result of calling 109 | * {@link #visitChildren} on {@code ctx}.

110 | */ 111 | @Override public T visitPart_objective_blk(SysML2Parser.Part_objective_blkContext ctx) { return visitChildren(ctx); } 112 | /** 113 | * {@inheritDoc} 114 | * 115 | *

The default implementation returns the result of calling 116 | * {@link #visitChildren} on {@code ctx}.

117 | */ 118 | @Override public T visitObjective_def(SysML2Parser.Objective_defContext ctx) { return visitChildren(ctx); } 119 | /** 120 | * {@inheritDoc} 121 | * 122 | *

The default implementation returns the result of calling 123 | * {@link #visitChildren} on {@code ctx}.

124 | */ 125 | @Override public T visitFeature(SysML2Parser.FeatureContext ctx) { return visitChildren(ctx); } 126 | /** 127 | * {@inheritDoc} 128 | * 129 | *

The default implementation returns the result of calling 130 | * {@link #visitChildren} on {@code ctx}.

131 | */ 132 | @Override public T visitFeature_attribute_def(SysML2Parser.Feature_attribute_defContext ctx) { return visitChildren(ctx); } 133 | /** 134 | * {@inheritDoc} 135 | * 136 | *

The default implementation returns the result of calling 137 | * {@link #visitChildren} on {@code ctx}.

138 | */ 139 | @Override public T visitFeature_attribute_redefines(SysML2Parser.Feature_attribute_redefinesContext ctx) { return visitChildren(ctx); } 140 | /** 141 | * {@inheritDoc} 142 | * 143 | *

The default implementation returns the result of calling 144 | * {@link #visitChildren} on {@code ctx}.

145 | */ 146 | @Override public T visitFeature_part_specializes(SysML2Parser.Feature_part_specializesContext ctx) { return visitChildren(ctx); } 147 | /** 148 | * {@inheritDoc} 149 | * 150 | *

The default implementation returns the result of calling 151 | * {@link #visitChildren} on {@code ctx}.

152 | */ 153 | @Override public T visitFeature_part_specializes_subsets(SysML2Parser.Feature_part_specializes_subsetsContext ctx) { return visitChildren(ctx); } 154 | /** 155 | * {@inheritDoc} 156 | * 157 | *

The default implementation returns the result of calling 158 | * {@link #visitChildren} on {@code ctx}.

159 | */ 160 | @Override public T visitFeature_item_def(SysML2Parser.Feature_item_defContext ctx) { return visitChildren(ctx); } 161 | /** 162 | * {@inheritDoc} 163 | * 164 | *

The default implementation returns the result of calling 165 | * {@link #visitChildren} on {@code ctx}.

166 | */ 167 | @Override public T visitFeature_item_ref(SysML2Parser.Feature_item_refContext ctx) { return visitChildren(ctx); } 168 | /** 169 | * {@inheritDoc} 170 | * 171 | *

The default implementation returns the result of calling 172 | * {@link #visitChildren} on {@code ctx}.

173 | */ 174 | @Override public T visitFeature_actor_specializes(SysML2Parser.Feature_actor_specializesContext ctx) { return visitChildren(ctx); } 175 | /** 176 | * {@inheritDoc} 177 | * 178 | *

The default implementation returns the result of calling 179 | * {@link #visitChildren} on {@code ctx}.

180 | */ 181 | @Override public T visitComment(SysML2Parser.CommentContext ctx) { return visitChildren(ctx); } 182 | /** 183 | * {@inheritDoc} 184 | * 185 | *

The default implementation returns the result of calling 186 | * {@link #visitChildren} on {@code ctx}.

187 | */ 188 | @Override public T visitComment_unnamed(SysML2Parser.Comment_unnamedContext ctx) { return visitChildren(ctx); } 189 | /** 190 | * {@inheritDoc} 191 | * 192 | *

The default implementation returns the result of calling 193 | * {@link #visitChildren} on {@code ctx}.

194 | */ 195 | @Override public T visitComment_named(SysML2Parser.Comment_namedContext ctx) { return visitChildren(ctx); } 196 | /** 197 | * {@inheritDoc} 198 | * 199 | *

The default implementation returns the result of calling 200 | * {@link #visitChildren} on {@code ctx}.

201 | */ 202 | @Override public T visitComment_named_about(SysML2Parser.Comment_named_aboutContext ctx) { return visitChildren(ctx); } 203 | /** 204 | * {@inheritDoc} 205 | * 206 | *

The default implementation returns the result of calling 207 | * {@link #visitChildren} on {@code ctx}.

208 | */ 209 | @Override public T visitDoc(SysML2Parser.DocContext ctx) { return visitChildren(ctx); } 210 | /** 211 | * {@inheritDoc} 212 | * 213 | *

The default implementation returns the result of calling 214 | * {@link #visitChildren} on {@code ctx}.

215 | */ 216 | @Override public T visitDoc_unnamed(SysML2Parser.Doc_unnamedContext ctx) { return visitChildren(ctx); } 217 | /** 218 | * {@inheritDoc} 219 | * 220 | *

The default implementation returns the result of calling 221 | * {@link #visitChildren} on {@code ctx}.

222 | */ 223 | @Override public T visitDoc_named(SysML2Parser.Doc_namedContext ctx) { return visitChildren(ctx); } 224 | /** 225 | * {@inheritDoc} 226 | * 227 | *

The default implementation returns the result of calling 228 | * {@link #visitChildren} on {@code ctx}.

229 | */ 230 | @Override public T visitStatement(SysML2Parser.StatementContext ctx) { return visitChildren(ctx); } 231 | /** 232 | * {@inheritDoc} 233 | * 234 | *

The default implementation returns the result of calling 235 | * {@link #visitChildren} on {@code ctx}.

236 | */ 237 | @Override public T visitImport_package(SysML2Parser.Import_packageContext ctx) { return visitChildren(ctx); } 238 | } -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Lexer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Lexer.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_PORT=20 21 | KW_REDEFINES=21 22 | KW_REF=22 23 | KW_SPECIALIZES=23 24 | KW_SUBJECT=24 25 | KW_SUBSETS=25 26 | KW_USE=26 27 | KW_SYM_FQN=27 28 | KW_SYM_REDEFINES=28 29 | KW_SYM_SUBSETS=29 30 | CONSTANT=30 31 | TYPE=31 32 | ID=32 33 | INTEGER=33 34 | REAL=34 35 | BOOL=35 36 | STRING=36 37 | MULTIPLICITY=37 38 | NULL=38 39 | WS=39 40 | NOTE=40 41 | COMMENT_LONG=41 42 | '{'=1 43 | '}'=2 44 | ';'=3 45 | ','=4 46 | ':'=5 47 | '='=6 48 | '*'=7 49 | 'about'=8 50 | 'actor'=9 51 | 'attribute'=10 52 | 'case'=11 53 | 'comment'=12 54 | 'def'=13 55 | 'doc'=14 56 | 'import'=15 57 | 'item'=16 58 | 'objective'=17 59 | 'package'=18 60 | 'part'=19 61 | 'port'=20 62 | 'redefines'=21 63 | 'ref'=22 64 | 'specializes'=23 65 | 'subject'=24 66 | 'subsets'=25 67 | 'use'=26 68 | '::'=27 69 | ':>>'=28 70 | ':>'=29 71 | 'null'=38 72 | -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Listener.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Listener.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$CommentContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$CommentContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Comment_namedContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Comment_namedContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Comment_named_aboutContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Comment_named_aboutContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Comment_unnamedContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Comment_unnamedContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$DocContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$DocContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Doc_namedContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Doc_namedContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Doc_unnamedContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Doc_unnamedContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$ElementContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$ElementContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$FeatureContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$FeatureContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_actor_specializesContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_actor_specializesContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_attribute_defContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_attribute_defContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_attribute_redefinesContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_attribute_redefinesContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_item_defContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_item_defContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_item_refContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_item_refContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_part_specializesContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_part_specializesContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Feature_part_specializes_subsetsContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Feature_part_specializes_subsetsContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Import_packageContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Import_packageContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$ModelContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$ModelContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$NamespaceContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$NamespaceContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Objective_defContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Objective_defContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$PartContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$PartContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Part_blkContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Part_blkContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Part_defContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Part_defContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Part_def_specializesContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Part_def_specializesContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Part_objective_blkContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Part_objective_blkContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Part_specializesContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Part_specializesContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$StatementContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$StatementContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Sysml2_packageContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Sysml2_packageContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Use_case_blkContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Use_case_blkContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser$Use_case_defContext.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser$Use_case_defContext.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Parser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Parser.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Visitor.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distj/SysML2Visitor.class -------------------------------------------------------------------------------- /pysysml2/grammar/distj/SysML2Visitor.java: -------------------------------------------------------------------------------- 1 | // Generated from SysML2.g4 by ANTLR 4.13.2 2 | import org.antlr.v4.runtime.tree.ParseTreeVisitor; 3 | 4 | /** 5 | * This interface defines a complete generic visitor for a parse tree produced 6 | * by {@link SysML2Parser}. 7 | * 8 | * @param The return type of the visit operation. Use {@link Void} for 9 | * operations with no return type. 10 | */ 11 | public interface SysML2Visitor extends ParseTreeVisitor { 12 | /** 13 | * Visit a parse tree produced by {@link SysML2Parser#model}. 14 | * @param ctx the parse tree 15 | * @return the visitor result 16 | */ 17 | T visitModel(SysML2Parser.ModelContext ctx); 18 | /** 19 | * Visit a parse tree produced by {@link SysML2Parser#element}. 20 | * @param ctx the parse tree 21 | * @return the visitor result 22 | */ 23 | T visitElement(SysML2Parser.ElementContext ctx); 24 | /** 25 | * Visit a parse tree produced by {@link SysML2Parser#namespace}. 26 | * @param ctx the parse tree 27 | * @return the visitor result 28 | */ 29 | T visitNamespace(SysML2Parser.NamespaceContext ctx); 30 | /** 31 | * Visit a parse tree produced by {@link SysML2Parser#sysml2_package}. 32 | * @param ctx the parse tree 33 | * @return the visitor result 34 | */ 35 | T visitSysml2_package(SysML2Parser.Sysml2_packageContext ctx); 36 | /** 37 | * Visit a parse tree produced by {@link SysML2Parser#part_blk}. 38 | * @param ctx the parse tree 39 | * @return the visitor result 40 | */ 41 | T visitPart_blk(SysML2Parser.Part_blkContext ctx); 42 | /** 43 | * Visit a parse tree produced by {@link SysML2Parser#part}. 44 | * @param ctx the parse tree 45 | * @return the visitor result 46 | */ 47 | T visitPart(SysML2Parser.PartContext ctx); 48 | /** 49 | * Visit a parse tree produced by {@link SysML2Parser#part_def}. 50 | * @param ctx the parse tree 51 | * @return the visitor result 52 | */ 53 | T visitPart_def(SysML2Parser.Part_defContext ctx); 54 | /** 55 | * Visit a parse tree produced by {@link SysML2Parser#part_def_specializes}. 56 | * @param ctx the parse tree 57 | * @return the visitor result 58 | */ 59 | T visitPart_def_specializes(SysML2Parser.Part_def_specializesContext ctx); 60 | /** 61 | * Visit a parse tree produced by {@link SysML2Parser#port}. 62 | * @param ctx the parse tree 63 | * @return the visitor result 64 | */ 65 | T visitPort(SysML2Parser.PortContext ctx); 66 | /** 67 | * Visit a parse tree produced by {@link SysML2Parser#port_def}. 68 | * @param ctx the parse tree 69 | * @return the visitor result 70 | */ 71 | T visitPort_def(SysML2Parser.Port_defContext ctx); 72 | /** 73 | * Visit a parse tree produced by {@link SysML2Parser#port_blk}. 74 | * @param ctx the parse tree 75 | * @return the visitor result 76 | */ 77 | T visitPort_blk(SysML2Parser.Port_blkContext ctx); 78 | /** 79 | * Visit a parse tree produced by {@link SysML2Parser#use_case_blk}. 80 | * @param ctx the parse tree 81 | * @return the visitor result 82 | */ 83 | T visitUse_case_blk(SysML2Parser.Use_case_blkContext ctx); 84 | /** 85 | * Visit a parse tree produced by {@link SysML2Parser#use_case_def}. 86 | * @param ctx the parse tree 87 | * @return the visitor result 88 | */ 89 | T visitUse_case_def(SysML2Parser.Use_case_defContext ctx); 90 | /** 91 | * Visit a parse tree produced by {@link SysML2Parser#part_objective_blk}. 92 | * @param ctx the parse tree 93 | * @return the visitor result 94 | */ 95 | T visitPart_objective_blk(SysML2Parser.Part_objective_blkContext ctx); 96 | /** 97 | * Visit a parse tree produced by {@link SysML2Parser#objective_def}. 98 | * @param ctx the parse tree 99 | * @return the visitor result 100 | */ 101 | T visitObjective_def(SysML2Parser.Objective_defContext ctx); 102 | /** 103 | * Visit a parse tree produced by {@link SysML2Parser#feature}. 104 | * @param ctx the parse tree 105 | * @return the visitor result 106 | */ 107 | T visitFeature(SysML2Parser.FeatureContext ctx); 108 | /** 109 | * Visit a parse tree produced by {@link SysML2Parser#feature_attribute_def}. 110 | * @param ctx the parse tree 111 | * @return the visitor result 112 | */ 113 | T visitFeature_attribute_def(SysML2Parser.Feature_attribute_defContext ctx); 114 | /** 115 | * Visit a parse tree produced by {@link SysML2Parser#feature_attribute_redefines}. 116 | * @param ctx the parse tree 117 | * @return the visitor result 118 | */ 119 | T visitFeature_attribute_redefines(SysML2Parser.Feature_attribute_redefinesContext ctx); 120 | /** 121 | * Visit a parse tree produced by {@link SysML2Parser#feature_part_specializes}. 122 | * @param ctx the parse tree 123 | * @return the visitor result 124 | */ 125 | T visitFeature_part_specializes(SysML2Parser.Feature_part_specializesContext ctx); 126 | /** 127 | * Visit a parse tree produced by {@link SysML2Parser#feature_part_specializes_subsets}. 128 | * @param ctx the parse tree 129 | * @return the visitor result 130 | */ 131 | T visitFeature_part_specializes_subsets(SysML2Parser.Feature_part_specializes_subsetsContext ctx); 132 | /** 133 | * Visit a parse tree produced by {@link SysML2Parser#feature_item_def}. 134 | * @param ctx the parse tree 135 | * @return the visitor result 136 | */ 137 | T visitFeature_item_def(SysML2Parser.Feature_item_defContext ctx); 138 | /** 139 | * Visit a parse tree produced by {@link SysML2Parser#feature_item_ref}. 140 | * @param ctx the parse tree 141 | * @return the visitor result 142 | */ 143 | T visitFeature_item_ref(SysML2Parser.Feature_item_refContext ctx); 144 | /** 145 | * Visit a parse tree produced by {@link SysML2Parser#feature_actor_specializes}. 146 | * @param ctx the parse tree 147 | * @return the visitor result 148 | */ 149 | T visitFeature_actor_specializes(SysML2Parser.Feature_actor_specializesContext ctx); 150 | /** 151 | * Visit a parse tree produced by {@link SysML2Parser#comment}. 152 | * @param ctx the parse tree 153 | * @return the visitor result 154 | */ 155 | T visitComment(SysML2Parser.CommentContext ctx); 156 | /** 157 | * Visit a parse tree produced by {@link SysML2Parser#comment_unnamed}. 158 | * @param ctx the parse tree 159 | * @return the visitor result 160 | */ 161 | T visitComment_unnamed(SysML2Parser.Comment_unnamedContext ctx); 162 | /** 163 | * Visit a parse tree produced by {@link SysML2Parser#comment_named}. 164 | * @param ctx the parse tree 165 | * @return the visitor result 166 | */ 167 | T visitComment_named(SysML2Parser.Comment_namedContext ctx); 168 | /** 169 | * Visit a parse tree produced by {@link SysML2Parser#comment_named_about}. 170 | * @param ctx the parse tree 171 | * @return the visitor result 172 | */ 173 | T visitComment_named_about(SysML2Parser.Comment_named_aboutContext ctx); 174 | /** 175 | * Visit a parse tree produced by {@link SysML2Parser#doc}. 176 | * @param ctx the parse tree 177 | * @return the visitor result 178 | */ 179 | T visitDoc(SysML2Parser.DocContext ctx); 180 | /** 181 | * Visit a parse tree produced by {@link SysML2Parser#doc_unnamed}. 182 | * @param ctx the parse tree 183 | * @return the visitor result 184 | */ 185 | T visitDoc_unnamed(SysML2Parser.Doc_unnamedContext ctx); 186 | /** 187 | * Visit a parse tree produced by {@link SysML2Parser#doc_named}. 188 | * @param ctx the parse tree 189 | * @return the visitor result 190 | */ 191 | T visitDoc_named(SysML2Parser.Doc_namedContext ctx); 192 | /** 193 | * Visit a parse tree produced by {@link SysML2Parser#statement}. 194 | * @param ctx the parse tree 195 | * @return the visitor result 196 | */ 197 | T visitStatement(SysML2Parser.StatementContext ctx); 198 | /** 199 | * Visit a parse tree produced by {@link SysML2Parser#import_package}. 200 | * @param ctx the parse tree 201 | * @return the visitor result 202 | */ 203 | T visitImport_package(SysML2Parser.Import_packageContext ctx); 204 | } -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/SysML2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | KW_ABOUT=9 10 | KW_ACTOR=10 11 | KW_ATTRIBUTE=11 12 | KW_CASE=12 13 | KW_COMMENT=13 14 | KW_CONNECTION=14 15 | KW_CONNECT=15 16 | KW_DEF=16 17 | KW_DOC=17 18 | KW_FROM=18 19 | KW_END=19 20 | KW_IMPORT=20 21 | KW_INCLUDE=21 22 | KW_ITEM=22 23 | KW_MESSAGE=23 24 | KW_OBJECTIVE=24 25 | KW_PACKAGE=25 26 | KW_PART=26 27 | KW_PORT=27 28 | KW_REF=28 29 | KW_REDEFINES=29 30 | KW_SPECIALIZES=30 31 | KW_SUBJECT=31 32 | KW_SUBSETS=32 33 | KW_SYM_FQN=33 34 | KW_SYM_REDEFINES=34 35 | KW_SYM_SUBSETS=35 36 | KW_TO=36 37 | KW_USE=37 38 | KW_IN=38 39 | KW_OUT=39 40 | KW_OF=40 41 | CONSTANT=41 42 | TYPE=42 43 | ID=43 44 | INTEGER=44 45 | REAL=45 46 | BOOL=46 47 | STRING=47 48 | MULTIPLICITY=48 49 | NULL=49 50 | WS=50 51 | NOTE=51 52 | COMMENT_LONG=52 53 | '{'=1 54 | '}'=2 55 | ';'=3 56 | ','=4 57 | '='=5 58 | '.'=6 59 | ':'=7 60 | '*'=8 61 | 'about'=9 62 | 'actor'=10 63 | 'attribute'=11 64 | 'case'=12 65 | 'comment'=13 66 | 'connection'=14 67 | 'connect'=15 68 | 'def'=16 69 | 'doc'=17 70 | 'from'=18 71 | 'end'=19 72 | 'import'=20 73 | 'include'=21 74 | 'item'=22 75 | 'message'=23 76 | 'objective'=24 77 | 'package'=25 78 | 'part'=26 79 | 'port'=27 80 | 'ref'=28 81 | 'redefines'=29 82 | 'specializes'=30 83 | 'subject'=31 84 | 'subsets'=32 85 | '::'=33 86 | ':>>'=34 87 | ':>'=35 88 | 'to'=36 89 | 'use'=37 90 | 'in'=38 91 | 'out'=39 92 | 'of'=40 93 | 'null'=49 94 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/SysML2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | T__7=8 9 | KW_ABOUT=9 10 | KW_ACTOR=10 11 | KW_ATTRIBUTE=11 12 | KW_CASE=12 13 | KW_COMMENT=13 14 | KW_CONNECTION=14 15 | KW_CONNECT=15 16 | KW_DEF=16 17 | KW_DOC=17 18 | KW_FROM=18 19 | KW_END=19 20 | KW_IMPORT=20 21 | KW_INCLUDE=21 22 | KW_ITEM=22 23 | KW_MESSAGE=23 24 | KW_OBJECTIVE=24 25 | KW_PACKAGE=25 26 | KW_PART=26 27 | KW_PORT=27 28 | KW_REF=28 29 | KW_REDEFINES=29 30 | KW_SPECIALIZES=30 31 | KW_SUBJECT=31 32 | KW_SUBSETS=32 33 | KW_SYM_FQN=33 34 | KW_SYM_REDEFINES=34 35 | KW_SYM_SUBSETS=35 36 | KW_TO=36 37 | KW_USE=37 38 | KW_IN=38 39 | KW_OUT=39 40 | KW_OF=40 41 | CONSTANT=41 42 | TYPE=42 43 | ID=43 44 | INTEGER=44 45 | REAL=45 46 | BOOL=46 47 | STRING=47 48 | MULTIPLICITY=48 49 | NULL=49 50 | WS=50 51 | NOTE=51 52 | COMMENT_LONG=52 53 | '{'=1 54 | '}'=2 55 | ';'=3 56 | ','=4 57 | '='=5 58 | '.'=6 59 | ':'=7 60 | '*'=8 61 | 'about'=9 62 | 'actor'=10 63 | 'attribute'=11 64 | 'case'=12 65 | 'comment'=13 66 | 'connection'=14 67 | 'connect'=15 68 | 'def'=16 69 | 'doc'=17 70 | 'from'=18 71 | 'end'=19 72 | 'import'=20 73 | 'include'=21 74 | 'item'=22 75 | 'message'=23 76 | 'objective'=24 77 | 'package'=25 78 | 'part'=26 79 | 'port'=27 80 | 'ref'=28 81 | 'redefines'=29 82 | 'specializes'=30 83 | 'subject'=31 84 | 'subsets'=32 85 | '::'=33 86 | ':>>'=34 87 | ':>'=35 88 | 'to'=36 89 | 'use'=37 90 | 'in'=38 91 | 'out'=39 92 | 'of'=40 93 | 'null'=49 94 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/SysML2Visitor.py: -------------------------------------------------------------------------------- 1 | # Generated from SysML2.g4 by ANTLR 4.13.2 2 | from antlr4 import * 3 | if "." in __name__: 4 | from .SysML2Parser import SysML2Parser 5 | else: 6 | from SysML2Parser import SysML2Parser 7 | 8 | # This class defines a complete generic visitor for a parse tree produced by SysML2Parser. 9 | 10 | class SysML2Visitor(ParseTreeVisitor): 11 | 12 | # Visit a parse tree produced by SysML2Parser#model. 13 | def visitModel(self, ctx:SysML2Parser.ModelContext): 14 | return self.visitChildren(ctx) 15 | 16 | 17 | # Visit a parse tree produced by SysML2Parser#element. 18 | def visitElement(self, ctx:SysML2Parser.ElementContext): 19 | return self.visitChildren(ctx) 20 | 21 | 22 | # Visit a parse tree produced by SysML2Parser#namespace. 23 | def visitNamespace(self, ctx:SysML2Parser.NamespaceContext): 24 | return self.visitChildren(ctx) 25 | 26 | 27 | # Visit a parse tree produced by SysML2Parser#sysml2_package. 28 | def visitSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 29 | return self.visitChildren(ctx) 30 | 31 | 32 | # Visit a parse tree produced by SysML2Parser#part_blk. 33 | def visitPart_blk(self, ctx:SysML2Parser.Part_blkContext): 34 | return self.visitChildren(ctx) 35 | 36 | 37 | # Visit a parse tree produced by SysML2Parser#part. 38 | def visitPart(self, ctx:SysML2Parser.PartContext): 39 | return self.visitChildren(ctx) 40 | 41 | 42 | # Visit a parse tree produced by SysML2Parser#part_def. 43 | def visitPart_def(self, ctx:SysML2Parser.Part_defContext): 44 | return self.visitChildren(ctx) 45 | 46 | 47 | # Visit a parse tree produced by SysML2Parser#part_def_specializes. 48 | def visitPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 49 | return self.visitChildren(ctx) 50 | 51 | 52 | # Visit a parse tree produced by SysML2Parser#port. 53 | def visitPort(self, ctx:SysML2Parser.PortContext): 54 | return self.visitChildren(ctx) 55 | 56 | 57 | # Visit a parse tree produced by SysML2Parser#port_def. 58 | def visitPort_def(self, ctx:SysML2Parser.Port_defContext): 59 | return self.visitChildren(ctx) 60 | 61 | 62 | # Visit a parse tree produced by SysML2Parser#port_blk. 63 | def visitPort_blk(self, ctx:SysML2Parser.Port_blkContext): 64 | return self.visitChildren(ctx) 65 | 66 | 67 | # Visit a parse tree produced by SysML2Parser#use_case_blk. 68 | def visitUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 69 | return self.visitChildren(ctx) 70 | 71 | 72 | # Visit a parse tree produced by SysML2Parser#use_case_def. 73 | def visitUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 74 | return self.visitChildren(ctx) 75 | 76 | 77 | # Visit a parse tree produced by SysML2Parser#part_objective_blk. 78 | def visitPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 79 | return self.visitChildren(ctx) 80 | 81 | 82 | # Visit a parse tree produced by SysML2Parser#objective_def. 83 | def visitObjective_def(self, ctx:SysML2Parser.Objective_defContext): 84 | return self.visitChildren(ctx) 85 | 86 | 87 | # Visit a parse tree produced by SysML2Parser#subject_def. 88 | def visitSubject_def(self, ctx:SysML2Parser.Subject_defContext): 89 | return self.visitChildren(ctx) 90 | 91 | 92 | # Visit a parse tree produced by SysML2Parser#include. 93 | def visitInclude(self, ctx:SysML2Parser.IncludeContext): 94 | return self.visitChildren(ctx) 95 | 96 | 97 | # Visit a parse tree produced by SysML2Parser#include_blk. 98 | def visitInclude_blk(self, ctx:SysML2Parser.Include_blkContext): 99 | return self.visitChildren(ctx) 100 | 101 | 102 | # Visit a parse tree produced by SysML2Parser#message. 103 | def visitMessage(self, ctx:SysML2Parser.MessageContext): 104 | return self.visitChildren(ctx) 105 | 106 | 107 | # Visit a parse tree produced by SysML2Parser#message_expr. 108 | def visitMessage_expr(self, ctx:SysML2Parser.Message_exprContext): 109 | return self.visitChildren(ctx) 110 | 111 | 112 | # Visit a parse tree produced by SysML2Parser#feature. 113 | def visitFeature(self, ctx:SysML2Parser.FeatureContext): 114 | return self.visitChildren(ctx) 115 | 116 | 117 | # Visit a parse tree produced by SysML2Parser#connection. 118 | def visitConnection(self, ctx:SysML2Parser.ConnectionContext): 119 | return self.visitChildren(ctx) 120 | 121 | 122 | # Visit a parse tree produced by SysML2Parser#connection_blk. 123 | def visitConnection_blk(self, ctx:SysML2Parser.Connection_blkContext): 124 | return self.visitChildren(ctx) 125 | 126 | 127 | # Visit a parse tree produced by SysML2Parser#end_part. 128 | def visitEnd_part(self, ctx:SysML2Parser.End_partContext): 129 | return self.visitChildren(ctx) 130 | 131 | 132 | # Visit a parse tree produced by SysML2Parser#connect. 133 | def visitConnect(self, ctx:SysML2Parser.ConnectContext): 134 | return self.visitChildren(ctx) 135 | 136 | 137 | # Visit a parse tree produced by SysML2Parser#connect_expr. 138 | def visitConnect_expr(self, ctx:SysML2Parser.Connect_exprContext): 139 | return self.visitChildren(ctx) 140 | 141 | 142 | # Visit a parse tree produced by SysML2Parser#feature_attribute_def. 143 | def visitFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 144 | return self.visitChildren(ctx) 145 | 146 | 147 | # Visit a parse tree produced by SysML2Parser#feature_attribute_redefines. 148 | def visitFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 149 | return self.visitChildren(ctx) 150 | 151 | 152 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes. 153 | def visitFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 154 | return self.visitChildren(ctx) 155 | 156 | 157 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 158 | def visitFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 159 | return self.visitChildren(ctx) 160 | 161 | 162 | # Visit a parse tree produced by SysML2Parser#feature_item_def. 163 | def visitFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 164 | return self.visitChildren(ctx) 165 | 166 | 167 | # Visit a parse tree produced by SysML2Parser#feature_item_ref. 168 | def visitFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 169 | return self.visitChildren(ctx) 170 | 171 | 172 | # Visit a parse tree produced by SysML2Parser#feature_actor_specializes. 173 | def visitFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 174 | return self.visitChildren(ctx) 175 | 176 | 177 | # Visit a parse tree produced by SysML2Parser#comment. 178 | def visitComment(self, ctx:SysML2Parser.CommentContext): 179 | return self.visitChildren(ctx) 180 | 181 | 182 | # Visit a parse tree produced by SysML2Parser#comment_unnamed. 183 | def visitComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 184 | return self.visitChildren(ctx) 185 | 186 | 187 | # Visit a parse tree produced by SysML2Parser#comment_named. 188 | def visitComment_named(self, ctx:SysML2Parser.Comment_namedContext): 189 | return self.visitChildren(ctx) 190 | 191 | 192 | # Visit a parse tree produced by SysML2Parser#comment_named_about. 193 | def visitComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 194 | return self.visitChildren(ctx) 195 | 196 | 197 | # Visit a parse tree produced by SysML2Parser#doc. 198 | def visitDoc(self, ctx:SysML2Parser.DocContext): 199 | return self.visitChildren(ctx) 200 | 201 | 202 | # Visit a parse tree produced by SysML2Parser#doc_unnamed. 203 | def visitDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 204 | return self.visitChildren(ctx) 205 | 206 | 207 | # Visit a parse tree produced by SysML2Parser#doc_named. 208 | def visitDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 209 | return self.visitChildren(ctx) 210 | 211 | 212 | # Visit a parse tree produced by SysML2Parser#statement. 213 | def visitStatement(self, ctx:SysML2Parser.StatementContext): 214 | return self.visitChildren(ctx) 215 | 216 | 217 | # Visit a parse tree produced by SysML2Parser#import_package. 218 | def visitImport_package(self, ctx:SysML2Parser.Import_packageContext): 219 | return self.visitChildren(ctx) 220 | 221 | 222 | 223 | del SysML2Parser -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/pysysml2/grammar/distpy/__init__.py -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old/SysML2.interp: -------------------------------------------------------------------------------- 1 | token literal names: 2 | null 3 | '{' 4 | '}' 5 | ';' 6 | ',' 7 | ':' 8 | '=' 9 | '*' 10 | 'about' 11 | 'actor' 12 | 'attribute' 13 | 'case' 14 | 'comment' 15 | 'def' 16 | 'doc' 17 | 'import' 18 | 'item' 19 | 'objective' 20 | 'package' 21 | 'part' 22 | 'redefines' 23 | 'ref' 24 | 'specializes' 25 | 'subject' 26 | 'subsets' 27 | 'use' 28 | '::' 29 | ':>>' 30 | ':>' 31 | null 32 | null 33 | null 34 | null 35 | null 36 | null 37 | null 38 | null 39 | 'null' 40 | null 41 | null 42 | null 43 | 44 | token symbolic names: 45 | null 46 | null 47 | null 48 | null 49 | null 50 | null 51 | null 52 | null 53 | KW_ABOUT 54 | KW_ACTOR 55 | KW_ATTRIBUTE 56 | KW_CASE 57 | KW_COMMENT 58 | KW_DEF 59 | KW_DOC 60 | KW_IMPORT 61 | KW_ITEM 62 | KW_OBJECTIVE 63 | KW_PACKAGE 64 | KW_PART 65 | KW_REDEFINES 66 | KW_REF 67 | KW_SPECIALIZES 68 | KW_SUBJECT 69 | KW_SUBSETS 70 | KW_USE 71 | KW_SYM_FQN 72 | KW_SYM_REDEFINES 73 | KW_SYM_SUBSETS 74 | CONSTANT 75 | TYPE 76 | ID 77 | INTEGER 78 | REAL 79 | BOOL 80 | STRING 81 | MULTIPLICITY 82 | NULL 83 | WS 84 | NOTE 85 | COMMENT_LONG 86 | 87 | rule names: 88 | model 89 | element 90 | namespace 91 | sysml2_package 92 | part_blk 93 | part 94 | part_def 95 | part_def_specializes 96 | use_case_blk 97 | use_case_def 98 | part_objective_blk 99 | objective_def 100 | feature 101 | feature_attribute_def 102 | feature_attribute_redefines 103 | feature_part_specializes 104 | feature_part_specializes_subsets 105 | feature_item_def 106 | feature_item_ref 107 | feature_actor_specializes 108 | comment 109 | comment_unnamed 110 | comment_named 111 | comment_named_about 112 | doc 113 | doc_unnamed 114 | doc_named 115 | statement 116 | import_package 117 | 118 | 119 | atn: 120 | [4, 1, 40, 289, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 1, 0, 5, 0, 60, 8, 0, 10, 0, 12, 0, 63, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 72, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 79, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 85, 8, 3, 10, 3, 12, 3, 88, 9, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 96, 8, 4, 1, 5, 1, 5, 3, 5, 100, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 107, 8, 6, 10, 6, 12, 6, 110, 9, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 3, 6, 117, 8, 6, 1, 7, 1, 7, 3, 7, 121, 8, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 5, 7, 128, 8, 7, 10, 7, 12, 7, 131, 9, 7, 1, 7, 1, 7, 5, 7, 135, 8, 7, 10, 7, 12, 7, 138, 9, 7, 1, 7, 1, 7, 3, 7, 142, 8, 7, 1, 8, 1, 8, 3, 8, 146, 8, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 154, 8, 9, 10, 9, 12, 9, 157, 9, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 3, 12, 175, 8, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 3, 14, 188, 8, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 199, 8, 15, 1, 15, 1, 15, 1, 15, 5, 15, 204, 8, 15, 10, 15, 12, 15, 207, 9, 15, 1, 15, 3, 15, 210, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 217, 8, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 3, 18, 228, 8, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 3, 19, 241, 8, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 3, 20, 248, 8, 20, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 3, 24, 263, 8, 24, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 5, 28, 278, 8, 28, 10, 28, 12, 28, 281, 9, 28, 1, 28, 1, 28, 3, 28, 285, 8, 28, 1, 28, 1, 28, 1, 28, 1, 129, 0, 29, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 0, 3, 2, 0, 22, 22, 28, 28, 2, 0, 20, 20, 27, 28, 2, 0, 24, 24, 28, 28, 299, 0, 61, 1, 0, 0, 0, 2, 71, 1, 0, 0, 0, 4, 78, 1, 0, 0, 0, 6, 80, 1, 0, 0, 0, 8, 95, 1, 0, 0, 0, 10, 99, 1, 0, 0, 0, 12, 116, 1, 0, 0, 0, 14, 118, 1, 0, 0, 0, 16, 145, 1, 0, 0, 0, 18, 147, 1, 0, 0, 0, 20, 160, 1, 0, 0, 0, 22, 162, 1, 0, 0, 0, 24, 174, 1, 0, 0, 0, 26, 176, 1, 0, 0, 0, 28, 182, 1, 0, 0, 0, 30, 193, 1, 0, 0, 0, 32, 211, 1, 0, 0, 0, 34, 222, 1, 0, 0, 0, 36, 227, 1, 0, 0, 0, 38, 235, 1, 0, 0, 0, 40, 247, 1, 0, 0, 0, 42, 249, 1, 0, 0, 0, 44, 251, 1, 0, 0, 0, 46, 255, 1, 0, 0, 0, 48, 262, 1, 0, 0, 0, 50, 264, 1, 0, 0, 0, 52, 267, 1, 0, 0, 0, 54, 271, 1, 0, 0, 0, 56, 273, 1, 0, 0, 0, 58, 60, 3, 2, 1, 0, 59, 58, 1, 0, 0, 0, 60, 63, 1, 0, 0, 0, 61, 59, 1, 0, 0, 0, 61, 62, 1, 0, 0, 0, 62, 64, 1, 0, 0, 0, 63, 61, 1, 0, 0, 0, 64, 65, 5, 0, 0, 1, 65, 1, 1, 0, 0, 0, 66, 72, 3, 4, 2, 0, 67, 72, 3, 24, 12, 0, 68, 72, 3, 40, 20, 0, 69, 72, 3, 48, 24, 0, 70, 72, 3, 54, 27, 0, 71, 66, 1, 0, 0, 0, 71, 67, 1, 0, 0, 0, 71, 68, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 71, 70, 1, 0, 0, 0, 72, 3, 1, 0, 0, 0, 73, 79, 3, 6, 3, 0, 74, 79, 3, 10, 5, 0, 75, 79, 3, 18, 9, 0, 76, 79, 3, 40, 20, 0, 77, 79, 3, 48, 24, 0, 78, 73, 1, 0, 0, 0, 78, 74, 1, 0, 0, 0, 78, 75, 1, 0, 0, 0, 78, 76, 1, 0, 0, 0, 78, 77, 1, 0, 0, 0, 79, 5, 1, 0, 0, 0, 80, 81, 5, 18, 0, 0, 81, 82, 5, 31, 0, 0, 82, 86, 5, 1, 0, 0, 83, 85, 3, 4, 2, 0, 84, 83, 1, 0, 0, 0, 85, 88, 1, 0, 0, 0, 86, 84, 1, 0, 0, 0, 86, 87, 1, 0, 0, 0, 87, 89, 1, 0, 0, 0, 88, 86, 1, 0, 0, 0, 89, 90, 5, 2, 0, 0, 90, 7, 1, 0, 0, 0, 91, 96, 3, 24, 12, 0, 92, 96, 3, 40, 20, 0, 93, 96, 3, 48, 24, 0, 94, 96, 3, 14, 7, 0, 95, 91, 1, 0, 0, 0, 95, 92, 1, 0, 0, 0, 95, 93, 1, 0, 0, 0, 95, 94, 1, 0, 0, 0, 96, 9, 1, 0, 0, 0, 97, 100, 3, 12, 6, 0, 98, 100, 3, 14, 7, 0, 99, 97, 1, 0, 0, 0, 99, 98, 1, 0, 0, 0, 100, 11, 1, 0, 0, 0, 101, 102, 5, 19, 0, 0, 102, 103, 5, 13, 0, 0, 103, 104, 5, 31, 0, 0, 104, 108, 5, 1, 0, 0, 105, 107, 3, 8, 4, 0, 106, 105, 1, 0, 0, 0, 107, 110, 1, 0, 0, 0, 108, 106, 1, 0, 0, 0, 108, 109, 1, 0, 0, 0, 109, 111, 1, 0, 0, 0, 110, 108, 1, 0, 0, 0, 111, 117, 5, 2, 0, 0, 112, 113, 5, 19, 0, 0, 113, 114, 5, 13, 0, 0, 114, 115, 5, 31, 0, 0, 115, 117, 5, 3, 0, 0, 116, 101, 1, 0, 0, 0, 116, 112, 1, 0, 0, 0, 117, 13, 1, 0, 0, 0, 118, 120, 5, 19, 0, 0, 119, 121, 5, 13, 0, 0, 120, 119, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 122, 1, 0, 0, 0, 122, 123, 5, 31, 0, 0, 123, 124, 7, 0, 0, 0, 124, 129, 5, 31, 0, 0, 125, 126, 5, 4, 0, 0, 126, 128, 5, 31, 0, 0, 127, 125, 1, 0, 0, 0, 128, 131, 1, 0, 0, 0, 129, 130, 1, 0, 0, 0, 129, 127, 1, 0, 0, 0, 130, 141, 1, 0, 0, 0, 131, 129, 1, 0, 0, 0, 132, 136, 5, 1, 0, 0, 133, 135, 3, 8, 4, 0, 134, 133, 1, 0, 0, 0, 135, 138, 1, 0, 0, 0, 136, 134, 1, 0, 0, 0, 136, 137, 1, 0, 0, 0, 137, 139, 1, 0, 0, 0, 138, 136, 1, 0, 0, 0, 139, 142, 5, 2, 0, 0, 140, 142, 5, 3, 0, 0, 141, 132, 1, 0, 0, 0, 141, 140, 1, 0, 0, 0, 142, 15, 1, 0, 0, 0, 143, 146, 3, 8, 4, 0, 144, 146, 3, 22, 11, 0, 145, 143, 1, 0, 0, 0, 145, 144, 1, 0, 0, 0, 146, 17, 1, 0, 0, 0, 147, 148, 5, 25, 0, 0, 148, 149, 5, 11, 0, 0, 149, 150, 5, 13, 0, 0, 150, 151, 5, 31, 0, 0, 151, 155, 5, 1, 0, 0, 152, 154, 3, 16, 8, 0, 153, 152, 1, 0, 0, 0, 154, 157, 1, 0, 0, 0, 155, 153, 1, 0, 0, 0, 155, 156, 1, 0, 0, 0, 156, 158, 1, 0, 0, 0, 157, 155, 1, 0, 0, 0, 158, 159, 5, 2, 0, 0, 159, 19, 1, 0, 0, 0, 160, 161, 3, 48, 24, 0, 161, 21, 1, 0, 0, 0, 162, 163, 5, 17, 0, 0, 163, 164, 5, 1, 0, 0, 164, 165, 3, 20, 10, 0, 165, 166, 5, 2, 0, 0, 166, 23, 1, 0, 0, 0, 167, 175, 3, 26, 13, 0, 168, 175, 3, 28, 14, 0, 169, 175, 3, 30, 15, 0, 170, 175, 3, 32, 16, 0, 171, 175, 3, 34, 17, 0, 172, 175, 3, 36, 18, 0, 173, 175, 3, 38, 19, 0, 174, 167, 1, 0, 0, 0, 174, 168, 1, 0, 0, 0, 174, 169, 1, 0, 0, 0, 174, 170, 1, 0, 0, 0, 174, 171, 1, 0, 0, 0, 174, 172, 1, 0, 0, 0, 174, 173, 1, 0, 0, 0, 175, 25, 1, 0, 0, 0, 176, 177, 5, 10, 0, 0, 177, 178, 5, 31, 0, 0, 178, 179, 5, 5, 0, 0, 179, 180, 5, 30, 0, 0, 180, 181, 5, 3, 0, 0, 181, 27, 1, 0, 0, 0, 182, 183, 5, 10, 0, 0, 183, 184, 7, 1, 0, 0, 184, 187, 5, 31, 0, 0, 185, 186, 5, 5, 0, 0, 186, 188, 5, 30, 0, 0, 187, 185, 1, 0, 0, 0, 187, 188, 1, 0, 0, 0, 188, 189, 1, 0, 0, 0, 189, 190, 5, 6, 0, 0, 190, 191, 5, 29, 0, 0, 191, 192, 5, 3, 0, 0, 192, 29, 1, 0, 0, 0, 193, 194, 5, 19, 0, 0, 194, 195, 5, 31, 0, 0, 195, 196, 5, 5, 0, 0, 196, 198, 5, 31, 0, 0, 197, 199, 5, 36, 0, 0, 198, 197, 1, 0, 0, 0, 198, 199, 1, 0, 0, 0, 199, 209, 1, 0, 0, 0, 200, 210, 5, 3, 0, 0, 201, 205, 5, 1, 0, 0, 202, 204, 3, 8, 4, 0, 203, 202, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 208, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 210, 5, 2, 0, 0, 209, 200, 1, 0, 0, 0, 209, 201, 1, 0, 0, 0, 210, 31, 1, 0, 0, 0, 211, 212, 5, 19, 0, 0, 212, 213, 5, 31, 0, 0, 213, 214, 5, 5, 0, 0, 214, 216, 5, 31, 0, 0, 215, 217, 5, 36, 0, 0, 216, 215, 1, 0, 0, 0, 216, 217, 1, 0, 0, 0, 217, 218, 1, 0, 0, 0, 218, 219, 7, 2, 0, 0, 219, 220, 5, 31, 0, 0, 220, 221, 5, 3, 0, 0, 221, 33, 1, 0, 0, 0, 222, 223, 5, 16, 0, 0, 223, 224, 5, 31, 0, 0, 224, 225, 5, 3, 0, 0, 225, 35, 1, 0, 0, 0, 226, 228, 5, 21, 0, 0, 227, 226, 1, 0, 0, 0, 227, 228, 1, 0, 0, 0, 228, 229, 1, 0, 0, 0, 229, 230, 5, 16, 0, 0, 230, 231, 5, 31, 0, 0, 231, 232, 5, 5, 0, 0, 232, 233, 5, 31, 0, 0, 233, 234, 5, 3, 0, 0, 234, 37, 1, 0, 0, 0, 235, 236, 5, 9, 0, 0, 236, 237, 5, 31, 0, 0, 237, 238, 5, 5, 0, 0, 238, 240, 5, 31, 0, 0, 239, 241, 5, 36, 0, 0, 240, 239, 1, 0, 0, 0, 240, 241, 1, 0, 0, 0, 241, 242, 1, 0, 0, 0, 242, 243, 5, 3, 0, 0, 243, 39, 1, 0, 0, 0, 244, 248, 3, 42, 21, 0, 245, 248, 3, 44, 22, 0, 246, 248, 3, 46, 23, 0, 247, 244, 1, 0, 0, 0, 247, 245, 1, 0, 0, 0, 247, 246, 1, 0, 0, 0, 248, 41, 1, 0, 0, 0, 249, 250, 5, 40, 0, 0, 250, 43, 1, 0, 0, 0, 251, 252, 5, 12, 0, 0, 252, 253, 5, 31, 0, 0, 253, 254, 5, 40, 0, 0, 254, 45, 1, 0, 0, 0, 255, 256, 5, 12, 0, 0, 256, 257, 5, 8, 0, 0, 257, 258, 5, 31, 0, 0, 258, 259, 5, 40, 0, 0, 259, 47, 1, 0, 0, 0, 260, 263, 3, 50, 25, 0, 261, 263, 3, 52, 26, 0, 262, 260, 1, 0, 0, 0, 262, 261, 1, 0, 0, 0, 263, 49, 1, 0, 0, 0, 264, 265, 5, 14, 0, 0, 265, 266, 5, 40, 0, 0, 266, 51, 1, 0, 0, 0, 267, 268, 5, 14, 0, 0, 268, 269, 5, 31, 0, 0, 269, 270, 5, 40, 0, 0, 270, 53, 1, 0, 0, 0, 271, 272, 3, 56, 28, 0, 272, 55, 1, 0, 0, 0, 273, 274, 5, 15, 0, 0, 274, 279, 5, 31, 0, 0, 275, 276, 5, 26, 0, 0, 276, 278, 5, 31, 0, 0, 277, 275, 1, 0, 0, 0, 278, 281, 1, 0, 0, 0, 279, 277, 1, 0, 0, 0, 279, 280, 1, 0, 0, 0, 280, 284, 1, 0, 0, 0, 281, 279, 1, 0, 0, 0, 282, 283, 5, 26, 0, 0, 283, 285, 5, 7, 0, 0, 284, 282, 1, 0, 0, 0, 284, 285, 1, 0, 0, 0, 285, 286, 1, 0, 0, 0, 286, 287, 5, 3, 0, 0, 287, 57, 1, 0, 0, 0, 26, 61, 71, 78, 86, 95, 99, 108, 116, 120, 129, 136, 141, 145, 155, 174, 187, 198, 205, 209, 216, 227, 240, 247, 262, 279, 284] -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old/SysML2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_REDEFINES=20 21 | KW_REF=21 22 | KW_SPECIALIZES=22 23 | KW_SUBJECT=23 24 | KW_SUBSETS=24 25 | KW_USE=25 26 | KW_SYM_FQN=26 27 | KW_SYM_REDEFINES=27 28 | KW_SYM_SUBSETS=28 29 | CONSTANT=29 30 | TYPE=30 31 | ID=31 32 | INTEGER=32 33 | REAL=33 34 | BOOL=34 35 | STRING=35 36 | MULTIPLICITY=36 37 | NULL=37 38 | WS=38 39 | NOTE=39 40 | COMMENT_LONG=40 41 | '{'=1 42 | '}'=2 43 | ';'=3 44 | ','=4 45 | ':'=5 46 | '='=6 47 | '*'=7 48 | 'about'=8 49 | 'actor'=9 50 | 'attribute'=10 51 | 'case'=11 52 | 'comment'=12 53 | 'def'=13 54 | 'doc'=14 55 | 'import'=15 56 | 'item'=16 57 | 'objective'=17 58 | 'package'=18 59 | 'part'=19 60 | 'redefines'=20 61 | 'ref'=21 62 | 'specializes'=22 63 | 'subject'=23 64 | 'subsets'=24 65 | 'use'=25 66 | '::'=26 67 | ':>>'=27 68 | ':>'=28 69 | 'null'=37 70 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old/SysML2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_REDEFINES=20 21 | KW_REF=21 22 | KW_SPECIALIZES=22 23 | KW_SUBJECT=23 24 | KW_SUBSETS=24 25 | KW_USE=25 26 | KW_SYM_FQN=26 27 | KW_SYM_REDEFINES=27 28 | KW_SYM_SUBSETS=28 29 | CONSTANT=29 30 | TYPE=30 31 | ID=31 32 | INTEGER=32 33 | REAL=33 34 | BOOL=34 35 | STRING=35 36 | MULTIPLICITY=36 37 | NULL=37 38 | WS=38 39 | NOTE=39 40 | COMMENT_LONG=40 41 | '{'=1 42 | '}'=2 43 | ';'=3 44 | ','=4 45 | ':'=5 46 | '='=6 47 | '*'=7 48 | 'about'=8 49 | 'actor'=9 50 | 'attribute'=10 51 | 'case'=11 52 | 'comment'=12 53 | 'def'=13 54 | 'doc'=14 55 | 'import'=15 56 | 'item'=16 57 | 'objective'=17 58 | 'package'=18 59 | 'part'=19 60 | 'redefines'=20 61 | 'ref'=21 62 | 'specializes'=22 63 | 'subject'=23 64 | 'subsets'=24 65 | 'use'=25 66 | '::'=26 67 | ':>>'=27 68 | ':>'=28 69 | 'null'=37 70 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old/SysML2Listener.py: -------------------------------------------------------------------------------- 1 | # Generated from SysML2.g4 by ANTLR 4.10.1 2 | from antlr4 import * 3 | if __name__ is not None and "." in __name__: 4 | from .SysML2Parser import SysML2Parser 5 | else: 6 | from SysML2Parser import SysML2Parser 7 | 8 | # This class defines a complete listener for a parse tree produced by SysML2Parser. 9 | class SysML2Listener(ParseTreeListener): 10 | 11 | # Enter a parse tree produced by SysML2Parser#model. 12 | def enterModel(self, ctx:SysML2Parser.ModelContext): 13 | pass 14 | 15 | # Exit a parse tree produced by SysML2Parser#model. 16 | def exitModel(self, ctx:SysML2Parser.ModelContext): 17 | pass 18 | 19 | 20 | # Enter a parse tree produced by SysML2Parser#element. 21 | def enterElement(self, ctx:SysML2Parser.ElementContext): 22 | pass 23 | 24 | # Exit a parse tree produced by SysML2Parser#element. 25 | def exitElement(self, ctx:SysML2Parser.ElementContext): 26 | pass 27 | 28 | 29 | # Enter a parse tree produced by SysML2Parser#namespace. 30 | def enterNamespace(self, ctx:SysML2Parser.NamespaceContext): 31 | pass 32 | 33 | # Exit a parse tree produced by SysML2Parser#namespace. 34 | def exitNamespace(self, ctx:SysML2Parser.NamespaceContext): 35 | pass 36 | 37 | 38 | # Enter a parse tree produced by SysML2Parser#sysml2_package. 39 | def enterSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 40 | pass 41 | 42 | # Exit a parse tree produced by SysML2Parser#sysml2_package. 43 | def exitSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 44 | pass 45 | 46 | 47 | # Enter a parse tree produced by SysML2Parser#part_blk. 48 | def enterPart_blk(self, ctx:SysML2Parser.Part_blkContext): 49 | pass 50 | 51 | # Exit a parse tree produced by SysML2Parser#part_blk. 52 | def exitPart_blk(self, ctx:SysML2Parser.Part_blkContext): 53 | pass 54 | 55 | 56 | # Enter a parse tree produced by SysML2Parser#part. 57 | def enterPart(self, ctx:SysML2Parser.PartContext): 58 | pass 59 | 60 | # Exit a parse tree produced by SysML2Parser#part. 61 | def exitPart(self, ctx:SysML2Parser.PartContext): 62 | pass 63 | 64 | 65 | # Enter a parse tree produced by SysML2Parser#part_def. 66 | def enterPart_def(self, ctx:SysML2Parser.Part_defContext): 67 | pass 68 | 69 | # Exit a parse tree produced by SysML2Parser#part_def. 70 | def exitPart_def(self, ctx:SysML2Parser.Part_defContext): 71 | pass 72 | 73 | 74 | # Enter a parse tree produced by SysML2Parser#part_def_specializes. 75 | def enterPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 76 | pass 77 | 78 | # Exit a parse tree produced by SysML2Parser#part_def_specializes. 79 | def exitPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 80 | pass 81 | 82 | 83 | # Enter a parse tree produced by SysML2Parser#use_case_blk. 84 | def enterUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 85 | pass 86 | 87 | # Exit a parse tree produced by SysML2Parser#use_case_blk. 88 | def exitUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 89 | pass 90 | 91 | 92 | # Enter a parse tree produced by SysML2Parser#use_case_def. 93 | def enterUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 94 | pass 95 | 96 | # Exit a parse tree produced by SysML2Parser#use_case_def. 97 | def exitUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 98 | pass 99 | 100 | 101 | # Enter a parse tree produced by SysML2Parser#part_objective_blk. 102 | def enterPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 103 | pass 104 | 105 | # Exit a parse tree produced by SysML2Parser#part_objective_blk. 106 | def exitPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 107 | pass 108 | 109 | 110 | # Enter a parse tree produced by SysML2Parser#objective_def. 111 | def enterObjective_def(self, ctx:SysML2Parser.Objective_defContext): 112 | pass 113 | 114 | # Exit a parse tree produced by SysML2Parser#objective_def. 115 | def exitObjective_def(self, ctx:SysML2Parser.Objective_defContext): 116 | pass 117 | 118 | 119 | # Enter a parse tree produced by SysML2Parser#feature. 120 | def enterFeature(self, ctx:SysML2Parser.FeatureContext): 121 | pass 122 | 123 | # Exit a parse tree produced by SysML2Parser#feature. 124 | def exitFeature(self, ctx:SysML2Parser.FeatureContext): 125 | pass 126 | 127 | 128 | # Enter a parse tree produced by SysML2Parser#feature_attribute_def. 129 | def enterFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 130 | pass 131 | 132 | # Exit a parse tree produced by SysML2Parser#feature_attribute_def. 133 | def exitFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 134 | pass 135 | 136 | 137 | # Enter a parse tree produced by SysML2Parser#feature_attribute_redefines. 138 | def enterFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 139 | pass 140 | 141 | # Exit a parse tree produced by SysML2Parser#feature_attribute_redefines. 142 | def exitFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 143 | pass 144 | 145 | 146 | # Enter a parse tree produced by SysML2Parser#feature_part_specializes. 147 | def enterFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 148 | pass 149 | 150 | # Exit a parse tree produced by SysML2Parser#feature_part_specializes. 151 | def exitFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 152 | pass 153 | 154 | 155 | # Enter a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 156 | def enterFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 157 | pass 158 | 159 | # Exit a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 160 | def exitFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 161 | pass 162 | 163 | 164 | # Enter a parse tree produced by SysML2Parser#feature_item_def. 165 | def enterFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 166 | pass 167 | 168 | # Exit a parse tree produced by SysML2Parser#feature_item_def. 169 | def exitFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 170 | pass 171 | 172 | 173 | # Enter a parse tree produced by SysML2Parser#feature_item_ref. 174 | def enterFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 175 | pass 176 | 177 | # Exit a parse tree produced by SysML2Parser#feature_item_ref. 178 | def exitFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 179 | pass 180 | 181 | 182 | # Enter a parse tree produced by SysML2Parser#feature_actor_specializes. 183 | def enterFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 184 | pass 185 | 186 | # Exit a parse tree produced by SysML2Parser#feature_actor_specializes. 187 | def exitFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 188 | pass 189 | 190 | 191 | # Enter a parse tree produced by SysML2Parser#comment. 192 | def enterComment(self, ctx:SysML2Parser.CommentContext): 193 | pass 194 | 195 | # Exit a parse tree produced by SysML2Parser#comment. 196 | def exitComment(self, ctx:SysML2Parser.CommentContext): 197 | pass 198 | 199 | 200 | # Enter a parse tree produced by SysML2Parser#comment_unnamed. 201 | def enterComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 202 | pass 203 | 204 | # Exit a parse tree produced by SysML2Parser#comment_unnamed. 205 | def exitComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 206 | pass 207 | 208 | 209 | # Enter a parse tree produced by SysML2Parser#comment_named. 210 | def enterComment_named(self, ctx:SysML2Parser.Comment_namedContext): 211 | pass 212 | 213 | # Exit a parse tree produced by SysML2Parser#comment_named. 214 | def exitComment_named(self, ctx:SysML2Parser.Comment_namedContext): 215 | pass 216 | 217 | 218 | # Enter a parse tree produced by SysML2Parser#comment_named_about. 219 | def enterComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 220 | pass 221 | 222 | # Exit a parse tree produced by SysML2Parser#comment_named_about. 223 | def exitComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 224 | pass 225 | 226 | 227 | # Enter a parse tree produced by SysML2Parser#doc. 228 | def enterDoc(self, ctx:SysML2Parser.DocContext): 229 | pass 230 | 231 | # Exit a parse tree produced by SysML2Parser#doc. 232 | def exitDoc(self, ctx:SysML2Parser.DocContext): 233 | pass 234 | 235 | 236 | # Enter a parse tree produced by SysML2Parser#doc_unnamed. 237 | def enterDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 238 | pass 239 | 240 | # Exit a parse tree produced by SysML2Parser#doc_unnamed. 241 | def exitDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 242 | pass 243 | 244 | 245 | # Enter a parse tree produced by SysML2Parser#doc_named. 246 | def enterDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 247 | pass 248 | 249 | # Exit a parse tree produced by SysML2Parser#doc_named. 250 | def exitDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 251 | pass 252 | 253 | 254 | # Enter a parse tree produced by SysML2Parser#statement. 255 | def enterStatement(self, ctx:SysML2Parser.StatementContext): 256 | pass 257 | 258 | # Exit a parse tree produced by SysML2Parser#statement. 259 | def exitStatement(self, ctx:SysML2Parser.StatementContext): 260 | pass 261 | 262 | 263 | # Enter a parse tree produced by SysML2Parser#import_package. 264 | def enterImport_package(self, ctx:SysML2Parser.Import_packageContext): 265 | pass 266 | 267 | # Exit a parse tree produced by SysML2Parser#import_package. 268 | def exitImport_package(self, ctx:SysML2Parser.Import_packageContext): 269 | pass 270 | 271 | 272 | 273 | del SysML2Parser -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old/SysML2Visitor.py: -------------------------------------------------------------------------------- 1 | # Generated from SysML2.g4 by ANTLR 4.10.1 2 | from antlr4 import * 3 | if __name__ is not None and "." in __name__: 4 | from .SysML2Parser import SysML2Parser 5 | else: 6 | from SysML2Parser import SysML2Parser 7 | 8 | # This class defines a complete generic visitor for a parse tree produced by SysML2Parser. 9 | 10 | class SysML2Visitor(ParseTreeVisitor): 11 | 12 | # Visit a parse tree produced by SysML2Parser#model. 13 | def visitModel(self, ctx:SysML2Parser.ModelContext): 14 | return self.visitChildren(ctx) 15 | 16 | 17 | # Visit a parse tree produced by SysML2Parser#element. 18 | def visitElement(self, ctx:SysML2Parser.ElementContext): 19 | return self.visitChildren(ctx) 20 | 21 | 22 | # Visit a parse tree produced by SysML2Parser#namespace. 23 | def visitNamespace(self, ctx:SysML2Parser.NamespaceContext): 24 | return self.visitChildren(ctx) 25 | 26 | 27 | # Visit a parse tree produced by SysML2Parser#sysml2_package. 28 | def visitSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 29 | return self.visitChildren(ctx) 30 | 31 | 32 | # Visit a parse tree produced by SysML2Parser#part_blk. 33 | def visitPart_blk(self, ctx:SysML2Parser.Part_blkContext): 34 | return self.visitChildren(ctx) 35 | 36 | 37 | # Visit a parse tree produced by SysML2Parser#part. 38 | def visitPart(self, ctx:SysML2Parser.PartContext): 39 | return self.visitChildren(ctx) 40 | 41 | 42 | # Visit a parse tree produced by SysML2Parser#part_def. 43 | def visitPart_def(self, ctx:SysML2Parser.Part_defContext): 44 | return self.visitChildren(ctx) 45 | 46 | 47 | # Visit a parse tree produced by SysML2Parser#part_def_specializes. 48 | def visitPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 49 | return self.visitChildren(ctx) 50 | 51 | 52 | # Visit a parse tree produced by SysML2Parser#use_case_blk. 53 | def visitUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 54 | return self.visitChildren(ctx) 55 | 56 | 57 | # Visit a parse tree produced by SysML2Parser#use_case_def. 58 | def visitUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 59 | return self.visitChildren(ctx) 60 | 61 | 62 | # Visit a parse tree produced by SysML2Parser#part_objective_blk. 63 | def visitPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 64 | return self.visitChildren(ctx) 65 | 66 | 67 | # Visit a parse tree produced by SysML2Parser#objective_def. 68 | def visitObjective_def(self, ctx:SysML2Parser.Objective_defContext): 69 | return self.visitChildren(ctx) 70 | 71 | 72 | # Visit a parse tree produced by SysML2Parser#feature. 73 | def visitFeature(self, ctx:SysML2Parser.FeatureContext): 74 | return self.visitChildren(ctx) 75 | 76 | 77 | # Visit a parse tree produced by SysML2Parser#feature_attribute_def. 78 | def visitFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 79 | return self.visitChildren(ctx) 80 | 81 | 82 | # Visit a parse tree produced by SysML2Parser#feature_attribute_redefines. 83 | def visitFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 84 | return self.visitChildren(ctx) 85 | 86 | 87 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes. 88 | def visitFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 89 | return self.visitChildren(ctx) 90 | 91 | 92 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 93 | def visitFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 94 | return self.visitChildren(ctx) 95 | 96 | 97 | # Visit a parse tree produced by SysML2Parser#feature_item_def. 98 | def visitFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 99 | return self.visitChildren(ctx) 100 | 101 | 102 | # Visit a parse tree produced by SysML2Parser#feature_item_ref. 103 | def visitFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 104 | return self.visitChildren(ctx) 105 | 106 | 107 | # Visit a parse tree produced by SysML2Parser#feature_actor_specializes. 108 | def visitFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 109 | return self.visitChildren(ctx) 110 | 111 | 112 | # Visit a parse tree produced by SysML2Parser#comment. 113 | def visitComment(self, ctx:SysML2Parser.CommentContext): 114 | return self.visitChildren(ctx) 115 | 116 | 117 | # Visit a parse tree produced by SysML2Parser#comment_unnamed. 118 | def visitComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 119 | return self.visitChildren(ctx) 120 | 121 | 122 | # Visit a parse tree produced by SysML2Parser#comment_named. 123 | def visitComment_named(self, ctx:SysML2Parser.Comment_namedContext): 124 | return self.visitChildren(ctx) 125 | 126 | 127 | # Visit a parse tree produced by SysML2Parser#comment_named_about. 128 | def visitComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 129 | return self.visitChildren(ctx) 130 | 131 | 132 | # Visit a parse tree produced by SysML2Parser#doc. 133 | def visitDoc(self, ctx:SysML2Parser.DocContext): 134 | return self.visitChildren(ctx) 135 | 136 | 137 | # Visit a parse tree produced by SysML2Parser#doc_unnamed. 138 | def visitDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 139 | return self.visitChildren(ctx) 140 | 141 | 142 | # Visit a parse tree produced by SysML2Parser#doc_named. 143 | def visitDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 144 | return self.visitChildren(ctx) 145 | 146 | 147 | # Visit a parse tree produced by SysML2Parser#statement. 148 | def visitStatement(self, ctx:SysML2Parser.StatementContext): 149 | return self.visitChildren(ctx) 150 | 151 | 152 | # Visit a parse tree produced by SysML2Parser#import_package. 153 | def visitImport_package(self, ctx:SysML2Parser.Import_packageContext): 154 | return self.visitChildren(ctx) 155 | 156 | 157 | 158 | del SysML2Parser -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old2/SysML2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_PORT=20 21 | KW_REDEFINES=21 22 | KW_REF=22 23 | KW_SPECIALIZES=23 24 | KW_SUBJECT=24 25 | KW_SUBSETS=25 26 | KW_USE=26 27 | KW_SYM_FQN=27 28 | KW_SYM_REDEFINES=28 29 | KW_SYM_SUBSETS=29 30 | CONSTANT=30 31 | TYPE=31 32 | ID=32 33 | INTEGER=33 34 | REAL=34 35 | BOOL=35 36 | STRING=36 37 | MULTIPLICITY=37 38 | NULL=38 39 | WS=39 40 | NOTE=40 41 | COMMENT_LONG=41 42 | '{'=1 43 | '}'=2 44 | ';'=3 45 | ','=4 46 | ':'=5 47 | '='=6 48 | '*'=7 49 | 'about'=8 50 | 'actor'=9 51 | 'attribute'=10 52 | 'case'=11 53 | 'comment'=12 54 | 'def'=13 55 | 'doc'=14 56 | 'import'=15 57 | 'item'=16 58 | 'objective'=17 59 | 'package'=18 60 | 'part'=19 61 | 'port'=20 62 | 'redefines'=21 63 | 'ref'=22 64 | 'specializes'=23 65 | 'subject'=24 66 | 'subsets'=25 67 | 'use'=26 68 | '::'=27 69 | ':>>'=28 70 | ':>'=29 71 | 'null'=38 72 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old2/SysML2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | T__1=2 3 | T__2=3 4 | T__3=4 5 | T__4=5 6 | T__5=6 7 | T__6=7 8 | KW_ABOUT=8 9 | KW_ACTOR=9 10 | KW_ATTRIBUTE=10 11 | KW_CASE=11 12 | KW_COMMENT=12 13 | KW_DEF=13 14 | KW_DOC=14 15 | KW_IMPORT=15 16 | KW_ITEM=16 17 | KW_OBJECTIVE=17 18 | KW_PACKAGE=18 19 | KW_PART=19 20 | KW_PORT=20 21 | KW_REDEFINES=21 22 | KW_REF=22 23 | KW_SPECIALIZES=23 24 | KW_SUBJECT=24 25 | KW_SUBSETS=25 26 | KW_USE=26 27 | KW_SYM_FQN=27 28 | KW_SYM_REDEFINES=28 29 | KW_SYM_SUBSETS=29 30 | CONSTANT=30 31 | TYPE=31 32 | ID=32 33 | INTEGER=33 34 | REAL=34 35 | BOOL=35 36 | STRING=36 37 | MULTIPLICITY=37 38 | NULL=38 39 | WS=39 40 | NOTE=40 41 | COMMENT_LONG=41 42 | '{'=1 43 | '}'=2 44 | ';'=3 45 | ','=4 46 | ':'=5 47 | '='=6 48 | '*'=7 49 | 'about'=8 50 | 'actor'=9 51 | 'attribute'=10 52 | 'case'=11 53 | 'comment'=12 54 | 'def'=13 55 | 'doc'=14 56 | 'import'=15 57 | 'item'=16 58 | 'objective'=17 59 | 'package'=18 60 | 'part'=19 61 | 'port'=20 62 | 'redefines'=21 63 | 'ref'=22 64 | 'specializes'=23 65 | 'subject'=24 66 | 'subsets'=25 67 | 'use'=26 68 | '::'=27 69 | ':>>'=28 70 | ':>'=29 71 | 'null'=38 72 | -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old2/SysML2Listener.py: -------------------------------------------------------------------------------- 1 | # Generated from SysML2.g4 by ANTLR 4.13.1 2 | from antlr4 import * 3 | if "." in __name__: 4 | from .SysML2Parser import SysML2Parser 5 | else: 6 | from SysML2Parser import SysML2Parser 7 | 8 | # This class defines a complete listener for a parse tree produced by SysML2Parser. 9 | class SysML2Listener(ParseTreeListener): 10 | 11 | # Enter a parse tree produced by SysML2Parser#model. 12 | def enterModel(self, ctx:SysML2Parser.ModelContext): 13 | pass 14 | 15 | # Exit a parse tree produced by SysML2Parser#model. 16 | def exitModel(self, ctx:SysML2Parser.ModelContext): 17 | pass 18 | 19 | 20 | # Enter a parse tree produced by SysML2Parser#element. 21 | def enterElement(self, ctx:SysML2Parser.ElementContext): 22 | pass 23 | 24 | # Exit a parse tree produced by SysML2Parser#element. 25 | def exitElement(self, ctx:SysML2Parser.ElementContext): 26 | pass 27 | 28 | 29 | # Enter a parse tree produced by SysML2Parser#namespace. 30 | def enterNamespace(self, ctx:SysML2Parser.NamespaceContext): 31 | pass 32 | 33 | # Exit a parse tree produced by SysML2Parser#namespace. 34 | def exitNamespace(self, ctx:SysML2Parser.NamespaceContext): 35 | pass 36 | 37 | 38 | # Enter a parse tree produced by SysML2Parser#sysml2_package. 39 | def enterSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 40 | pass 41 | 42 | # Exit a parse tree produced by SysML2Parser#sysml2_package. 43 | def exitSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 44 | pass 45 | 46 | 47 | # Enter a parse tree produced by SysML2Parser#part_blk. 48 | def enterPart_blk(self, ctx:SysML2Parser.Part_blkContext): 49 | pass 50 | 51 | # Exit a parse tree produced by SysML2Parser#part_blk. 52 | def exitPart_blk(self, ctx:SysML2Parser.Part_blkContext): 53 | pass 54 | 55 | 56 | # Enter a parse tree produced by SysML2Parser#part. 57 | def enterPart(self, ctx:SysML2Parser.PartContext): 58 | pass 59 | 60 | # Exit a parse tree produced by SysML2Parser#part. 61 | def exitPart(self, ctx:SysML2Parser.PartContext): 62 | pass 63 | 64 | 65 | # Enter a parse tree produced by SysML2Parser#part_def. 66 | def enterPart_def(self, ctx:SysML2Parser.Part_defContext): 67 | pass 68 | 69 | # Exit a parse tree produced by SysML2Parser#part_def. 70 | def exitPart_def(self, ctx:SysML2Parser.Part_defContext): 71 | pass 72 | 73 | 74 | # Enter a parse tree produced by SysML2Parser#part_def_specializes. 75 | def enterPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 76 | pass 77 | 78 | # Exit a parse tree produced by SysML2Parser#part_def_specializes. 79 | def exitPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 80 | pass 81 | 82 | 83 | # Enter a parse tree produced by SysML2Parser#port. 84 | def enterPort(self, ctx:SysML2Parser.PortContext): 85 | pass 86 | 87 | # Exit a parse tree produced by SysML2Parser#port. 88 | def exitPort(self, ctx:SysML2Parser.PortContext): 89 | pass 90 | 91 | 92 | # Enter a parse tree produced by SysML2Parser#port_def. 93 | def enterPort_def(self, ctx:SysML2Parser.Port_defContext): 94 | pass 95 | 96 | # Exit a parse tree produced by SysML2Parser#port_def. 97 | def exitPort_def(self, ctx:SysML2Parser.Port_defContext): 98 | pass 99 | 100 | 101 | # Enter a parse tree produced by SysML2Parser#port_blk. 102 | def enterPort_blk(self, ctx:SysML2Parser.Port_blkContext): 103 | pass 104 | 105 | # Exit a parse tree produced by SysML2Parser#port_blk. 106 | def exitPort_blk(self, ctx:SysML2Parser.Port_blkContext): 107 | pass 108 | 109 | 110 | # Enter a parse tree produced by SysML2Parser#use_case_blk. 111 | def enterUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 112 | pass 113 | 114 | # Exit a parse tree produced by SysML2Parser#use_case_blk. 115 | def exitUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 116 | pass 117 | 118 | 119 | # Enter a parse tree produced by SysML2Parser#use_case_def. 120 | def enterUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 121 | pass 122 | 123 | # Exit a parse tree produced by SysML2Parser#use_case_def. 124 | def exitUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 125 | pass 126 | 127 | 128 | # Enter a parse tree produced by SysML2Parser#part_objective_blk. 129 | def enterPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 130 | pass 131 | 132 | # Exit a parse tree produced by SysML2Parser#part_objective_blk. 133 | def exitPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 134 | pass 135 | 136 | 137 | # Enter a parse tree produced by SysML2Parser#objective_def. 138 | def enterObjective_def(self, ctx:SysML2Parser.Objective_defContext): 139 | pass 140 | 141 | # Exit a parse tree produced by SysML2Parser#objective_def. 142 | def exitObjective_def(self, ctx:SysML2Parser.Objective_defContext): 143 | pass 144 | 145 | 146 | # Enter a parse tree produced by SysML2Parser#feature. 147 | def enterFeature(self, ctx:SysML2Parser.FeatureContext): 148 | pass 149 | 150 | # Exit a parse tree produced by SysML2Parser#feature. 151 | def exitFeature(self, ctx:SysML2Parser.FeatureContext): 152 | pass 153 | 154 | 155 | # Enter a parse tree produced by SysML2Parser#feature_attribute_def. 156 | def enterFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 157 | pass 158 | 159 | # Exit a parse tree produced by SysML2Parser#feature_attribute_def. 160 | def exitFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 161 | pass 162 | 163 | 164 | # Enter a parse tree produced by SysML2Parser#feature_attribute_redefines. 165 | def enterFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 166 | pass 167 | 168 | # Exit a parse tree produced by SysML2Parser#feature_attribute_redefines. 169 | def exitFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 170 | pass 171 | 172 | 173 | # Enter a parse tree produced by SysML2Parser#feature_part_specializes. 174 | def enterFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 175 | pass 176 | 177 | # Exit a parse tree produced by SysML2Parser#feature_part_specializes. 178 | def exitFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 179 | pass 180 | 181 | 182 | # Enter a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 183 | def enterFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 184 | pass 185 | 186 | # Exit a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 187 | def exitFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 188 | pass 189 | 190 | 191 | # Enter a parse tree produced by SysML2Parser#feature_item_def. 192 | def enterFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 193 | pass 194 | 195 | # Exit a parse tree produced by SysML2Parser#feature_item_def. 196 | def exitFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 197 | pass 198 | 199 | 200 | # Enter a parse tree produced by SysML2Parser#feature_item_ref. 201 | def enterFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 202 | pass 203 | 204 | # Exit a parse tree produced by SysML2Parser#feature_item_ref. 205 | def exitFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 206 | pass 207 | 208 | 209 | # Enter a parse tree produced by SysML2Parser#feature_actor_specializes. 210 | def enterFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 211 | pass 212 | 213 | # Exit a parse tree produced by SysML2Parser#feature_actor_specializes. 214 | def exitFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 215 | pass 216 | 217 | 218 | # Enter a parse tree produced by SysML2Parser#comment. 219 | def enterComment(self, ctx:SysML2Parser.CommentContext): 220 | pass 221 | 222 | # Exit a parse tree produced by SysML2Parser#comment. 223 | def exitComment(self, ctx:SysML2Parser.CommentContext): 224 | pass 225 | 226 | 227 | # Enter a parse tree produced by SysML2Parser#comment_unnamed. 228 | def enterComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 229 | pass 230 | 231 | # Exit a parse tree produced by SysML2Parser#comment_unnamed. 232 | def exitComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 233 | pass 234 | 235 | 236 | # Enter a parse tree produced by SysML2Parser#comment_named. 237 | def enterComment_named(self, ctx:SysML2Parser.Comment_namedContext): 238 | pass 239 | 240 | # Exit a parse tree produced by SysML2Parser#comment_named. 241 | def exitComment_named(self, ctx:SysML2Parser.Comment_namedContext): 242 | pass 243 | 244 | 245 | # Enter a parse tree produced by SysML2Parser#comment_named_about. 246 | def enterComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 247 | pass 248 | 249 | # Exit a parse tree produced by SysML2Parser#comment_named_about. 250 | def exitComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 251 | pass 252 | 253 | 254 | # Enter a parse tree produced by SysML2Parser#doc. 255 | def enterDoc(self, ctx:SysML2Parser.DocContext): 256 | pass 257 | 258 | # Exit a parse tree produced by SysML2Parser#doc. 259 | def exitDoc(self, ctx:SysML2Parser.DocContext): 260 | pass 261 | 262 | 263 | # Enter a parse tree produced by SysML2Parser#doc_unnamed. 264 | def enterDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 265 | pass 266 | 267 | # Exit a parse tree produced by SysML2Parser#doc_unnamed. 268 | def exitDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 269 | pass 270 | 271 | 272 | # Enter a parse tree produced by SysML2Parser#doc_named. 273 | def enterDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 274 | pass 275 | 276 | # Exit a parse tree produced by SysML2Parser#doc_named. 277 | def exitDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 278 | pass 279 | 280 | 281 | # Enter a parse tree produced by SysML2Parser#statement. 282 | def enterStatement(self, ctx:SysML2Parser.StatementContext): 283 | pass 284 | 285 | # Exit a parse tree produced by SysML2Parser#statement. 286 | def exitStatement(self, ctx:SysML2Parser.StatementContext): 287 | pass 288 | 289 | 290 | # Enter a parse tree produced by SysML2Parser#import_package. 291 | def enterImport_package(self, ctx:SysML2Parser.Import_packageContext): 292 | pass 293 | 294 | # Exit a parse tree produced by SysML2Parser#import_package. 295 | def exitImport_package(self, ctx:SysML2Parser.Import_packageContext): 296 | pass 297 | 298 | 299 | 300 | del SysML2Parser -------------------------------------------------------------------------------- /pysysml2/grammar/distpy/old2/SysML2Visitor.py: -------------------------------------------------------------------------------- 1 | # Generated from SysML2.g4 by ANTLR 4.13.1 2 | from antlr4 import * 3 | if "." in __name__: 4 | from .SysML2Parser import SysML2Parser 5 | else: 6 | from SysML2Parser import SysML2Parser 7 | 8 | # This class defines a complete generic visitor for a parse tree produced by SysML2Parser. 9 | 10 | class SysML2Visitor(ParseTreeVisitor): 11 | 12 | # Visit a parse tree produced by SysML2Parser#model. 13 | def visitModel(self, ctx:SysML2Parser.ModelContext): 14 | return self.visitChildren(ctx) 15 | 16 | 17 | # Visit a parse tree produced by SysML2Parser#element. 18 | def visitElement(self, ctx:SysML2Parser.ElementContext): 19 | return self.visitChildren(ctx) 20 | 21 | 22 | # Visit a parse tree produced by SysML2Parser#namespace. 23 | def visitNamespace(self, ctx:SysML2Parser.NamespaceContext): 24 | return self.visitChildren(ctx) 25 | 26 | 27 | # Visit a parse tree produced by SysML2Parser#sysml2_package. 28 | def visitSysml2_package(self, ctx:SysML2Parser.Sysml2_packageContext): 29 | return self.visitChildren(ctx) 30 | 31 | 32 | # Visit a parse tree produced by SysML2Parser#part_blk. 33 | def visitPart_blk(self, ctx:SysML2Parser.Part_blkContext): 34 | return self.visitChildren(ctx) 35 | 36 | 37 | # Visit a parse tree produced by SysML2Parser#part. 38 | def visitPart(self, ctx:SysML2Parser.PartContext): 39 | return self.visitChildren(ctx) 40 | 41 | 42 | # Visit a parse tree produced by SysML2Parser#part_def. 43 | def visitPart_def(self, ctx:SysML2Parser.Part_defContext): 44 | return self.visitChildren(ctx) 45 | 46 | 47 | # Visit a parse tree produced by SysML2Parser#part_def_specializes. 48 | def visitPart_def_specializes(self, ctx:SysML2Parser.Part_def_specializesContext): 49 | return self.visitChildren(ctx) 50 | 51 | 52 | # Visit a parse tree produced by SysML2Parser#port. 53 | def visitPort(self, ctx:SysML2Parser.PortContext): 54 | return self.visitChildren(ctx) 55 | 56 | 57 | # Visit a parse tree produced by SysML2Parser#port_def. 58 | def visitPort_def(self, ctx:SysML2Parser.Port_defContext): 59 | return self.visitChildren(ctx) 60 | 61 | 62 | # Visit a parse tree produced by SysML2Parser#port_blk. 63 | def visitPort_blk(self, ctx:SysML2Parser.Port_blkContext): 64 | return self.visitChildren(ctx) 65 | 66 | 67 | # Visit a parse tree produced by SysML2Parser#use_case_blk. 68 | def visitUse_case_blk(self, ctx:SysML2Parser.Use_case_blkContext): 69 | return self.visitChildren(ctx) 70 | 71 | 72 | # Visit a parse tree produced by SysML2Parser#use_case_def. 73 | def visitUse_case_def(self, ctx:SysML2Parser.Use_case_defContext): 74 | return self.visitChildren(ctx) 75 | 76 | 77 | # Visit a parse tree produced by SysML2Parser#part_objective_blk. 78 | def visitPart_objective_blk(self, ctx:SysML2Parser.Part_objective_blkContext): 79 | return self.visitChildren(ctx) 80 | 81 | 82 | # Visit a parse tree produced by SysML2Parser#objective_def. 83 | def visitObjective_def(self, ctx:SysML2Parser.Objective_defContext): 84 | return self.visitChildren(ctx) 85 | 86 | 87 | # Visit a parse tree produced by SysML2Parser#feature. 88 | def visitFeature(self, ctx:SysML2Parser.FeatureContext): 89 | return self.visitChildren(ctx) 90 | 91 | 92 | # Visit a parse tree produced by SysML2Parser#feature_attribute_def. 93 | def visitFeature_attribute_def(self, ctx:SysML2Parser.Feature_attribute_defContext): 94 | return self.visitChildren(ctx) 95 | 96 | 97 | # Visit a parse tree produced by SysML2Parser#feature_attribute_redefines. 98 | def visitFeature_attribute_redefines(self, ctx:SysML2Parser.Feature_attribute_redefinesContext): 99 | return self.visitChildren(ctx) 100 | 101 | 102 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes. 103 | def visitFeature_part_specializes(self, ctx:SysML2Parser.Feature_part_specializesContext): 104 | return self.visitChildren(ctx) 105 | 106 | 107 | # Visit a parse tree produced by SysML2Parser#feature_part_specializes_subsets. 108 | def visitFeature_part_specializes_subsets(self, ctx:SysML2Parser.Feature_part_specializes_subsetsContext): 109 | return self.visitChildren(ctx) 110 | 111 | 112 | # Visit a parse tree produced by SysML2Parser#feature_item_def. 113 | def visitFeature_item_def(self, ctx:SysML2Parser.Feature_item_defContext): 114 | return self.visitChildren(ctx) 115 | 116 | 117 | # Visit a parse tree produced by SysML2Parser#feature_item_ref. 118 | def visitFeature_item_ref(self, ctx:SysML2Parser.Feature_item_refContext): 119 | return self.visitChildren(ctx) 120 | 121 | 122 | # Visit a parse tree produced by SysML2Parser#feature_actor_specializes. 123 | def visitFeature_actor_specializes(self, ctx:SysML2Parser.Feature_actor_specializesContext): 124 | return self.visitChildren(ctx) 125 | 126 | 127 | # Visit a parse tree produced by SysML2Parser#comment. 128 | def visitComment(self, ctx:SysML2Parser.CommentContext): 129 | return self.visitChildren(ctx) 130 | 131 | 132 | # Visit a parse tree produced by SysML2Parser#comment_unnamed. 133 | def visitComment_unnamed(self, ctx:SysML2Parser.Comment_unnamedContext): 134 | return self.visitChildren(ctx) 135 | 136 | 137 | # Visit a parse tree produced by SysML2Parser#comment_named. 138 | def visitComment_named(self, ctx:SysML2Parser.Comment_namedContext): 139 | return self.visitChildren(ctx) 140 | 141 | 142 | # Visit a parse tree produced by SysML2Parser#comment_named_about. 143 | def visitComment_named_about(self, ctx:SysML2Parser.Comment_named_aboutContext): 144 | return self.visitChildren(ctx) 145 | 146 | 147 | # Visit a parse tree produced by SysML2Parser#doc. 148 | def visitDoc(self, ctx:SysML2Parser.DocContext): 149 | return self.visitChildren(ctx) 150 | 151 | 152 | # Visit a parse tree produced by SysML2Parser#doc_unnamed. 153 | def visitDoc_unnamed(self, ctx:SysML2Parser.Doc_unnamedContext): 154 | return self.visitChildren(ctx) 155 | 156 | 157 | # Visit a parse tree produced by SysML2Parser#doc_named. 158 | def visitDoc_named(self, ctx:SysML2Parser.Doc_namedContext): 159 | return self.visitChildren(ctx) 160 | 161 | 162 | # Visit a parse tree produced by SysML2Parser#statement. 163 | def visitStatement(self, ctx:SysML2Parser.StatementContext): 164 | return self.visitChildren(ctx) 165 | 166 | 167 | # Visit a parse tree produced by SysML2Parser#import_package. 168 | def visitImport_package(self, ctx:SysML2Parser.Import_packageContext): 169 | return self.visitChildren(ctx) 170 | 171 | 172 | 173 | del SysML2Parser -------------------------------------------------------------------------------- /pysysml2/grammar/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.23.1 2 | pandas==1.4.3 3 | -------------------------------------------------------------------------------- /pysysml2/modeling/__init__.py: -------------------------------------------------------------------------------- 1 | from .model import Model 2 | from .element import Element, Relationship 3 | -------------------------------------------------------------------------------- /pysysml2/modeling/element.py: -------------------------------------------------------------------------------- 1 | from abc import ABC 2 | from enum import Enum 3 | import json 4 | from anytree import NodeMixin 5 | 6 | 7 | class ArchitectureLayers(Enum): 8 | root_syntactic_element = 'Root Syntactic Element' 9 | core_element = 'Core Element' 10 | kernel_element = 'Kernel Element' 11 | systems_element = 'Systems Element' 12 | 13 | 14 | class Archtypes(Enum): 15 | element = 'element' 16 | relationship = 'relationship' 17 | sysml2_import = 'import' 18 | 19 | 20 | class _RootSyntacticElement(ABC, NodeMixin): 21 | 22 | def __init__(self, name=None, parent=None, 23 | sysml2_type=None, 24 | idx=None, 25 | uuid = None, 26 | idx_parent=None, 27 | uuid_parent=None, 28 | idx_related_element=None, 29 | related_element_name=None, 30 | value_types=None, 31 | constants=None, 32 | multiplicity=None, 33 | context_type=None, 34 | keywords=None, 35 | fully_qualified_name=None, 36 | fully_qualified_name_tagged=None, 37 | tree_level=None, 38 | element_text=None): 39 | 40 | """Base class for all syntactic elements, including Element and 41 | Relationship. Note that this class is not meant to be instantiated. 42 | """ 43 | self.name = name 44 | self.parent = parent 45 | self.sysml2_type = sysml2_type 46 | self.idx = idx 47 | self.uuid = uuid 48 | self.idx_parent = idx_parent 49 | self.uuid_parent = uuid_parent 50 | self.idx_related_element = idx_related_element 51 | self.related_element_name = related_element_name 52 | self.value_types = value_types 53 | self.constants = constants 54 | self.multiplicity = multiplicity 55 | self.context_type = context_type 56 | self.keywords = keywords 57 | self.fully_qualified_name = fully_qualified_name 58 | self.fully_qualified_name_tagged = fully_qualified_name_tagged 59 | self.tree_level = tree_level 60 | self.element_text = element_text 61 | self.sysml2_layer = None # Set in child class definitions 62 | self.archtype = None 63 | 64 | def to_JSON(self): 65 | return json.dumps(self, default=lambda o: o.__dict__, 66 | sort_keys=True, indent=4) 67 | 68 | def to_dict(self): 69 | """Returns a dictionary representation of the object. 70 | Returns: 71 | _type_: _description_ 72 | """ 73 | dd = {} 74 | for k in ['sysml2_layer', 'archtype', 'sysml2_type', 'tree_level', 75 | 'name', 'idx', 'uuid', 'parent', 'idx_parent', 'uuid_parent', 76 | 'related_element_name', 'idx_related_element', 'multiplicity', 77 | 'value_types', 'constants', 'context_type', 'keywords', 78 | 'fully_qualified_name', 'fully_qualified_name_tagged', 79 | 'element_text',]: 80 | if k == 'parent': 81 | dd[k] = getattr(self, '_NodeMixin__parent').name 82 | else: 83 | dd[k] = getattr(self, k) 84 | return dd 85 | 86 | 87 | class Element(_RootSyntacticElement, NodeMixin): 88 | 89 | def __init__(self, name=None, parent=None, **kwargs): 90 | 91 | super(Element, self).__init__(name=name, parent=parent, **kwargs) 92 | self.archtype = Archtypes.element.value 93 | 94 | 95 | class Relationship(_RootSyntacticElement, NodeMixin): 96 | 97 | def __init__(self, name=None, parent=None, **kwargs): 98 | 99 | super(Relationship, self).__init__(name=name, parent=parent, **kwargs) 100 | self.archtype = Archtypes.relationship.value 101 | 102 | 103 | class Attribute(Element, NodeMixin): 104 | 105 | def __init__(self, name=None, parent=None, **kwargs): 106 | 107 | super(Attribute, self).__init__(name=name, parent=parent, **kwargs) 108 | self.sysml2_layer = ArchitectureLayers.systems_element.value 109 | 110 | 111 | class Comment(Element, NodeMixin): 112 | 113 | def __init__(self, name=None, parent=None, **kwargs): 114 | 115 | super(Comment, self).__init__(name=name, parent=parent, **kwargs) 116 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 117 | 118 | 119 | class Connection(Element, NodeMixin): 120 | 121 | def __init__(self, name=None, parent=None, **kwargs): 122 | 123 | super(Connection, self).__init__(name=name, parent=parent, **kwargs) 124 | self.sysml2_layer = ArchitectureLayers.systems_element.value 125 | 126 | 127 | class ConnectionEndPart(Element, NodeMixin): 128 | 129 | def __init__(self, name=None, parent=None, **kwargs): 130 | 131 | super(ConnectionEndPart, self).__init__(name=name, parent=parent, **kwargs) 132 | self.sysml2_layer = ArchitectureLayers.systems_element.value 133 | 134 | 135 | class Doc(Element, NodeMixin): 136 | 137 | def __init__(self, name=None, parent=None, **kwargs): 138 | 139 | super(Doc, self).__init__(name=name, parent=parent, **kwargs) 140 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 141 | 142 | 143 | class Import(Element, NodeMixin): 144 | 145 | def __init__(self, name=None, parent=None, **kwargs): 146 | 147 | super(Import, self).__init__(name=name, parent=parent, **kwargs) 148 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 149 | 150 | 151 | class Item(Element, NodeMixin): 152 | 153 | def __init__(self, name=None, parent=None, **kwargs): 154 | 155 | super(Item, self).__init__(name=name, parent=parent, **kwargs) 156 | self.sysml2_layer = ArchitectureLayers.systems_element.value 157 | 158 | 159 | class Include(Element, NodeMixin): 160 | 161 | def __init__(self, name=None, parent=None, **kwargs): 162 | 163 | super(Include, self).__init__(name=name, parent=parent, **kwargs) 164 | self.sysml2_layer = ArchitectureLayers.systems_element.value 165 | 166 | 167 | class Objective(Element, NodeMixin): 168 | 169 | def __init__(self, name=None, parent=None, **kwargs): 170 | 171 | super(Objective, self).__init__(name=name, parent=parent, **kwargs) 172 | self.sysml2_layer = ArchitectureLayers.systems_element.value 173 | 174 | 175 | class Package(Element, NodeMixin): 176 | 177 | def __init__(self, name=None, parent=None, **kwargs): 178 | 179 | super(Package, self).__init__(name=name, parent=parent, **kwargs) 180 | self.sysml2_layer = ArchitectureLayers.kernel_element.value 181 | 182 | 183 | class Part(Element, NodeMixin): 184 | 185 | def __init__(self, name=None, parent=None, **kwargs): 186 | 187 | super(Part, self).__init__(name=name, parent=parent, **kwargs) 188 | self.sysml2_layer = ArchitectureLayers.systems_element.value 189 | 190 | 191 | class Port(Element, NodeMixin): 192 | 193 | def __init__(self, name=None, parent=None, **kwargs): 194 | 195 | super(Port, self).__init__(name=name, parent=parent, **kwargs) 196 | self.sysml2_layer = ArchitectureLayers.systems_element.value 197 | 198 | 199 | class UseCase(Element, NodeMixin): 200 | 201 | def __init__(self, name=None, parent=None, **kwargs): 202 | 203 | super(UseCase, self).__init__(name=name, parent=parent, **kwargs) 204 | self.sysml2_layer = ArchitectureLayers.systems_element.value 205 | 206 | 207 | 208 | class RelationshipConnect(Relationship, NodeMixin): 209 | 210 | def __init__(self, name=None, parent=None, **kwargs): 211 | 212 | super(RelationshipConnect, self).__init__(name=name, parent=parent, **kwargs) 213 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 214 | 215 | 216 | 217 | class RelationshipRedefines(Relationship, NodeMixin): 218 | 219 | def __init__(self, name=None, parent=None, **kwargs): 220 | 221 | super(RelationshipRedefines, self).__init__(name=name, parent=parent, **kwargs) 222 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 223 | 224 | 225 | class RelationshipSpecializes(Relationship, NodeMixin): 226 | 227 | def __init__(self, name=None, parent=None, **kwargs): 228 | 229 | super(RelationshipSpecializes, self).__init__(name=name, parent=parent, **kwargs) 230 | self.sysml2_layer = ArchitectureLayers.root_syntactic_element.value 231 | 232 | 233 | class RelationshipMessage(Relationship, NodeMixin): 234 | 235 | def __init__(self, name=None, parent=None, **kwargs): 236 | 237 | super(RelationshipMessage, self).__init__(name=name, parent=parent, **kwargs) 238 | self.sysml2_layer = ArchitectureLayers.systems_element.value -------------------------------------------------------------------------------- /sandbox/helloworld.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/sandbox/helloworld.py -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from setuptools import setup 3 | 4 | packages = \ 5 | ['pysysml2', 6 | 'pysysml2.cli', 7 | 'pysysml2.grammar', 8 | 'pysysml2.grammar.distpy', 9 | 'pysysml2.modeling'] 10 | 11 | package_data = \ 12 | {'': ['*'], 'pysysml2.grammar': ['distj/*']} 13 | 14 | install_requires = \ 15 | ['antlr4-python3-runtime==4.10', 16 | 'anytree>=2.8.0,<3.0.0', 17 | 'graphviz>=0.20.1,<0.21.0', 18 | 'numpy>=1.24.2,<2.0.0', 19 | 'openpyxl>=3.1.1,<4.0.0', 20 | 'pandas>=1.5.3,<2.0.0', 21 | 'typer>=0.7.0,<0.8.0'] 22 | 23 | entry_points = \ 24 | {'console_scripts': ['pysysml2 = pysysml2.cli.__main__:app']} 25 | 26 | setup_kwargs = { 27 | 'name': 'pysysml2', 28 | 'version': '0.1.1', 29 | 'description': 'Python based parser for the SysML 2.0 textual modeling language.', 30 | 'long_description': "# PySysML2\n\nPySysML2 is a Python-based parser for the SysML 2.0 textual modeling language. Its main purpose is to parse a SysML 2.0 textual model into a Python object, and then transform that model into various data structures useful for data science and analysis.\n\n## Dependencies\n\nPySysML2 has the following dependencies:\n\n- anytree: provides the tree data structure, the basis for the Python model class\n- graphviz: renders images of graphs\n- numpy: numerical analysis package\n- pandas: data analysis package, provides the DataFrame data structure\n- openpyxl: allows Pandas to export to Excel\n- antlr4: provides the language parsing workbench\n\nNote that some of these packages (specifically Anytree, Graphviz, and Antlr4) are not available on Anaconda. Also, Pandas does not automatically install the required OpenPyxl module for exporting Excel, so that must be done separately.\n\n## Installation\n\nSee the [Development section](#development) for installation instructions if you are a developer.\n\n### Install From Source\n\n```console\ngit clone git@github.com:TrekkieByDay/PySysML2.git\n\ncd PySysML2/\n\npip install .\n```\n\n## Usage\n\n### CLI\n\nAfter installation, the `pysysml2` CLI tool should be available. The following demonstrates using the `pysysml2 export` command to export the SysML 2.0 textual model file to various output file formats.\n```console\n❯ pysysml2 export examples/models/model_test_1.sysml2 --output-dir out/ --format json,txt,csv,xlsx,dot,png\nUsing output directory: /Users/delannmt/Workspace/Projects/react/sysml/PySysML2/tmp\nExporting to JSON...\nExporting to txt...\nExporting to csv...\nExporting to xlsx...\nExporting to dot...\nExporting to png...\n```\n\nFor more information about the `pysysml2 export` command, use the `--help` option:\n```console\n❯ pysysml2 export --help\nUsage: pysysml2 export [OPTIONS] MODEL_FILE\n\n Export a SysML v2 model to various file formats.\n\nArguments:\n MODEL_FILE The sysml2 model file. [required]\n\nOptions:\n --format TEXT One or more comma-separated output file formats.\n Supported formats: json,txt,csv,xlsx,dot,png\n [default: json]\n -o, --output-dir PATH The output directory for the generated file(s).\n Defaults to current directory.\n --help Show this message and exit.\n```\n\n### Python API Examples\n\nThe `examples/` directory contains an example Python script using `pysysml2` to export sample SysML 2.0 textual models to various output file formats. \n\n### Jupyter Notebook\n\nPySysML2 can be used through Jupyter notebooks. Check the [PySysML2_notebook.ipynb](PySysML2_notebook.ipynb) notebook to test the parsing functionality using the provided SysML 2.0 models.\n\n## Project Structure\n\nThe `pysysml2` directory contains all the code. It is divided into the `grammar` and `modeling` packages.\n\nThe `grammar` package contains all the Antlr4 parsing code. The primary artifact of interest is the `SysML.g4` grammar source file, which defines the basic elements of SysML 2.0 that PySysML2 implements. This file is used by the stand-alone Antlr4 command-line application that generates the language parsing Python code. Everything in the `distpy`, `.antlr`, and `distj` directories is auto-generated, and only `distpy` is required for PySysML2. The `sysml2_model_visitor.py` module is an extension of the generated `SysML2Visitor.py` and is the interface between the language parse tree from the textual model and the PySysML2 toolset.\n\nThe `modeling` package contains the SysML 2.0 modeling implementation and export tools. The `element` module implements model elements, and the `model` module implements a SysML 2.0 model class built from element objects. All export functions are in `model.py`.\n\n## Development\n\n### Setup Poetry\n\nTo use PySysML2 with Poetry, follow these steps:\n\n1. Install Poetry by following the instructions in the [official documentation](https://python-poetry.org/docs/#installation). **TLDR:** run the following command:\n```\ncurl -sSL https://install.python-poetry.org | python3 -\n```\n\n2. In the root directory of the project repository, run the following command to install all the required dependencies:\n```\npoetry install\n```\n\nThis will install the main dependencies specified in the `pyproject.toml` file.\n\n#### Development Group\n\nPySysML2 has a `dev` group in its `pyproject.toml` file that contains the dependencies required for development and testing. To install these dependencies, run the following command in the root directory of the cloned repository:\n\n```\npoetry install --group=dev\n```\n\nThis will install the development dependencies, including packages such as `pytest`.\n\n### Using Poetry\n\nBy default, Poetry creates a virtual environment for each project, so all the\ndependencies are installed locally to that environment. This ensures that different\nprojects can have different dependencies and versions installed without interfering\nwith each other.\n\nTo execute a command inside the virtual environment, use the `poetry run` command.\nFor instance, to run the tests for this project, run the following command:\n```\npoetry run pytest\n```\n\nTo activate the virtual environment, run the following command:\n```\npoetry shell\n```\n\nTo exit the virtual environment, use `exit`:\n```\nexit\n```\n\n### poetry2setup\n\nFor the convenience of users installing from source without Poetry, developers can\ngenerate the `setup.py` file from the `pyproject.toml` using the `poetry2setup` tool\n(requires [Poetry dev group installation](#development-group)):\n```\npoetry run poetry2setup >> setup.py\n```\n\n### poetry2conda\n\nTo support Anaconda distribution, developers can generate the conda environment file\nfrom the `pyproject.toml` using the `poetry2conda`\n(requires [Poetry dev groupinstallation](#development-group)):\n```\npoetry run poetry2conda pyproject.toml environment.yaml\n```\n\n### Why use Poetry?\n\nPoetry is a Python packaging and dependency management tool that helps simplify the process of building, packaging, and distributing Python projects. It provides a simple and intuitive way to manage project dependencies, handle virtual environments, and create distributable packages.\n\nUsing Poetry has several benefits:\n\n- **Dependency management**: Poetry simplifies dependency management by allowing you to easily install, uninstall, and upgrade packages, and automatically resolving dependencies between packages.\n- **Virtual environments**: Poetry creates and manages virtual environments for each project, ensuring that different projects can have different dependencies and versions installed without interfering with each other.\n- **Package building and publishing**: Poetry provides a simple way to build and publish packages to PyPI, as well as other package indexes such as your company's private package index.\n- **PEP standards compliance**: Poetry is designed to comply with the Python Enhancement Proposal (PEP) standards, which helps ensure compatibility with other Python tools and libraries.\n\n### How Poetry helps follow PEP standards\n\nPEP standards are a set of guidelines and recommendations for how to structure, package, and distribute Python code. These standards help ensure that Python packages are well-designed, easy to use, and compatible with other Python tools and libraries.\n\nPoetry is designed to follow the PEP standards, which makes it easier to create Python packages that are compliant with these guidelines. Here are some ways in which Poetry helps follow PEP standards:\n\n- [PEP 517](https://peps.python.org/pep-0517/)/[518](https://peps.python.org/pep-0518/) compliance: Poetry uses the PEP 517/518 standards for building and packaging Python projects, including build isolation to ensure that builds are reproducible and do not rely on the developer's environment. These standards help ensure compatibility with other Python tools such as pip and setuptools.\n- [pyproject.toml](https://pip.pypa.io/en/stable/reference/build-system/pyproject-toml/): Poetry uses a pyproject.toml configuration file to manage project settings and dependencies. This file conforms to the [PEP 621](https://peps.python.org/pep-0621/) standard, which provides a standard way to define project metadata and dependencies.\n- [PEP 440](https://peps.python.org/pep-0440/) versioning: Poetry uses the PEP 440 standard for versioning packages, which provides a standard way to version and compare package versions.\n- [PEP 508](https://peps.python.org/pep-0508/) dependencies: Poetry supports PEP 508-style dependencies, which allows you to specify dependencies with more detail and flexibility than standard requirements.txt files.", 31 | 'author': 'Keith Lucas', 32 | 'author_email': 'ke.le.luc@gmail.com', 33 | 'maintainer': 'None', 34 | 'maintainer_email': 'None', 35 | 'url': 'None', 36 | 'packages': packages, 37 | 'package_data': package_data, 38 | 'install_requires': install_requires, 39 | 'entry_points': entry_points, 40 | 'python_requires': '>=3.8,<4.0', 41 | } 42 | 43 | 44 | setup(**setup_kwargs) 45 | 46 | -------------------------------------------------------------------------------- /simulation/context_builder.py: -------------------------------------------------------------------------------- 1 | import os,sys 2 | from src.modeling.model import Model 3 | from src.modeling.element import Element, Relationship 4 | from anytree import Node, RenderTree, NodeMixin 5 | from anytree.exporter import DotExporter, JsonExporter 6 | 7 | 8 | class SimContext: 9 | 10 | def __init__(self, model_file): 11 | 12 | self.model = Model().from_sysml2_file(model_file) 13 | 14 | for pre, fill, node in RenderTree(self.model): 15 | print("{}".format(node.name)) 16 | 17 | print('stop') 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /simulation/sim_engine.py: -------------------------------------------------------------------------------- 1 | import os,sys 2 | # sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 3 | # print(sys.path) 4 | # from ..modeling.model import Model 5 | import src.modeling.model as model -------------------------------------------------------------------------------- /template.tex: -------------------------------------------------------------------------------- 1 | \documentclass{article} 2 | \usepackage[utf8]{inputenc} 3 | \usepackage{helvet} 4 | \renewcommand{\familydefault}{\sfdefault} 5 | 6 | \begin{document} 7 | $body$ 8 | \end{document} -------------------------------------------------------------------------------- /test.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pysysml2.modeling import Model 3 | 4 | 5 | # in_dir = "./examples/models" 6 | # out_dir = "./examples/output" 7 | # in_sysml2 = [f for f in os.listdir(in_dir) if f.endswith(".sysml2")] 8 | 9 | # # Looping through all model files in the input directory 10 | # for in_f in in_sysml2: 11 | # in_f = os.path.join(in_dir, in_f) # Set filename 12 | # model = Model() # Create Model object 13 | # model.from_sysml2_file(in_f) # Parse the textual model 14 | # model.to_dot(out_dir) # Tranform model to a .dot file 15 | # model.to_png(out_dir) # Export PNG of tree graph 16 | # model.to_excel(out_dir) # Convert to tabular format 17 | # model.to_csv(out_dir) # Export tabular view to CSV 18 | # model.to_JSON(out_dir) # Serialize Model object to JSON 19 | # model.to_txt(out_dir) # Output string representation 20 | 21 | 22 | in_dir = "./examples/models" 23 | # in_dir = "./examples/updated_test" 24 | # model_file = "simplified_beagleplay.sysml" 25 | # model_file = "model_test_3.sysml2" 26 | model_file = "model_test_2.sysml2" 27 | out_dir = "./examples/output" 28 | 29 | in_f = os.path.join(in_dir, model_file) # Set filename 30 | model = Model() # Create Model object 31 | model.from_sysml2_file(in_f) 32 | model.to_excel(out_dir) 33 | 34 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/__init__.py -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | import os 2 | from pathlib import Path 3 | import pytest 4 | 5 | 6 | @pytest.fixture 7 | def shared_models_datadir(shared_datadir: Path): 8 | return shared_datadir / "models" 9 | 10 | 11 | @pytest.fixture 12 | def output_datadir(datadir: Path): 13 | """Temporary output data diretory for a test case.""" 14 | output_dir = datadir / "__output__" 15 | os.makedirs(output_dir, exist_ok=True) 16 | return output_dir 17 | -------------------------------------------------------------------------------- /tests/grammar/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/grammar/__init__.py -------------------------------------------------------------------------------- /tests/grammar/test_antlr4_helper.py: -------------------------------------------------------------------------------- 1 | from pysysml2.grammar.distpy.SysML2Parser import SysML2Parser 2 | 3 | from pysysml2.grammar.antlr4_helper import ( 4 | build_parser_context_names_enum, 5 | ) 6 | 7 | 8 | def test_build_parser_context_names_enum(): 9 | parser_contexts = build_parser_context_names_enum( 10 | SysML2Parser, "ParserContextsEnum" 11 | ) 12 | for kw in parser_contexts: 13 | assert kw.name == kw.value 14 | -------------------------------------------------------------------------------- /tests/modeling/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/modeling/__init__.py -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_1.dot: -------------------------------------------------------------------------------- 1 | digraph tree { 2 | "root"; 3 | "Model@0_None"; 4 | "PySysML2_GENERATED_NAME_1_0@1_0"; 5 | "PySysML2_GENERATED_NAME_2_0@2_0"; 6 | "Comment_1@3_0"; 7 | "Structure@4_0"; 8 | "WiFi Card@5_4"; 9 | "Bluetooth Card@6_4"; 10 | "Icon@7_4"; 11 | "Controller Board@8_4"; 12 | "wifi card@9_8"; 13 | "bluetooth card@10_8"; 14 | "RAM@11_8"; 15 | "Primary Interface@12_8"; 16 | "Secondary Interface@13_8"; 17 | "WiFi Frequency@14_8"; 18 | "WiFi Protocol@15_8"; 19 | "Bluetooth Capable@16_8"; 20 | "LCD Display@17_4"; 21 | "Battery@18_4"; 22 | "Raspberry Pi Pico Wireless@19_4"; 23 | "RAM@20_19"; 24 | "Bluetooth Capable@21_19"; 25 | "Primary Interface@22_19"; 26 | "Secondary Interface@23_19"; 27 | "WiFi Protocol@24_19"; 28 | "WiFi Frequency@25_19"; 29 | "Bicool Round LCD IPS Display GC9A01@26_4"; 30 | "TTRPG eToken System@27_4"; 31 | "controller board@28_27"; 32 | "lcd display@29_27"; 33 | "battery@30_27"; 34 | "TTRPG eToken System Prototype@31_4"; 35 | "controller board@32_31"; 36 | "lcd display@33_31"; 37 | "Behavior@34_0"; 38 | "User@35_34"; 39 | "Change displayed image on eToken@36_34"; 40 | "user@37_36"; 41 | "PySysML2_GENERATED_NAME_38_36@38_36"; 42 | "PySysML2_GENERATED_NAME_39_38@39_38"; 43 | "Remove existing image form eToken@40_34"; 44 | "PySysML2_GENERATED_NAME_41_40@41_40"; 45 | "PySysML2_GENERATED_NAME_42_41@42_41"; 46 | "user@43_40"; 47 | "Load new image to eToken@44_34"; 48 | "PySysML2_GENERATED_NAME_45_44@45_44"; 49 | "PySysML2_GENERATED_NAME_46_45@46_45"; 50 | "user@47_44"; 51 | "Use eToken as game piece@48_34"; 52 | "PySysML2_GENERATED_NAME_49_48@49_48"; 53 | "PySysML2_GENERATED_NAME_50_49@50_49"; 54 | "user@51_48"; 55 | "root" -> "Model@0_None"; 56 | "Model@0_None" -> "PySysML2_GENERATED_NAME_1_0@1_0"; 57 | "Model@0_None" -> "PySysML2_GENERATED_NAME_2_0@2_0"; 58 | "Model@0_None" -> "Comment_1@3_0"; 59 | "Model@0_None" -> "Structure@4_0"; 60 | "Model@0_None" -> "Behavior@34_0"; 61 | "Structure@4_0" -> "WiFi Card@5_4"; 62 | "Structure@4_0" -> "Bluetooth Card@6_4"; 63 | "Structure@4_0" -> "Icon@7_4"; 64 | "Structure@4_0" -> "Controller Board@8_4"; 65 | "Structure@4_0" -> "LCD Display@17_4"; 66 | "Structure@4_0" -> "Battery@18_4"; 67 | "Structure@4_0" -> "Raspberry Pi Pico Wireless@19_4"; 68 | "Structure@4_0" -> "Bicool Round LCD IPS Display GC9A01@26_4"; 69 | "Structure@4_0" -> "TTRPG eToken System@27_4"; 70 | "Structure@4_0" -> "TTRPG eToken System Prototype@31_4"; 71 | "Controller Board@8_4" -> "wifi card@9_8"; 72 | "Controller Board@8_4" -> "bluetooth card@10_8"; 73 | "Controller Board@8_4" -> "RAM@11_8"; 74 | "Controller Board@8_4" -> "Primary Interface@12_8"; 75 | "Controller Board@8_4" -> "Secondary Interface@13_8"; 76 | "Controller Board@8_4" -> "WiFi Frequency@14_8"; 77 | "Controller Board@8_4" -> "WiFi Protocol@15_8"; 78 | "Controller Board@8_4" -> "Bluetooth Capable@16_8"; 79 | "Raspberry Pi Pico Wireless@19_4" -> "RAM@20_19"; 80 | "Raspberry Pi Pico Wireless@19_4" -> "Bluetooth Capable@21_19"; 81 | "Raspberry Pi Pico Wireless@19_4" -> "Primary Interface@22_19"; 82 | "Raspberry Pi Pico Wireless@19_4" -> "Secondary Interface@23_19"; 83 | "Raspberry Pi Pico Wireless@19_4" -> "WiFi Protocol@24_19"; 84 | "Raspberry Pi Pico Wireless@19_4" -> "WiFi Frequency@25_19"; 85 | "TTRPG eToken System@27_4" -> "controller board@28_27"; 86 | "TTRPG eToken System@27_4" -> "lcd display@29_27"; 87 | "TTRPG eToken System@27_4" -> "battery@30_27"; 88 | "TTRPG eToken System Prototype@31_4" -> "controller board@32_31"; 89 | "TTRPG eToken System Prototype@31_4" -> "lcd display@33_31"; 90 | "Behavior@34_0" -> "User@35_34"; 91 | "Behavior@34_0" -> "Change displayed image on eToken@36_34"; 92 | "Behavior@34_0" -> "Remove existing image form eToken@40_34"; 93 | "Behavior@34_0" -> "Load new image to eToken@44_34"; 94 | "Behavior@34_0" -> "Use eToken as game piece@48_34"; 95 | "Change displayed image on eToken@36_34" -> "user@37_36"; 96 | "Change displayed image on eToken@36_34" -> "PySysML2_GENERATED_NAME_38_36@38_36"; 97 | "PySysML2_GENERATED_NAME_38_36@38_36" -> "PySysML2_GENERATED_NAME_39_38@39_38"; 98 | "Remove existing image form eToken@40_34" -> "PySysML2_GENERATED_NAME_41_40@41_40"; 99 | "Remove existing image form eToken@40_34" -> "user@43_40"; 100 | "PySysML2_GENERATED_NAME_41_40@41_40" -> "PySysML2_GENERATED_NAME_42_41@42_41"; 101 | "Load new image to eToken@44_34" -> "PySysML2_GENERATED_NAME_45_44@45_44"; 102 | "Load new image to eToken@44_34" -> "user@47_44"; 103 | "PySysML2_GENERATED_NAME_45_44@45_44" -> "PySysML2_GENERATED_NAME_46_45@46_45"; 104 | "Use eToken as game piece@48_34" -> "PySysML2_GENERATED_NAME_49_48@49_48"; 105 | "Use eToken as game piece@48_34" -> "user@51_48"; 106 | "PySysML2_GENERATED_NAME_49_48@49_48" -> "PySysML2_GENERATED_NAME_50_49@50_49"; 107 | } 108 | -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/modeling/data/expect/output/model_1.png -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_1.txt: -------------------------------------------------------------------------------- 1 | [root]: 2 | └── [0]: Model@0_None 3 | ├── [1]: PySysML2_GENERATED_NAME_1_0@1_0 4 | ├── [2]: PySysML2_GENERATED_NAME_2_0@2_0 5 | ├── [3]: Comment_1@3_0 6 | ├── [4]: Structure@4_0 7 | │ ├── [5]: WiFi Card@5_4 8 | │ ├── [6]: Bluetooth Card@6_4 9 | │ ├── [7]: Icon@7_4 10 | │ ├── [8]: Controller Board@8_4 11 | │ │ ├── [9]: wifi card@9_8 12 | │ │ ├── [10]: bluetooth card@10_8 13 | │ │ ├── [11]: RAM@11_8 14 | │ │ ├── [12]: Primary Interface@12_8 15 | │ │ ├── [13]: Secondary Interface@13_8 16 | │ │ ├── [14]: WiFi Frequency@14_8 17 | │ │ ├── [15]: WiFi Protocol@15_8 18 | │ │ └── [16]: Bluetooth Capable@16_8 19 | │ ├── [17]: LCD Display@17_4 20 | │ ├── [18]: Battery@18_4 21 | │ ├── [19]: Raspberry Pi Pico Wireless@19_4 22 | │ │ ├── [20]: RAM@20_19 23 | │ │ ├── [21]: Bluetooth Capable@21_19 24 | │ │ ├── [22]: Primary Interface@22_19 25 | │ │ ├── [23]: Secondary Interface@23_19 26 | │ │ ├── [24]: WiFi Protocol@24_19 27 | │ │ └── [25]: WiFi Frequency@25_19 28 | │ ├── [26]: Bicool Round LCD IPS Display GC9A01@26_4 29 | │ ├── [27]: TTRPG eToken System@27_4 30 | │ │ ├── [28]: controller board@28_27 31 | │ │ ├── [29]: lcd display@29_27 32 | │ │ └── [30]: battery@30_27 33 | │ └── [31]: TTRPG eToken System Prototype@31_4 34 | │ ├── [32]: controller board@32_31 35 | │ └── [33]: lcd display@33_31 36 | └── [34]: Behavior@34_0 37 | ├── [35]: User@35_34 38 | ├── [36]: Change displayed image on eToken@36_34 39 | │ ├── [37]: user@37_36 40 | │ └── [38]: PySysML2_GENERATED_NAME_38_36@38_36 41 | │ └── [39]: PySysML2_GENERATED_NAME_39_38@39_38 42 | ├── [40]: Remove existing image form eToken@40_34 43 | │ ├── [41]: PySysML2_GENERATED_NAME_41_40@41_40 44 | │ │ └── [42]: PySysML2_GENERATED_NAME_42_41@42_41 45 | │ └── [43]: user@43_40 46 | ├── [44]: Load new image to eToken@44_34 47 | │ ├── [45]: PySysML2_GENERATED_NAME_45_44@45_44 48 | │ │ └── [46]: PySysML2_GENERATED_NAME_46_45@46_45 49 | │ └── [47]: user@47_44 50 | └── [48]: Use eToken as game piece@48_34 51 | ├── [49]: PySysML2_GENERATED_NAME_49_48@49_48 52 | │ └── [50]: PySysML2_GENERATED_NAME_50_49@50_49 53 | └── [51]: user@51_48 54 | -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/modeling/data/expect/output/model_1.xlsx -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_2.dot: -------------------------------------------------------------------------------- 1 | digraph tree { 2 | "root"; 3 | "ISQ@0_None"; 4 | "ISQSpaceTime@1_None"; 5 | "ScalarValues@2_None"; 6 | "TTRPGeToken@3_None"; 7 | "overview@4_3"; 8 | "PySysML2_GENERATED_NAME_5_3@5_3"; 9 | "PySysML2_GENERATED_NAME_6_3@6_3"; 10 | "RevComment_1@7_3"; 11 | "Structure@8_3"; 12 | "overview@9_8"; 13 | "WiFi Component@10_8"; 14 | "Bluetooth Component@11_8"; 15 | "Integrated Wireless Chip@12_8"; 16 | "name@13_12"; 17 | "wifiComponent@14_12"; 18 | "WiFi Frequency@15_14"; 19 | "WiFi Protocol@16_14"; 20 | "btComponent@17_12"; 21 | "Bluetooth Protocol@18_17"; 22 | "Controller Board@19_8"; 23 | "wChip@20_19"; 24 | "RAM_kb@21_19"; 25 | "Primary Interface@22_19"; 26 | "Secondary Interface@23_19"; 27 | "Bluetooth Capable@24_19"; 28 | "LCD Display@25_8"; 29 | "Battery@26_8"; 30 | "isRechargeable@27_26"; 31 | "Battery Type@28_26"; 32 | "name@29_26"; 33 | "avg_voltage_V@30_26"; 34 | "avg_capacity_mAh@31_26"; 35 | "Raspberry Pi Pico Wireless@32_8"; 36 | "info@33_32"; 37 | "wChip_PiPicoW@34_32"; 38 | "name@35_34"; 39 | "wifiComponet_PiPicoW@36_34"; 40 | "WiFi Frequency@37_36"; 41 | "WiFi Protocol@38_36"; 42 | "btComponet_PiPicoW@39_34"; 43 | "Bluetooth Protocol@40_39"; 44 | "RAM_kb@41_32"; 45 | "Bluetooth Capable@42_32"; 46 | "Primary Interface@43_32"; 47 | "Secondary Interface@44_32"; 48 | "AA Battery Duracell Quantum@45_8"; 49 | "isRechargeable@46_45"; 50 | "Battery Type@47_45"; 51 | "name@48_45"; 52 | "avg_voltage_V@49_45"; 53 | "avg_capacity_mAh@50_45"; 54 | "Bicool Round LCD IPS Display GC9A01@51_8"; 55 | "TTRPG eToken System@52_8"; 56 | "controller board@53_52"; 57 | "lcd display@54_52"; 58 | "battery@55_52"; 59 | "TTRPG eToken System Prototype@56_8"; 60 | "controller board@57_56"; 61 | "lcd display@58_56"; 62 | "battery@59_56"; 63 | "Behavior@60_3"; 64 | "User@61_60"; 65 | "Change displayed image on eToken@62_60"; 66 | "user@63_62"; 67 | "PySysML2_GENERATED_NAME_64_62@64_62"; 68 | "PySysML2_GENERATED_NAME_65_64@65_64"; 69 | "Remove existing image form eToken@66_60"; 70 | "PySysML2_GENERATED_NAME_67_66@67_66"; 71 | "PySysML2_GENERATED_NAME_68_67@68_67"; 72 | "user@69_66"; 73 | "Load new image to eToken@70_60"; 74 | "PySysML2_GENERATED_NAME_71_70@71_70"; 75 | "PySysML2_GENERATED_NAME_72_71@72_71"; 76 | "user@73_70"; 77 | "Use eToken as game piece@74_60"; 78 | "PySysML2_GENERATED_NAME_75_74@75_74"; 79 | "PySysML2_GENERATED_NAME_76_75@76_75"; 80 | "user@77_74"; 81 | "root" -> "ISQ@0_None"; 82 | "root" -> "ISQSpaceTime@1_None"; 83 | "root" -> "ScalarValues@2_None"; 84 | "root" -> "TTRPGeToken@3_None"; 85 | "TTRPGeToken@3_None" -> "overview@4_3"; 86 | "TTRPGeToken@3_None" -> "PySysML2_GENERATED_NAME_5_3@5_3"; 87 | "TTRPGeToken@3_None" -> "PySysML2_GENERATED_NAME_6_3@6_3"; 88 | "TTRPGeToken@3_None" -> "RevComment_1@7_3"; 89 | "TTRPGeToken@3_None" -> "Structure@8_3"; 90 | "TTRPGeToken@3_None" -> "Behavior@60_3"; 91 | "Structure@8_3" -> "overview@9_8"; 92 | "Structure@8_3" -> "WiFi Component@10_8"; 93 | "Structure@8_3" -> "Bluetooth Component@11_8"; 94 | "Structure@8_3" -> "Integrated Wireless Chip@12_8"; 95 | "Structure@8_3" -> "Controller Board@19_8"; 96 | "Structure@8_3" -> "LCD Display@25_8"; 97 | "Structure@8_3" -> "Battery@26_8"; 98 | "Structure@8_3" -> "Raspberry Pi Pico Wireless@32_8"; 99 | "Structure@8_3" -> "AA Battery Duracell Quantum@45_8"; 100 | "Structure@8_3" -> "Bicool Round LCD IPS Display GC9A01@51_8"; 101 | "Structure@8_3" -> "TTRPG eToken System@52_8"; 102 | "Structure@8_3" -> "TTRPG eToken System Prototype@56_8"; 103 | "Integrated Wireless Chip@12_8" -> "name@13_12"; 104 | "Integrated Wireless Chip@12_8" -> "wifiComponent@14_12"; 105 | "Integrated Wireless Chip@12_8" -> "btComponent@17_12"; 106 | "wifiComponent@14_12" -> "WiFi Frequency@15_14"; 107 | "wifiComponent@14_12" -> "WiFi Protocol@16_14"; 108 | "btComponent@17_12" -> "Bluetooth Protocol@18_17"; 109 | "Controller Board@19_8" -> "wChip@20_19"; 110 | "Controller Board@19_8" -> "RAM_kb@21_19"; 111 | "Controller Board@19_8" -> "Primary Interface@22_19"; 112 | "Controller Board@19_8" -> "Secondary Interface@23_19"; 113 | "Controller Board@19_8" -> "Bluetooth Capable@24_19"; 114 | "Battery@26_8" -> "isRechargeable@27_26"; 115 | "Battery@26_8" -> "Battery Type@28_26"; 116 | "Battery@26_8" -> "name@29_26"; 117 | "Battery@26_8" -> "avg_voltage_V@30_26"; 118 | "Battery@26_8" -> "avg_capacity_mAh@31_26"; 119 | "Raspberry Pi Pico Wireless@32_8" -> "info@33_32"; 120 | "Raspberry Pi Pico Wireless@32_8" -> "wChip_PiPicoW@34_32"; 121 | "Raspberry Pi Pico Wireless@32_8" -> "RAM_kb@41_32"; 122 | "Raspberry Pi Pico Wireless@32_8" -> "Bluetooth Capable@42_32"; 123 | "Raspberry Pi Pico Wireless@32_8" -> "Primary Interface@43_32"; 124 | "Raspberry Pi Pico Wireless@32_8" -> "Secondary Interface@44_32"; 125 | "wChip_PiPicoW@34_32" -> "name@35_34"; 126 | "wChip_PiPicoW@34_32" -> "wifiComponet_PiPicoW@36_34"; 127 | "wChip_PiPicoW@34_32" -> "btComponet_PiPicoW@39_34"; 128 | "wifiComponet_PiPicoW@36_34" -> "WiFi Frequency@37_36"; 129 | "wifiComponet_PiPicoW@36_34" -> "WiFi Protocol@38_36"; 130 | "btComponet_PiPicoW@39_34" -> "Bluetooth Protocol@40_39"; 131 | "AA Battery Duracell Quantum@45_8" -> "isRechargeable@46_45"; 132 | "AA Battery Duracell Quantum@45_8" -> "Battery Type@47_45"; 133 | "AA Battery Duracell Quantum@45_8" -> "name@48_45"; 134 | "AA Battery Duracell Quantum@45_8" -> "avg_voltage_V@49_45"; 135 | "AA Battery Duracell Quantum@45_8" -> "avg_capacity_mAh@50_45"; 136 | "TTRPG eToken System@52_8" -> "controller board@53_52"; 137 | "TTRPG eToken System@52_8" -> "lcd display@54_52"; 138 | "TTRPG eToken System@52_8" -> "battery@55_52"; 139 | "TTRPG eToken System Prototype@56_8" -> "controller board@57_56"; 140 | "TTRPG eToken System Prototype@56_8" -> "lcd display@58_56"; 141 | "TTRPG eToken System Prototype@56_8" -> "battery@59_56"; 142 | "Behavior@60_3" -> "User@61_60"; 143 | "Behavior@60_3" -> "Change displayed image on eToken@62_60"; 144 | "Behavior@60_3" -> "Remove existing image form eToken@66_60"; 145 | "Behavior@60_3" -> "Load new image to eToken@70_60"; 146 | "Behavior@60_3" -> "Use eToken as game piece@74_60"; 147 | "Change displayed image on eToken@62_60" -> "user@63_62"; 148 | "Change displayed image on eToken@62_60" -> "PySysML2_GENERATED_NAME_64_62@64_62"; 149 | "PySysML2_GENERATED_NAME_64_62@64_62" -> "PySysML2_GENERATED_NAME_65_64@65_64"; 150 | "Remove existing image form eToken@66_60" -> "PySysML2_GENERATED_NAME_67_66@67_66"; 151 | "Remove existing image form eToken@66_60" -> "user@69_66"; 152 | "PySysML2_GENERATED_NAME_67_66@67_66" -> "PySysML2_GENERATED_NAME_68_67@68_67"; 153 | "Load new image to eToken@70_60" -> "PySysML2_GENERATED_NAME_71_70@71_70"; 154 | "Load new image to eToken@70_60" -> "user@73_70"; 155 | "PySysML2_GENERATED_NAME_71_70@71_70" -> "PySysML2_GENERATED_NAME_72_71@72_71"; 156 | "Use eToken as game piece@74_60" -> "PySysML2_GENERATED_NAME_75_74@75_74"; 157 | "Use eToken as game piece@74_60" -> "user@77_74"; 158 | "PySysML2_GENERATED_NAME_75_74@75_74" -> "PySysML2_GENERATED_NAME_76_75@76_75"; 159 | } 160 | -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/modeling/data/expect/output/model_2.png -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_2.txt: -------------------------------------------------------------------------------- 1 | [root]: 2 | ├── [0]: ISQ@0_None 3 | ├── [1]: ISQSpaceTime@1_None 4 | ├── [2]: ScalarValues@2_None 5 | └── [3]: TTRPGeToken@3_None 6 | ├── [4]: overview@4_3 7 | ├── [5]: PySysML2_GENERATED_NAME_5_3@5_3 8 | ├── [6]: PySysML2_GENERATED_NAME_6_3@6_3 9 | ├── [7]: RevComment_1@7_3 10 | ├── [8]: Structure@8_3 11 | │ ├── [9]: overview@9_8 12 | │ ├── [10]: WiFi Component@10_8 13 | │ ├── [11]: Bluetooth Component@11_8 14 | │ ├── [12]: Integrated Wireless Chip@12_8 15 | │ │ ├── [13]: name@13_12 16 | │ │ ├── [14]: wifiComponent@14_12 17 | │ │ │ ├── [15]: WiFi Frequency@15_14 18 | │ │ │ └── [16]: WiFi Protocol@16_14 19 | │ │ └── [17]: btComponent@17_12 20 | │ │ └── [18]: Bluetooth Protocol@18_17 21 | │ ├── [19]: Controller Board@19_8 22 | │ │ ├── [20]: wChip@20_19 23 | │ │ ├── [21]: RAM_kb@21_19 24 | │ │ ├── [22]: Primary Interface@22_19 25 | │ │ ├── [23]: Secondary Interface@23_19 26 | │ │ └── [24]: Bluetooth Capable@24_19 27 | │ ├── [25]: LCD Display@25_8 28 | │ ├── [26]: Battery@26_8 29 | │ │ ├── [27]: isRechargeable@27_26 30 | │ │ ├── [28]: Battery Type@28_26 31 | │ │ ├── [29]: name@29_26 32 | │ │ ├── [30]: avg_voltage_V@30_26 33 | │ │ └── [31]: avg_capacity_mAh@31_26 34 | │ ├── [32]: Raspberry Pi Pico Wireless@32_8 35 | │ │ ├── [33]: info@33_32 36 | │ │ ├── [34]: wChip_PiPicoW@34_32 37 | │ │ │ ├── [35]: name@35_34 38 | │ │ │ ├── [36]: wifiComponet_PiPicoW@36_34 39 | │ │ │ │ ├── [37]: WiFi Frequency@37_36 40 | │ │ │ │ └── [38]: WiFi Protocol@38_36 41 | │ │ │ └── [39]: btComponet_PiPicoW@39_34 42 | │ │ │ └── [40]: Bluetooth Protocol@40_39 43 | │ │ ├── [41]: RAM_kb@41_32 44 | │ │ ├── [42]: Bluetooth Capable@42_32 45 | │ │ ├── [43]: Primary Interface@43_32 46 | │ │ └── [44]: Secondary Interface@44_32 47 | │ ├── [45]: AA Battery Duracell Quantum@45_8 48 | │ │ ├── [46]: isRechargeable@46_45 49 | │ │ ├── [47]: Battery Type@47_45 50 | │ │ ├── [48]: name@48_45 51 | │ │ ├── [49]: avg_voltage_V@49_45 52 | │ │ └── [50]: avg_capacity_mAh@50_45 53 | │ ├── [51]: Bicool Round LCD IPS Display GC9A01@51_8 54 | │ ├── [52]: TTRPG eToken System@52_8 55 | │ │ ├── [53]: controller board@53_52 56 | │ │ ├── [54]: lcd display@54_52 57 | │ │ └── [55]: battery@55_52 58 | │ └── [56]: TTRPG eToken System Prototype@56_8 59 | │ ├── [57]: controller board@57_56 60 | │ ├── [58]: lcd display@58_56 61 | │ └── [59]: battery@59_56 62 | └── [60]: Behavior@60_3 63 | ├── [61]: User@61_60 64 | ├── [62]: Change displayed image on eToken@62_60 65 | │ ├── [63]: user@63_62 66 | │ └── [64]: PySysML2_GENERATED_NAME_64_62@64_62 67 | │ └── [65]: PySysML2_GENERATED_NAME_65_64@65_64 68 | ├── [66]: Remove existing image form eToken@66_60 69 | │ ├── [67]: PySysML2_GENERATED_NAME_67_66@67_66 70 | │ │ └── [68]: PySysML2_GENERATED_NAME_68_67@68_67 71 | │ └── [69]: user@69_66 72 | ├── [70]: Load new image to eToken@70_60 73 | │ ├── [71]: PySysML2_GENERATED_NAME_71_70@71_70 74 | │ │ └── [72]: PySysML2_GENERATED_NAME_72_71@72_71 75 | │ └── [73]: user@73_70 76 | └── [74]: Use eToken as game piece@74_60 77 | ├── [75]: PySysML2_GENERATED_NAME_75_74@75_74 78 | │ └── [76]: PySysML2_GENERATED_NAME_76_75@76_75 79 | └── [77]: user@77_74 80 | -------------------------------------------------------------------------------- /tests/modeling/data/expect/output/model_2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DAF-Digital-Transformation-Office/PySysML2/6dfaf83ebe8abe2c988a178e105e73c7e9c56fdf/tests/modeling/data/expect/output/model_2.xlsx -------------------------------------------------------------------------------- /tests/modeling/data/models/model_1.sysml2: -------------------------------------------------------------------------------- 1 | package Model{ 2 | doc /* This is the documentation for the Model package*/ 3 | /* This is a comment */ 4 | // This is a note 1 5 | comment Comment_1 /* This is a named comment */ 6 | package Structure{ 7 | 8 | part def 'WiFi Card' {} // This is a note 2 9 | part def 'Bluetooth Card' {} 10 | part def 'Icon'; 11 | part def 'Controller Board' { 12 | part 'wifi card' : 'WiFi Card' [1..2]; 13 | part 'bluetooth card' : 'Bluetooth Card'; 14 | attribute 'RAM' : Integer; 15 | attribute 'Primary Interface' : String; 16 | attribute 'Secondary Interface' : String; 17 | attribute 'WiFi Frequency' : Real; 18 | attribute 'WiFi Protocol' : String; 19 | attribute 'Bluetooth Capable' : Boolean; 20 | // This is a note 3 21 | } 22 | part def 'LCD Display' {} 23 | part def 'Battery' {// This is a note 4 24 | } 25 | part def 'Raspberry Pi Pico Wireless' specializes 'Controller Board' { 26 | attribute redefines 'RAM' = 264; 27 | attribute redefines 'Bluetooth Capable' = false; 28 | attribute redefines 'Primary Interface' = "USB 1.1"; 29 | attribute redefines 'Secondary Interface' = "SPI"; 30 | attribute redefines 'WiFi Protocol' = "Wireless (802.11n)"; 31 | attribute redefines 'WiFi Frequency' = 2.4; // Another note 4 32 | // Another note 5 33 | } 34 | part def 'Bicool Round LCD IPS Display GC9A01' specializes 'LCD Display' {} 35 | 36 | part def 'TTRPG eToken System' { 37 | part 'controller board' : 'Controller Board'; 38 | part 'lcd display' : 'LCD Display'; 39 | part 'battery' : 'Battery'; 40 | } 41 | part def 'TTRPG eToken System Prototype' { 42 | part 'controller board' : 'Raspberry Pi Pico Wireless'; 43 | part 'lcd display' : 'Bicool Round LCD IPS Display GC9A01'; 44 | } 45 | } 46 | package Behavior{ 47 | 48 | part def 'User' {} 49 | use case def 'Change displayed image on eToken'{ 50 | actor 'user' : 'User'; 51 | objective { 52 | doc /*The user changes the displayed image on the eToken to one that is currently stored in storage*/ 53 | } 54 | } 55 | use case def 'Remove existing image form eToken'{ 56 | objective { 57 | doc /*The user deletes an image from the eToken currently stored in storage*/ 58 | } 59 | actor 'user' : 'User'; 60 | } 61 | use case def 'Load new image to eToken'{ 62 | objective { 63 | doc /*The user uploads a new image to the eToken's storage*/ 64 | } 65 | actor 'user' : 'User'; 66 | } 67 | use case def 'Use eToken as game piece'{ 68 | objective { 69 | doc /*The user places the eToken on the board to use as a game piece*/ 70 | } 71 | actor 'user' : 'User'; 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /tests/modeling/data/models/model_2.sysml2: -------------------------------------------------------------------------------- 1 | // Be aware that anything after double forward slash on a single line is completely ignored and not part of the model. [1]: pg 16 2 | // My convention will be to annotate features of the SysML2 language with notes, along with references. 3 | // I will also include meta commentary on the PySysML2 reader in notes. 4 | 5 | // References ------------------------------------------------------------------------------------------------------------------------------------------------ 6 | // [1]: Intro to the SysML v2 Language-Textual Notation.pdf (https://github.com/Systems-Modeling/SysML-v2-Release/tree/master/doc) 7 | 8 | import ISQ::*; 9 | import ISQSpaceTime; 10 | import ScalarValues::*; 11 | 12 | package TTRPGeToken{ 13 | // These are examples of documentation style comments, regular comments, both named and unamed, along with Notes. 14 | // Be aware that any comment style text NOT blocked by double slashes is actually part of the model. [1]: pg 16 15 | // This is an example of a named documentation. [1]: pg 16 16 | doc overview /* The TTRPGeToken is a device used for displaying NPC/PC avatars in a physical token that can be used in a Table Top RPG game. */ 17 | 18 | // This is an example of unnamed documentation. [1]: pg 16 19 | doc /* TODO: include links to remotely hosted images */ 20 | 21 | doc // This is an exmple of an element ignoring whitespace and using a Note as an inline comment 22 | /* TODO: include links to public facing documentation */ 23 | 24 | // Named comment example. Also demonstrating carriage reteruns in comments. [1]: pg 16 25 | comment RevComment_1 /* TO: Maatlock: Please evaluate your vigorous use of commenting in the TTRPGeToken model. 26 | * Comment variety in the language seems... excessive. Don't get carried away! 27 | */ 28 | package Structure{ 29 | 30 | doc overview /* The structure package will contain all structural elements of the model */ 31 | 32 | // Note here that another doc comment named 'overview' has been created. These have unique names in the background, but 33 | // PySysML will have to replicate this behavior through implementation of fully qualified names, uids, auto-generated names 34 | // for unnamed elements 35 | 36 | // This is an example of composite structures, [1] pg. 16 37 | part def 'WiFi Component'; 38 | part def 'Bluetooth Component'; 39 | part def 'Integrated Wireless Chip' { 40 | attribute name : String; 41 | part wifiComponent : 'WiFi Component' { 42 | attribute 'WiFi Frequency' : Real; 43 | attribute 'WiFi Protocol' : String; 44 | } 45 | part btComponent : 'Bluetooth Component'{ 46 | attribute 'Bluetooth Protocol' : String; 47 | } 48 | } 49 | part def 'Controller Board' { 50 | 51 | part def 'wChip' specializes 'Integrated Wireless Chip'; 52 | attribute 'RAM_kb' : Integer; 53 | attribute 'Primary Interface' : String; 54 | attribute 'Secondary Interface' : String; 55 | attribute 'Bluetooth Capable' : Boolean; 56 | 57 | } 58 | part def 'LCD Display' {} 59 | part def 'Battery' { 60 | 61 | attribute isRechargeable : Boolean; 62 | attribute 'Battery Type' : String; 63 | attribute name : String; 64 | attribute avg_voltage_V : Real; 65 | attribute avg_capacity_mAh : Real; 66 | } 67 | part def 'Raspberry Pi Pico Wireless' specializes 'Controller Board' { 68 | doc info /*https://en.wikipedia.org/wiki/Raspberry_Pi*/ 69 | part def wChip_PiPicoW :> wChip{ 70 | attribute redefines name : String = "Infineon CYW43439"; 71 | part wifiComponet_PiPicoW :> wifiComponent{ 72 | attribute redefines 'WiFi Frequency': Real = 2.4; 73 | attribute :> 'WiFi Protocol': String = "IEEE 802.11 b/g/n wireless LAN"; 74 | } 75 | part btComponet_PiPicoW :> btComponent{ 76 | attribute redefines 'Bluetooth Protocol' : String = "Bluetooth 5.2"; 77 | } 78 | } 79 | attribute :> 'RAM_kb' = 264; 80 | attribute :> 'Bluetooth Capable' = true; 81 | attribute :> 'Primary Interface' = "USB 1.1"; 82 | attribute redefines 'Secondary Interface' = "SPI"; 83 | } 84 | 85 | part def 'AA Battery Duracell Quantum' specializes 'Battery' { 86 | attribute :> isRechargeable : Boolean = false; 87 | attribute :> 'Battery Type' : String = "AA"; 88 | attribute :> name : String = "Duracell Quantum"; 89 | attribute :> avg_voltage_V : Real = 1.5; 90 | attribute :> avg_capacity_mAh : Real = 2350.0; 91 | } 92 | // Specialize using the "subset" symbol 93 | part def 'Bicool Round LCD IPS Display GC9A01' :> 'LCD Display' {} 94 | 95 | part def 'TTRPG eToken System' { 96 | part 'controller board' : 'Controller Board'; 97 | part 'lcd display' : 'LCD Display'; 98 | part 'battery' : 'Battery'[1..2]; 99 | } 100 | part def 'TTRPG eToken System Prototype' { 101 | part 'controller board' : 'Raspberry Pi Pico Wireless'; 102 | part 'lcd display' : 'Bicool Round LCD IPS Display GC9A01'; 103 | part 'battery' : 'AA Battery Duracell Quantum'; 104 | } 105 | } 106 | package Behavior{ 107 | 108 | part def 'User' {} 109 | use case def 'Change displayed image on eToken'{ 110 | actor 'user' : 'User'; 111 | objective { 112 | doc /*The user changes the displayed image on the eToken to one that is currently stored in storage*/ 113 | } 114 | } 115 | use case def 'Remove existing image form eToken'{ 116 | objective { 117 | doc /*The user deletes an image from the eToken currently stored in storage*/ 118 | } 119 | actor 'user' : 'User'; 120 | } 121 | use case def 'Load new image to eToken'{ 122 | objective { 123 | doc /*The user uploads a new image to the eToken's storage*/ 124 | } 125 | actor 'user' : 'User'; 126 | } 127 | use case def 'Use eToken as game piece'{ 128 | objective { 129 | doc /*The user places the eToken on the board to use as a game piece*/ 130 | } 131 | actor 'user' : 'User'; 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /tests/modeling/test_model.py: -------------------------------------------------------------------------------- 1 | import json 2 | from pathlib import Path 3 | 4 | import pytest 5 | import pandas as pd 6 | 7 | from pysysml2.modeling.model import Model 8 | 9 | from ..utils import ( 10 | assert_dicts_equal, 11 | assert_dataframes_equal, 12 | requires_graphviz, 13 | requires_openpyxl, 14 | ) 15 | 16 | 17 | def assert_model_output_json_equal(output_path: Path, expect_path: Path): 18 | assert output_path.exists() 19 | 20 | with open(output_path) as f: 21 | output_data = json.load(f) 22 | with open(expect_path) as f: 23 | expect_data = json.load(f) 24 | 25 | assert_dicts_equal( 26 | output_data, expect_data, ignore_keys=("uuid", "uuid_parent", "input_file") 27 | ) 28 | 29 | 30 | def assert_model_output_csv_equal(output_path: Path, expect_path: Path): 31 | assert output_path.exists() 32 | 33 | output_df = pd.read_csv(output_path) 34 | expect_df = pd.read_csv(expect_path) 35 | 36 | assert_dataframes_equal( 37 | output_df, expect_df, ignore_columns=("uuid", "uuid_parent", "parent") 38 | ) 39 | 40 | 41 | def assert_model_output_txt_equal(output_path: Path, expect_path: Path): 42 | assert output_path.exists() 43 | 44 | output_txt = output_path.read_text() 45 | expect_txt = expect_path.read_text() 46 | 47 | assert output_txt == expect_txt 48 | 49 | 50 | def assert_model_output_excel_equal(output_path: Path, expect_path: Path): 51 | assert output_path.exists() 52 | 53 | output_df = pd.read_excel(output_path) 54 | expect_df = pd.read_excel(expect_path) 55 | 56 | assert_dataframes_equal( 57 | output_df, expect_df, ignore_columns=("uuid", "uuid_parent", "parent") 58 | ) 59 | 60 | 61 | @pytest.fixture 62 | def expect_datadir(shared_datadir: Path): 63 | return shared_datadir / "expect" / "output" 64 | 65 | 66 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 67 | def test_model1_load(model_name: str, shared_datadir: Path): 68 | 69 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 70 | model = Model() 71 | model.from_sysml2_file(str(model_path)) 72 | 73 | # TODO: asserts 74 | 75 | 76 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 77 | def test_model_to_json(model_name: str, shared_datadir: Path, output_datadir: Path): 78 | 79 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 80 | model = Model() 81 | model.from_sysml2_file(str(model_path)) 82 | model.to_JSON(output_datadir) 83 | 84 | output_name = f"{model_name}.json" 85 | expect_datadir = shared_datadir / "expect" / "output" 86 | expect_path = expect_datadir / output_name 87 | output_path = output_datadir / output_name 88 | assert_model_output_json_equal(output_path, expect_path) 89 | 90 | 91 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 92 | def test_model_to_csv(model_name: str, shared_datadir: Path, output_datadir: Path): 93 | 94 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 95 | model = Model() 96 | model.from_sysml2_file(str(model_path)) 97 | model.to_csv(output_datadir) 98 | 99 | output_name = f"{model_name}.csv" 100 | expect_datadir = shared_datadir / "expect" / "output" 101 | expect_path = expect_datadir / output_name 102 | output_path = output_datadir / output_name 103 | assert_model_output_csv_equal(output_path, expect_path) 104 | 105 | 106 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 107 | def test_model_to_txt(model_name: str, shared_datadir: Path, output_datadir: Path): 108 | 109 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 110 | model = Model() 111 | model.from_sysml2_file(str(model_path)) 112 | model.to_txt(output_datadir) 113 | 114 | output_name = f"{model_name}.txt" 115 | expect_datadir = shared_datadir / "expect" / "output" 116 | expect_path = expect_datadir / output_name 117 | output_path = output_datadir / output_name 118 | assert_model_output_txt_equal(output_path, expect_path) 119 | 120 | 121 | @requires_openpyxl 122 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 123 | def test_model_to_excel(model_name: str, shared_datadir: Path, output_datadir: Path): 124 | 125 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 126 | model = Model() 127 | model.from_sysml2_file(str(model_path)) 128 | model.to_excel(output_datadir) 129 | 130 | output_name = f"{model_name}.xlsx" 131 | expect_datadir = shared_datadir / "expect" / "output" 132 | expect_path = expect_datadir / output_name 133 | output_path = output_datadir / output_name 134 | assert_model_output_excel_equal(output_path, expect_path) 135 | 136 | 137 | @requires_graphviz(python_only=True) 138 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 139 | def test_model_to_dot(model_name: str, shared_datadir: Path, output_datadir: Path): 140 | 141 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 142 | model = Model() 143 | model.from_sysml2_file(str(model_path)) 144 | model.to_dot(output_datadir) 145 | 146 | output_name = f"{model_name}.dot" 147 | output_path = output_datadir / output_name 148 | assert output_path 149 | 150 | # TODO: check contents of generated file 151 | 152 | 153 | @requires_graphviz 154 | @pytest.mark.parametrize("model_name", ["model_1", "model_2"]) 155 | def test_model_to_png(model_name: str, shared_datadir: Path, output_datadir: Path): 156 | 157 | model_path = shared_datadir / "models" / f"{model_name}.sysml2" 158 | model = Model() 159 | model.from_sysml2_file(str(model_path)) 160 | model.to_png(output_datadir) 161 | 162 | output_name = f"{model_name}.png" 163 | output_path = output_datadir / output_name 164 | assert output_path 165 | 166 | # TODO: check contents of generated file 167 | -------------------------------------------------------------------------------- /tests/utils.py: -------------------------------------------------------------------------------- 1 | """Testing utilities.""" 2 | 3 | import shutil 4 | import sys 5 | from typing import Callable, Container, Dict, Optional 6 | 7 | import pandas as pd 8 | import pytest 9 | 10 | try: 11 | import openpyxl 12 | except ImportError: 13 | pass 14 | 15 | try: 16 | import graphviz 17 | except ImportError: 18 | pass 19 | 20 | 21 | def requires_openpyxl(f: Callable): 22 | """Decorator that marks a test function to be skipped in openpyxl is not 23 | installed.""" 24 | skipif = pytest.mark.skipif( 25 | "openpyxl" not in sys.modules, reason="requires openpyxl package" 26 | ) 27 | return skipif(f) 28 | 29 | 30 | def requires_graphviz(f: Optional[Callable] = None, python_only: bool = False): 31 | """Decorator that marks a test function to be skipped in graphviz is not 32 | installed.""" 33 | 34 | def _decorator(f: Callable): 35 | graphviz_package_installed = "graphviz" in sys.modules 36 | dot_command_installed = shutil.which("dot") is not None 37 | 38 | if python_only: 39 | skip_condition = not graphviz_package_installed 40 | else: 41 | skip_condition = not (graphviz_package_installed and dot_command_installed) 42 | 43 | if not graphviz_package_installed: 44 | reason = "graphviz package not installed" 45 | elif not dot_command_installed: 46 | reason = "graphviz not installed. `dot` command not found" 47 | else: 48 | reason = None 49 | 50 | skipif = pytest.mark.skipif(skip_condition, reason=reason) 51 | return skipif(f) 52 | 53 | if f is None: 54 | return _decorator 55 | else: 56 | return _decorator(f) 57 | 58 | 59 | def assert_dicts_equal( 60 | dict1: Dict, dict2: Dict, ignore_keys: Optional[Container[str]] = None 61 | ) -> None: 62 | """ 63 | Check two dictionaries recursively for equivalence, optionally ignoring comparison 64 | between values of certain keys. 65 | 66 | Args: 67 | dict1 (dict): First dictionary 68 | dict2 (dict): Second dictionary 69 | ignore_keys (list): List of keys whose values should be ignored during comparison 70 | """ 71 | ignore_keys = ignore_keys or () 72 | 73 | # Check if the keys in both dictionaries match 74 | assert set(dict1.keys()) == set(dict2.keys()) 75 | 76 | # Iterate over the keys in the dictionaries 77 | for key in dict1.keys(): 78 | # Check if the key is in the list of keys to ignore 79 | if key in ignore_keys: 80 | continue 81 | 82 | # Check if the values for the key in both dictionaries are themselves 83 | # dictionaries 84 | if isinstance(dict1[key], dict) and isinstance(dict2[key], dict): 85 | # Recursively check equivalence of the dictionaries 86 | assert_dicts_equal(dict1[key], dict2[key], ignore_keys) 87 | elif isinstance(dict1[key], list) and isinstance(dict2[key], list): 88 | for i in range(len(dict1[key])): 89 | item1 = dict1[key][i] 90 | item2 = dict2[key][i] 91 | 92 | if isinstance(item1, dict) and isinstance(item2, dict): 93 | # Recursively check equivalence of the dictionaries 94 | assert_dicts_equal(item1, item2, ignore_keys) 95 | else: 96 | assert item1 == item2 97 | else: 98 | # Check equivalence of the values for the key in both dictionaries 99 | assert dict1[key] == dict2[key], f"Key: {key}" 100 | 101 | 102 | def assert_dataframes_equal( 103 | df1: pd.DataFrame, 104 | df2: pd.DataFrame, 105 | ignore_columns: Optional[Container[str]] = None, 106 | ) -> None: 107 | """ 108 | Check two dataframes for equivalence, optionally ignoring comparison between certain 109 | columns. 110 | 111 | Args: 112 | dict1 (dict): First dictionary 113 | dict2 (dict): Second dictionary 114 | ignore_columns (list): List of keys whose values should be ignored during comparison 115 | """ 116 | ignore_columns = list(ignore_columns) or [] 117 | 118 | df1 = df1.drop(columns=ignore_columns) 119 | df2 = df2.drop(columns=ignore_columns) 120 | 121 | assert df1.equals(df2) 122 | --------------------------------------------------------------------------------