Skip to content

Latest commit

 

History

History
97 lines (81 loc) · 4.37 KB

Updated Workflow 20240805.md

File metadata and controls

97 lines (81 loc) · 4.37 KB

Workflow for Adding New Syntax Elements

Tips:

  • Don't work with the complicated file directly (or its simplified version)
  • 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
  • I made model_test_3.sysml2 for this purpose
  • Paste in new language elements, get that working, then move on
  • Doing it this way makes it much easier to debug as you're working through Antlr4 grammar and coding

Example One: Keyword "port"

Examples of "port" Usage

Can appear in package or block scope

SysMLv2 Code

  • port 'socket 1';
  • port 'USB-A-Socket'  {
       attribute 'usb_type' : String;
    }
    

ANTLR4 Rules

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.

// An element is anything that can be a part of a model
element : namespace
        | feature 
        | comment 
        | doc
        | statement
        | port
        ;
// A namespace is an element with a scope defined by curly braces
namespace   : sysml2_package 
            | part 
            | use_case_def 
            | comment 
            | doc
            | port
            ;
part_blk: (feature | comment | doc | part | port | connect | connection);  
// Ports
port: (port_def | port_blk);
// e.g. port 'socket 1';
port_def: KW_PORT ID ';' | (KW_PORT ID '{' port_blk* '}');
port_blk: (feature | comment | doc );
KW_PORT: 'port';

Workflow

  1. Update SysML2.g4 (ANTLR4 file)
  2. Run the ANTLR4 command line tool to generate the Python modules in distpy from within the grammar directory
    • Command line args: antlr4 -Dlanguage=Python3 SysML2.g4 -visitor -o distpy
  3. Verify the updated .py files in distpy:
    • Check the date of creation.
    • 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.
  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.
  5. Update Python modules sysml2_model_visitor.py, element.py, model.py:
    • sysml2_model_visitor.py: This extends the SysML2Visitor.py module generated by ANTLR4.
      1. For relationships, specialized code is required... please consult.
      2. Elements are straightforward. Extend the appropriate visitor function, e.g., visitPort_def, which was automatically generated in SysML2Visitor.py:
      # Visit a parse tree produced by SysML2Parser#part_def.
      def visitPort_def(self, ctx: SysML2Parser.Port_defContext):
          setattr(ctx, _SYSML2_TYPE_NAME, _SML2_KWS.KW_PORT.value)
          self._model_table_builder(ctx)
          return self.visitChildren(ctx)
      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).
    • element.py: This implements the concept of an element. Add the appropriate class with code like this:
      class Port(Element, NodeMixin):
          def __init__(self, name=None, parent=None, **kwargs):
              super(Port, self).__init__(name=name, parent=parent, **kwargs)
              self.sysml2_layer = ArchitectureLayers.systems_element.value
    • model.py: This implements the concept of a model as a tree data structure.
      1. Update the import statement, i.e., from pysysml2.modeling.element import (Attribute, Port) etc. Recommend not to import * for readability and maintainability purposes.
      2. Update the elif block in the for loop in from_sysml2_file function, e.g.:
      elif v["sysml2_type"] == smv._SML2_KWS.KW_PORT.value:
          Port(**v)
  6. Run the test and check the resulting table. Debug accordingly.

Example 2: Keywords "connect" and "connection"

TODO: Write updated workflow for relationships.