diff --git a/.gitignore b/.gitignore index fe9a83318..d3f04a5e4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,5 +35,8 @@ dependency-reduced-pom.xml # MacOS Finder .DS_Store +# Generated Python files +*.pyc + # Built libraries *.kpar diff --git a/tool-support/bnf_grammar_tools/.gitignore b/tool-support/bnf_grammar_tools/.gitignore new file mode 100644 index 000000000..ab3023ea6 --- /dev/null +++ b/tool-support/bnf_grammar_tools/.gitignore @@ -0,0 +1,3 @@ +build/ +dist/ +scratch/ diff --git a/tool-support/bnf_grammar_tools/README.adoc b/tool-support/bnf_grammar_tools/README.adoc new file mode 100644 index 000000000..07df928a2 --- /dev/null +++ b/tool-support/bnf_grammar_tools/README.adoc @@ -0,0 +1,192 @@ += bnf_grammar_tools + +Tools that process KerML and SysML2 concrete language grammars from their respective specifications, check them for correctness and generates two kinds of grammar listings: (1) machine-readable plain text BNF files and (2) human-readable hyperlinked BNF files in HTML format. + +== Usage of the Tools + +=== Obtain a Complete KerML or SysML Specification in HTML Source Format + +Instructions on how to export a selected version of the specification from View Editor to a self-standing HTML file. + +> Note: These instructions are tested with View Editor version 4 with the FireFox browser v130.0.1 on Windows 11. In other browsers the menu or key to inspect the source code may be different. + +1. Open the selected spec in View Editor. +2. Load the full document by clicking the "Full Document" icon (image:VE-full-document-icon.png[]) at the top of the left panel. This may take several minutes. +3. Click the print icon, image:VE-print-icon.png[] left next to the EXPORT icon at the top of the document panel. +4. Wait for a new browser tab to appear with the complete HTML document and a popup print dialog. Again, be patient, this may take several minutes. +5. Cancel the popup print dialog. +6. In the complete HTML document tab, open a Developer / Inspector panel via menu *More tools > Web Developer Tools* or by hitting `Ctrl+Shift+I`. (Note: a direct *Save page as ...* or `Ctlr+S` does not work, as it saves a script.) +7. In the Inspector tab of the Developer panel, right-click the top level `` element, and select *Copy > Outer HTML* from the context menu. +8. Open a new, appropriately named `.html` file in a text editor, paste the contents and save. +9. Close the complete HTML document tab. + +=== Install the Python Environment + +Ensure that Python version 3.9 or higher is installed on your machine. The most convenient way is to use the https://www.jetbrains.com/pycharm/[PyCharm] tool. Create a dedicated `conda` or `venv` development environment and activate it. The best tool to install a Python base environment is https://github.com/conda-forge/miniforge[miniforge]. + +After installation check the active Python version, e.g.: + +[source,shell] +---- + $ python --version + Python 3.12.12 +---- + +Also ensure that the latest version of the following packages are installed. You can use `pip` or `conda` or `mamba`. + +* Package https://pypi.org/project/beautifulsoup4/[beautifulsoup4] is used to parse the HTML input file. +* Package https://pypi.org/project/lxml/[lxml] is used to assist beautifulsoup4 with processing SVG/XML files. +* Package https://pypi.org/project/lark/[lark] is used to parse and verify the extracted BNF source. +* Package https://pypi.org/project/pytest/[pytest] is used to run unit tests. + +for example with the following commands: + +[source,shell] +---- + $ pip install beautifulsoup4 + $ pip install lxml + $ pip install lark + $ pip install pytest +---- + +=== Run the bnf_grammar_processor + +The usage info for the `bnf_grammar_processor` is as below, as usual obtained with the `-h` or `--help` option. +Go to the `tool-support/bnf_grammar_tools` directory and run `python .\bnf_grammar\bnf_grammar_processor.py -h`. + +[source,shell] +---- +usage: python bnf_grammar_processor [-h] [-i [INPUT_DIR]] [-o [OUTPUT_DIR]] SOURCE_DATA + +Extract or parse textual and/or graphical grammars from given KerML or SysML specifications and generate plain text and html BNF grammar files. + +positional arguments: + SOURCE_DATA JSON file defining source data - see examples under + the tests directory + +options: + -h, --help show this help message and exit + -i [INPUT_DIR], --input-dir [INPUT_DIR] + input directory path + -o [OUTPUT_DIR], --output-dir [OUTPUT_DIR] + output directory path + +The processor supports to two main capabilities: +1) Extract the KerML or SysML grammar(s) + from provided raw .html file(s) exported from KerML and SysML specifications in the View Editor tool, + and then validate the extracted grammars, report possible errors, and generate these outputs: + - .json dumps of the processed intermediate data model(s), + - .kebnf and/or .kgbnf plain text files, + - -marked_up.kebnf and/or -marked_up.kgbnf marked up text files, that can be used as a basis for corrected grammars, + - .html files with hyperlinked, human-readable versions of the grammars. +2) Validate corrected -marked_up.kebnf or -marked_up.kgbnf input files + and generate the same files as under 1), but now for the corrected grammars. + +Option 2) is selected when the input filename(s) end on '-marked_up.kebnf' or '-marked_up.kgbnf', otherwise option 1). +Both options will produce a log file named 'bnf_grammar_processor.log' in the working directory. +In SOURCE_DATA the input files should be given in reverse dependendy order, i.e., first KerML textual, then SysML textual, then SysML graphical notation. +Via diff'ing of the extracted and corrected .kebnf and/or .kgbnf files a list of corrections to be fed into the OMG issue trackers can be compiled. +---- + +Note. The file extensions `.kebnf` and `.kgbnf` are inspired by the `.kpar` extension for the KerML archive files. + +The BNF grammars are defined in the format of the https://github.com/lark-parser/lark[Lark] parsing toolkit for Python. The definitions are in: + +* `bnf_grammar/kebnf_textual_grammar.lark`, and, +* `bnf_grammar/kgbnf_graphical_grammar.lark`. + +Inside the `bnf_grammar_processer` Lark is used to check each production individually. Some additional heuristic validation is also performed to permit processing of incorrect grammar or note fragments. All diagnostics are reported in the `bnf_grammar_processor.log` file. For the graphical grammar this includes a mapping table between the existing (PNG) images in the specs from the View Editor source and the new SVG images in `images` subdirectory. + +.Example command line arguments +For the time being, example input and output directories with `SOURCE_DATA` files can be found under the `tests` folder. + +For option 1): + +- `INPUT_DIR` = `tests/KerML_and_SysML_spec_sources` +- `OUTPUT-DIR` = `tests/KerML_and_SysML_grammars` +- `SOURCE_DATA` = `source_specs.json` (in `INPUT_DIR`) + +The style information for the generated HTML outputs resides in `tests/KerML_and_SysML_grammars/bnf_styles.css`. + +For option 2): + +- `INPUT_DIR` = `tests/KerML_and_SysML_grammars` +- `OUTPUT-DIR` = `tests/KerML_and_SysML_grammars` +- `SOURCE_DATA` = `source_marked_ups.json` (in `INPUT_DIR`) + +.Example generated outputs for option 1) (extract) +The bnf_grammar_processor with produces the following outputs (see directory `tests/KerML_and_SysML_grammars`): + +[cols="2,3"] +|=== +| `KerML-textual-bnf-elements.json` | dump of the processed intermediate data model(s) +| `KerML-textual-bnf.kebnf` | generated plain text KerML textual grammar file +| `KerML-textual-bnf-marked_up.kebnf` | generated editable marked up KerML textual grammar file +| `KerML-textual-bnf.html` | generated browsable, hyperlinked HTML KerML textual grammar file +| `SysML-textual-bnf-elements.json` | dump of the processed intermediate data model(s) +| `SysML-textual-bnf.kebnf` | generated plain text SysML textual grammar file +| `SysML-textual-bnf-marked_up.kebnf` | generated editable marked up SysML textual grammar file +| `SysML-textual-bnf.html` | generated browsable, hyperlinked HTML SysML textual grammar file +| `SysML-graphical-bnf-elements.json` | dump of the processed intermediate data model(s) +| `SysML-graphical-bnf.kgbnf` | generated plain text SysML graphical grammar file +| `SysML-graphical-bnf-marked_up.kgbnf` | generated editable marked up SysML graphical grammar file +| `SysML-graphical-bnf.html` | generated browsable, hyperlinked HTML SysML graphical grammar file (See Note) +|=== + +Note. The SVG images for the graphical BNF productions reside in `tests/KerML_and_SysML_grammars/images`. They are copied from the source in https://github.com/Systems-Modeling/Graphical-Specification-WG/tree/main/src/Graphical-BNF/_svg[Graphical-Specification-WG github repo]. + +Each run of the `bnf_grammar_processor` produces a log on the console and in file `bnf_grammar_processor.log`. The log of the previous run is saved in `bnf_grammar_processor.log.backup`, which can be used to detect differences between runs. + +=== Correct the Extracted Grammar Files and Reprocess with the bnf_grammar_processor + +If there are errors in the grammar files, the following workflow can be used to apply bulk corrections. + +. Copy `KerML-textual-bnf-marked_up.kebnf` to `KerML-textual-bnf-corrected-marked_up.kebnf` +. Copy `SysML-textual-bnf-marked_up.kebnf` to `SysML-textual-bnf-corrected-marked_up.kebnf` +. Copy `SysML-graphical-bnf-marked_up.kgbnf` to `SysML-graphical-bnf-corrected-marked_up.kgbnf` +. Check the errors in the log files, and modify the `...-corrected-marked_up.k*bnf` files in a text editor to correct the errors. +. After every couple of corrections, run the `bnf_grammar_processor` with the option 2) arguments. This will validate the corrected `.kebnf` and `.kgbnf` and generate the set of files described in the table below, similar to option 1) +. Iterate the steps 4 and 5, until satisfied. +. By making a diff between pairs of original (`...-bnf-marked_up.k*bnf`) and corrected (`...-bnf-corrected-marked_up.k*bnf`) files the required changes to be raised in OMG issues can be systematically compiled. + +.Example generated files for option 2) +[cols="2,3"] +|=== +| `KerML-textual-bnf-corrected-elements.json` | dump of the corrected intermediate data model(s) +| `KerML-textual-bnf-corrected.kebnf` | generated corrected plain text KerML textual grammar file +| `KerML-textual-bnf-corrected.html` | generated corrected browsable, hyperlinked HTML KerML textual grammar file +| `SysML-textual-bnf-corrected-elements.json` | dump of the processed intermediate corrected data model(s) +| `SysML-textual-bnf-corrected.kebnf` | generated corrected plain text SysML textual grammar file +| `SysML-textual-bnf-corrected.html` | generated corrected browsable, hyperlinked HTML SysML textual grammar file +| `SysML-graphical-bnf-corrected-elements.json` | dump of the corrected intermediate data model(s) +| `SysML-graphical-bnf-corrected.kgbnf` | generated corrected plain text SysML graphical grammar file +| `SysML-graphical-bnf-corrected.html` | generated corrected browsable, hyperlinked HTML SysML textual grammar file +|=== + +=== Use the bnf_file_parser for Final Checks + +As a final check the `bnf_file_parser` can be used to validate complete, corrected BNF grammar files. + +The usage info for the `bnf_file_parser` is as below, as usual obtained with the `-h` or `--help` option. +Go to the `tool-support/bnf_grammar_tools` directory and run `python .\bnf_grammar\bnf_file_parser.py -h`. + +[source,shell] +---- +usage: bnf_file_parser [-h] BNF_PATH + +Parse KerML or SysML grammar files in textual or graphical BNF format. + +positional arguments: + BNF_PATH Path to plain text BNF file with extension .kebnf or .kgbnf + +options: + -h, --help show this help message and exit +---- + +Run `bnf_file_parser` on the following files: + +* `KerML-textual-bnf-corrected.kebnf` +* `SysML-textual-bnf-corrected.kebnf` +* `SysML-graphical-bnf-corrected.kgbnf` + +The console and the log file `bnf_file_parser.log` will list any errors still present. Otherwise, if the parse is completely successful, a dump of the resulting abstract syntax tree (in Lark's pretty print format) will be listed. diff --git a/tool-support/bnf_grammar_tools/VE-full-document-icon.png b/tool-support/bnf_grammar_tools/VE-full-document-icon.png new file mode 100644 index 000000000..709493157 Binary files /dev/null and b/tool-support/bnf_grammar_tools/VE-full-document-icon.png differ diff --git a/tool-support/bnf_grammar_tools/VE-print-icon.png b/tool-support/bnf_grammar_tools/VE-print-icon.png new file mode 100644 index 000000000..7089eedd7 Binary files /dev/null and b/tool-support/bnf_grammar_tools/VE-print-icon.png differ diff --git a/tool-support/bnf_grammar_tools/__init__.py b/tool-support/bnf_grammar_tools/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tool-support/bnf_grammar_tools/bnf_file_parser.log b/tool-support/bnf_grammar_tools/bnf_file_parser.log new file mode 100644 index 000000000..e69de29bb diff --git a/tool-support/bnf_grammar_tools/bnf_file_parser.log.backup b/tool-support/bnf_grammar_tools/bnf_file_parser.log.backup new file mode 100644 index 000000000..e69de29bb diff --git a/tool-support/bnf_grammar_tools/bnf_grammar/__init__.py b/tool-support/bnf_grammar_tools/bnf_grammar/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tool-support/bnf_grammar_tools/bnf_grammar/bnf_file_parser.py b/tool-support/bnf_grammar_tools/bnf_grammar/bnf_file_parser.py new file mode 100644 index 000000000..4e8ad4f22 --- /dev/null +++ b/tool-support/bnf_grammar_tools/bnf_grammar/bnf_file_parser.py @@ -0,0 +1,110 @@ +#!python + +""" +bnf_file_parser is a command line tool that parses a KerML or SysML plain text grammar file. + +The supported file formats are: +- .kebnf for a KerML or SysML textual notation grammar +- .kgbnf for a SysML graphical notation grammar + +Its usage is described below in the main() function. + +@author: Hans Peter de Koning (DEKonsult) + +Requirements: + +This tool requires installation of the following packages: +- lark (See https://pypi.org/project/lark) + +""" + +import sys +import os +import shutil +import argparse +from datetime import datetime, timezone +from typing import Optional +from lark import Lark, UnexpectedInput + +# Create logger for debug, info, warning, error, critical messages +import logging +LOGGER = logging.getLogger() + + +class BnfParser: + def __init__(self) -> None: + self.start_timestamp: Optional[datetime] = None + self.bnf_filepath: Optional[str] = None + self.parser: Optional[Lark] = None + + def parse(self, bnf_filepath: str) -> None: + self.start_timestamp = datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + self.bnf_filepath = bnf_filepath + + LOGGER.info(f"Started parsing {self.bnf_filepath} at {self.start_timestamp}") + + basename, ext = os.path.splitext(bnf_filepath) + grammar_file = None + if ext == ".kebnf": + grammar_file = "kebnf_textual_grammar.lark" + elif ext == ".kgbnf": + grammar_file = "kgbnf_graphical_grammar.lark" + else: + LOGGER.critical(f"Unrecognized file extension for BNF_PATH {bnf_filepath}, terminating ...") + sys.exit(1) + + self.parser = Lark.open(grammar_file, rel_to=__file__, parser="lalr") + + bnf_file = open(bnf_filepath, "r", encoding="utf-8") + bnf_input = bnf_file.read() + bnf_file.close() + + try: + parse_tree = self.parser.parse(bnf_input) + except UnexpectedInput as e: + LOGGER.error(f"Parse error in {self.bnf_filepath}:\n{e}") + else: + LOGGER.info(f"Parse completed successfully") + LOGGER.info(f"The resulting (AST) parse tree is:\n\n{parse_tree.pretty()}") + + +def main() -> None: + # Initialize logging + LOGGER.setLevel(logging.DEBUG) + formatter = logging.Formatter("%(levelname)-8s: %(message)s") + + console_handler = logging.StreamHandler() + console_handler.set_name("console") + console_handler.setLevel(logging.INFO) + console_handler.setFormatter(formatter) + LOGGER.addHandler(console_handler) + + log_file_name = "bnf_file_parser.log" + if os.path.exists(log_file_name): + # Create backup copy of the log-file to inspect differences between runs + shutil.copy2(log_file_name, log_file_name + ".backup") + + file_handler = logging.FileHandler(log_file_name, mode="w", encoding="utf-8") + file_handler.set_name("logfile") + file_handler.setLevel(logging.INFO) + file_handler.setFormatter(formatter) + LOGGER.addHandler(file_handler) + + LOGGER.debug(f"bnf_grammar_parser started in {os.getcwd()}") + + # Parse command line + parser = argparse.ArgumentParser( + prog="bnf_file_parser", + allow_abbrev=False, + description="Parse KerML or SysML grammar files in textual or graphical BNF format.") + parser.add_argument("bnf_path", metavar="BNF_PATH", type=str, help="Path to plain text BNF file with extension .kebnf or .kgbnf") + args = parser.parse_args() + LOGGER.debug(f"args={args}") + + # Run the parser + bnf_parser = BnfParser() + bnf_parser.parse(args.bnf_path) + + +if __name__ == "__main__": + main() diff --git a/tool-support/bnf_grammar_tools/bnf_grammar/bnf_grammar_processor.py b/tool-support/bnf_grammar_tools/bnf_grammar/bnf_grammar_processor.py new file mode 100644 index 000000000..27546fcb7 --- /dev/null +++ b/tool-support/bnf_grammar_tools/bnf_grammar/bnf_grammar_processor.py @@ -0,0 +1,1432 @@ +#!python + +""" +bnf_grammar_processor is a command line tool that +1. can extract the textual and graphical BNF grammars from + exports of the KerML and SysML specifications in raw HTML format +2. can parse and validate (manually) corrected BNF grammar files. + +Detailed usage documentation is below in the main() function, +and also be obtained by running the tool with the --help option. + +@author: Hans Peter de Koning (DEKonsult) + +Requirements: +This tool requires Python v3.9 or higher and installation of the following packages: +- beautifulsoup4 (See https://pypi.org/project/beautifulsoup4/) +- lxml (See https://pypi.org/project/lxml/) +- lark (See https://pypi.org/project/lark) +""" + +import os +import shutil +import sys +import json +import re +import argparse +from datetime import datetime, timezone +from dataclasses import dataclass, asdict +from enum import Enum, auto +from logging import Logger +from textwrap import wrap +from typing import Any, ClassVar, Iterable, Optional + +from bs4 import BeautifulSoup, Tag, PageElement + +from lark import Lark, UnexpectedInput + +# Create logger for diagnostic messages at debug, info, warning, error and critical levels +import logging + +LOGGER: Logger = logging.getLogger() + +# Marker denoting start of a line comment in generated output +LINE_COMMENT_MARKER = "//" + +# Images directory to hold SVG images as part of graphical BNF productions +IMAGES_DIR = "images" + +# Scaling factor for right-sizing SVG images in graphical BNF productions +SVG_SCALING_FACTOR = 1.5 + + +class TokenKind(Enum): + TERMINAL = auto() + NON_TERMINAL = auto() + NOTE = auto() + EQUALS = auto() + COLON = auto() + IMAGE = auto() + INTERPUNCTION = auto() + WHITESPACE = auto() + LINE_COMMENT = auto() + + +class RenderMode(Enum): + HTML = auto() + TXT = auto() + +@dataclass +class Token: + kind: TokenKind = None + text: str = "" + + +@dataclass +class ListStackItem: + kind: str = "" + level: int = 0 + item_count: int = 0 + + +@dataclass +class Grammar: + name: str + production_names: set[str] + + +@dataclass +class GrammarElement: + """Abstract superclass for any element of the internal grammar metamodel""" + processor: ClassVar["GrammarProcessor"] + """the activated GrammarProcessor instance""" + clause_id: str + lines: list[str] + + def get_marked_up_txt(self) -> str: + LOGGER.error(f"GrammarElement.get_marked_up_txt() should be overridden in subclass {self.__class__.__name__}, never called.") + return "" + + def get_txt(self) -> str: + LOGGER.error(f"GrammarElement.get_txt() should be overridden in subclass {self.__class__.__name__}, never called.") + return "" + + def get_html(self) -> str: + rendered_lines = "\n".join(self.lines) + return f"
\n{rendered_lines}\n\n\n"
+
+ def get_as_dict(self) -> dict[str, Any]:
+ self_as_dict = asdict(self)
+ self_as_dict["@type"] = self.__class__.__name__
+ return self_as_dict
+
+ @staticmethod
+ def get_safe_anchor_id(candidate_anchor_id: str) -> str:
+ """
+ Return safe anchor id for given candidate string.
+
+ To avoid name collisions between PascalCase and UPPER_SNAKE_CASE identifiers,
+ append "_" to all uppercase tokens because the HTML anchor id attribute is not case-sensitive
+ """
+ return f"{candidate_anchor_id}_" if candidate_anchor_id.isupper() else candidate_anchor_id
+
+
+#dataclass
+class Comment(GrammarElement):
+ def get_marked_up_txt(self) -> str:
+ return self.get_txt()
+
+ def get_txt(self) -> str:
+ rendered_string = "\n".join(self.lines)
+ return f"{rendered_string}\n\n"
+
+ def get_html(self) -> str:
+ if self.lines[0].startswith("<"):
+ rendered_string = "".join(self.lines)
+ else:
+ rendered_string = "{rendered_string}\n
\n" + + +@dataclass +class Info(GrammarElement): + source: str + timestamp: str + + def get_marked_up_txt(self) -> str: + return self.get_txt() + + def get_txt(self) -> str: + rendered_lines = [ + line_comment(f"Source document: {self.source}"), + line_comment(f"Generated by bnf_grammar_processor at: {self.timestamp}") + ] + [line_comment(x) for x in self.lines] + rendered_string = "".join(rendered_lines) + return f"{rendered_string}\n\n" + + def get_html(self) -> str: + rendered_lines = [ + f"{LINE_COMMENT_MARKER} Source document: {self.source}", + f"{LINE_COMMENT_MARKER} Generated by bnf_grammar_processor at: {self.timestamp}" + ] + [f"{LINE_COMMENT_MARKER} {x}" for x in self.lines] + rendered_string = "{rendered_string}\n
\n" + + +@dataclass +class Heading(GrammarElement): + def get_marked_up_txt(self) -> str: + return self.get_txt() + + def get_txt(self) -> str: + assert len(self.lines) == 1 + return f"{line_comment(self.lines[0])}\n" + + def get_html(self) -> str: + assert len(self.lines) == 1 + if self.clause_id: + anchor = f'' + level = self.clause_id.count(".") + 1 + else: + anchor = "" + level = 1 + html_string = f'{rendered_lines}\n\n"
+ return hyperlinked_production
+
+
+@dataclass
+class Image(GrammarElement):
+ def get_marked_up_txt(self) -> str:
+ return self.get_txt()
+
+ def get_txt(self) -> str:
+ rendered_lines = "\n".join(self.lines)
+ return f"{rendered_lines}\n"
+
+ def get_html(self) -> str:
+ rendered_lines = "\n".join(self.lines)
+ return f"{rendered_lines}\n"
+
+
+@dataclass
+class NoteRef(GrammarElement):
+ def get_marked_up_txt(self) -> str:
+ return self.get_txt()
+
+ def get_txt(self) -> str:
+ rendered_lines = "".join(self.lines)
+ return f"{line_comment(rendered_lines)}\n"
+
+ def get_html(self) -> str:
+ rendered_lines = "".join(self.lines)
+ return f"{line_comment(rendered_lines, False)}
\n" + + +@dataclass +class NoteList(GrammarElement): + html_snippet: str + + def get_marked_up_txt(self) -> str: + list_tag_pattern = re.compile(r"(<(ol|ul|li)>)") + snippet_with_linebreaks = list_tag_pattern.sub(r"\n\1", self.html_snippet).strip() + rendered_lines = ["Notes:"] + rendered_lines += snippet_with_linebreaks.split("\n") + comment_prefix = f"{LINE_COMMENT_MARKER} " + rendered_string = comment_prefix + f"\n{comment_prefix}".join(rendered_lines) + "\n\n" + return rendered_string + + def get_txt(self) -> str: + rendered_lines = ["Notes:"] + rendered_lines += render_nested_lists(self.html_snippet, mode=RenderMode.TXT, apply_line_comment=False).split("\n") + rendered_string = block_comment(rendered_lines) + rendered_string = remove_html_tags(rendered_string) + return rendered_string + + def get_html(self) -> str: + rendered_lines = [f"{LINE_COMMENT_MARKER} Notes:
"] + rendered_lines.extend(render_nested_lists(self.html_snippet, mode=RenderMode.HTML, apply_line_comment=True).split("\n")) + rendered_string = "\n".join(rendered_lines) + return rendered_string + + +class GrammarProcessor: + """ + Grammar processor that handles KerML and SysML2 BNF grammars + + The processor has two main methods: + - extract_bnf_from_spec(...): extracts BNF grammar snippets from a given KerML or SysML spec file in raw (View Editor) HTML format + - process_marked_up_bnf(...): processes a (corrected) BNF grammar from a given KerML or SysML marked_up text file + + Both can process two kinds of grammars: + - concrete textual notation + - concrete graphical notation + + Mistakes or ambiguous productions and notes are logged in the form of ERROR or WARNING messages respectively. + """ + def __init__(self): + self.start_timestamp = datetime.now(timezone.utc).isoformat(timespec="seconds").replace("+00:00", "Z") + self.input_dir = "" + self.output_dir = "" + self.input_path: str = "" + self.input_path_previous: Optional[str] = None + self.soup: Optional[BeautifulSoup] = None + self.spec_title = "" + self.bnf_clause_id: str = "" + self.bnf_path: str = "" + self.syntax_kind: str = "" + self.elements: list[GrammarElement] = [] + self.grammars: list[Grammar] = [] + self.reserved_keyword_set: set[str] = set() + self.extracted_keyword_set: set[str] = set() + self.reserved_symbol_set: set[str] = set() + self.extracted_symbol_set: set[str] = set() + self.parser: Optional[Lark] = None + self.partial_productions: dict[str, list[str]] = dict() + self.missing_svgs: list[str] = [] + self.image_map: dict[str, str] = dict() + self.unresolved_non_terminals_dict: dict[str, list[str]] = dict() + + # Provide a backlink to this GrammarProcessor inside the GrammarElement classes + GrammarElement.processor = self + + def extract_bnf_from_spec(self, input_dir: str, output_dir: str, input_file: str, syntax_kind: str, bnf_clause_id: str): + """ + extract BNF productions and notes from raw HTML dump of a KerML or SysML specification + + This method produces the following outputs: + - a plain text file containing a machine-readable version of each BNF grammar, + with extension .kebnf for a textual EBNF source and extension .kgbnf for a graphical EBNF source; + - an HTML file containing a human-readable version of each BNF grammar, in which all references to terms are hyperlinked to their declaration; + - a log file containing diagnostic information (DEBUG, INFO, WARNING, ERROR messages) about the processed grammars. + + This method uses heuristics to process the raw HTML input, which may contain format and content errors. + """ + self.input_dir = input_dir + self.output_dir = output_dir + self.input_path = os.path.join(self.input_dir, input_file) + + if syntax_kind == "textual-bnf": + self.syntax_kind = syntax_kind + self.bnf_path = input_file.replace("-spec.html", "-textual-bnf") + self.parser = Lark.open("kebnf_textual_grammar.lark", rel_to=__file__, parser="lalr") + elif syntax_kind == "graphical-bnf": + self.syntax_kind = syntax_kind + self.bnf_path = input_file.replace("-spec.html", "-graphical-bnf") + self.parser = Lark.open("kgbnf_graphical_grammar.lark", rel_to=__file__, parser="lalr") + elif syntax_kind == "kerml-library": + raise NotImplementedError + elif syntax_kind == "sysml-library": + raise NotImplementedError + else: + LOGGER.critical(f"Unsupported BNF mode: {syntax_kind}, terminating ...\n") + sys.exit(1) + + self.bnf_clause_id = bnf_clause_id + self.spec_title = "" + self.elements = [] + self.grammars.append(Grammar(self.bnf_path, set())) + self.reserved_keyword_set = set() + self.extracted_keyword_set = set() + self.reserved_symbol_set = set() + self.extracted_symbol_set = set() + self.partial_productions = dict() + self.image_map = dict() + self.unresolved_non_terminals_dict: dict[str, list[str]] = dict() + + LOGGER.info(20 * "=") + LOGGER.info(f"Extract BNF from {self.input_path} syntax-kind={syntax_kind} clause={self.bnf_clause_id} at {self.start_timestamp}") + LOGGER.info(20 * "=") + + self.elements.append(Info("", [], source=self.input_path.replace("\\", "/"), timestamp=self.start_timestamp)) + + # Regular expression patterns + KEYWORD_PATTERN = re.compile(r"('[a-z]{2,}')") + SYMBOL_PATTERN = re.compile(r"('[^A-Za-z\s]+')") + SEE_NOTE_PATTERN = re.compile(r"^[ \t]*[(]?[ \t]*See Note.*$", flags=re.IGNORECASE) + + if self.input_path == self.input_path_previous: + # Skip reparsing the HTML spec and reuse self.soup + pass + else: + with open(self.input_path, mode="r", encoding="utf-8") as html_spec: + self.soup = BeautifulSoup(html_spec, "html.parser") + + inside_bnf_clause = False + contains_note_reference = False + contains_notes_section = False + contains_pre_tag = False + count = 0 + clause_id = "" + clause_title = "" + + # Walk through all HTML elements (tags) and extract + # - clause headings + # - grammar productions and their notes from the given textual or graphical notation clause + for tag in self.soup.find_all(name=["h1", "pre", "p", "ol"], recursive=True): + assert isinstance(tag, Tag) + count += 1 + LOGGER.debug(f"Visit tag #{count} {tag.name}") + + if tag.name == "h1": + # Process clause heading + contains_note_reference = False + contains_notes_section = False + contains_pre_tag = False + # LOGGER.debug(f"tag{count}={tag}") + + class_attribute = tag.attrs.get("class") + if class_attribute and "view-title" in class_attribute: + # LOGGER.debug(f"view-title tag={tag}") + clause_id = tag.find("span", {"class": "ve-view-number"}).string + clause_id = clause_id.strip() if clause_id else "" + clause_title = tag.find("transclude-name").find("span").string + clause_title = clause_title.strip() if clause_title else "" + + if clause_id == self.bnf_clause_id: + inside_bnf_clause = True + elif inside_bnf_clause and not clause_id.startswith(self.bnf_clause_id): + inside_bnf_clause = False + + if inside_bnf_clause or clause_id == "": + if clause_id == "": + clause_string = clause_title + self.spec_title = clause_title + else: + clause_string = f"Clause {clause_id} {clause_title}" + + LOGGER.info(f"PROCESSING {clause_string}") + self.elements.append(Heading(clause_id, [clause_string])) + + # TODO: Properly check forelements in notes lists, i.e. contained in
element that contains BNF grammar lines + if tag.parent.name == "li": + LOGGER.warning(f"appearing inside
element: {candidate_production}")
+ current_note_ref = NoteRef(clause_id, lines=[line])
+ self.elements.append(current_note_ref)
+ else:
+ if line.find("=|") >= 0:
+ # Process partial graphical BNF productions
+ is_partial = True
+ lhs, rhs = line.split("=|", 1)
+ production_name = lhs.strip()
+ abstract_type = ""
+ if not production_name in self.partial_productions:
+ self.partial_productions[production_name] = []
+ for term in [x.strip() for x in rhs.split("|")]:
+ if term:
+ self.partial_productions[production_name].append(term)
+ else:
+ # Process other BNF productions
+ is_partial = False
+ lhs1 = line.split("=")[0].strip()
+ lhs2 = lhs1.split(":", 1)
+ production_name = lhs2[0].strip()
+ if len(lhs2) == 2:
+ abstract_type = lhs2[1].strip()
+ elif is_pascal_case(production_name):
+ abstract_type = production_name
+ else:
+ abstract_type = ""
+ if production_name in self.grammars[-1].production_names:
+ LOGGER.error(f"Non-unique production name: {production_name} in {clause_id}:\n{candidate_production}")
+ else:
+ self.grammars[-1].production_names.add(production_name)
+
+ current_production = Production(clause_id, [line], production_name, abstract_type, is_partial)
+ self.elements.append(current_production)
+
+ if line[0] in (" ", "\t"):
+ LOGGER.error(f"Production start line starts with a space or tab: {line}")
+ line = line.strip()
+ if self.syntax_kind == "textual-bnf":
+ TEXTUAL_EQUALS_PATTERN = re.compile(r"( = | =$)")
+ if not TEXTUAL_EQUALS_PATTERN.search(line):
+ LOGGER.warning(f"Production start line does not contain exactly one '=': {line}")
+ elif self.syntax_kind == "graphical-bnf":
+ GRAPHICAL_EQUALS_PATTERN = re.compile(r"( = | =$| =\| | =\|$)")
+ if not GRAPHICAL_EQUALS_PATTERN.search(line):
+ LOGGER.warning(f"Production start line does not contain exactly one '=' or '=|': {line}")
+ elif current_note_ref:
+ current_note_ref.lines.append(line)
+ elif " element: tag={subtag}")
+
+ elif tag.name == "p" and inside_bnf_clause and contains_pre_tag:
+ LOGGER.debug(f"note
tag={tag}") + if tag.string == "Notes": + contains_notes_section = True + elif (tag.contents and tag.contents[0].name == "strong" + and tag.contents[0].string and tag.contents[0].string.strip() in ("Note.", "Note:")): + # Note in graphical BNF + text_content = clean_text_content(" ".join(tag.stripped_strings), True) + self.elements.append(NoteRef(clause_id, lines=[text_content])) + + + elif tag.name == "ol" and inside_bnf_clause and contains_pre_tag and tag.parent.name != "li": + LOGGER.debug(f"note
element: tag=implementation defined character sequence
+ERROR : Unexpected tag inside element: tag=character sequence excluding
+INFO : PROCESSING Clause 8.2.2.2 Notes and Comments
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.2 in production:
+COMMENT_LINE_TEXT =
+ LINE_TEXT excluding the sequence '*/'
+
+Unexpected token Token('PROPERTY_NAME', 'the') at line 2, column 25.
+Expected one of:
+ * "?="
+ * "+="
+ * DOT
+ * EQUAL
+Previous tokens: [Token('PROPERTY_NAME', 'excluding')]
+
+ERROR : Unexpected tag inside element: tag=excluding the sequence
+INFO : PROCESSING Clause 8.2.2.3 Names
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.3 in production:
+UNRESTRICTED_NAME =
+ single_quote ( NAME_CHARACTER | ESCAPE_SEQUENCE )* single_quote
+
+No terminal matches '_' in the current parser context, at line 2 col 11
+
+ single_quote ( NAME_CHARACTER | ESCAPE_SEQUENC
+ ^
+Expected one of:
+ * "?="
+ * RBRACE
+ * "+="
+ * DOT
+ * EQUAL
+
+Previous tokens: Token('PROPERTY_NAME', 'single')
+
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.3 in production:
+ALPHABETIC_CHARACTER =
+ any character 'a' through 'z' or 'A' through 'Z'
+
+Unexpected token Token('PROPERTY_NAME', 'character') at line 2, column 9.
+Expected one of:
+ * "?="
+ * "+="
+ * DOT
+ * EQUAL
+Previous tokens: [Token('PROPERTY_NAME', 'any')]
+
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.3 in production:
+DECIMAL_DIGIT =
+ any character '0' through '9'
+
+Unexpected token Token('PROPERTY_NAME', 'character') at line 2, column 9.
+Expected one of:
+ * "?="
+ * "+="
+ * DOT
+ * EQUAL
+Previous tokens: [Token('PROPERTY_NAME', 'any')]
+
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.3 in production:
+NAME_CHARACTER =
+ any printable character other than backslash or single_quote
+
+Unexpected token Token('PROPERTY_NAME', 'printable') at line 2, column 9.
+Expected one of:
+ * "?="
+ * "+="
+ * DOT
+ * EQUAL
+Previous tokens: [Token('PROPERTY_NAME', 'any')]
+
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.3 in production:
+ESCAPE_SEQUENCE =
+
+Unexpected token Token('_NON_CONTINUATION_LINE', '\n') at line 1, column 18.
+Expected one of:
+ * TERMINAL
+ * TILDE
+ * QUALIFIED_NAME
+ * PROPERTY_NAME
+ * LEXICAL_NAME
+ * LBRACE
+ * LPAR
+ * NONTERMINAL_NAME
+Previous tokens: [Token('EQUAL', '=')]
+
+ERROR : Unexpected tag inside element: tag=(see Note 1
+ERROR : Unexpected tag inside element: tag=any character
+ERROR : Unexpected tag inside element: tag=through
+ERROR : Unexpected tag inside element: tag=or
+ERROR : Unexpected tag inside element: tag=through
+ERROR : Unexpected tag inside element: tag=any character
+ERROR : Unexpected tag inside element: tag=through
+ERROR : Unexpected tag inside element: tag=any printable character other than backslash or single_quote
+ERROR : Unexpected tag inside element: tag=see Note 2
+INFO : PROCESSING Clause 8.2.2.4 Numeric Values
+INFO : PROCESSING Clause 8.2.2.5 String Value
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.2.5 in production:
+STRING_CHARACTER =
+ any printable character other than backslash or '"'
+
+Unexpected token Token('PROPERTY_NAME', 'printable') at line 2, column 9.
+Expected one of:
+ * "?="
+ * "+="
+ * DOT
+ * EQUAL
+Previous tokens: [Token('PROPERTY_NAME', 'any')]
+
+INFO : PROCESSING Clause 8.2.2.6 Reserved Words
+ERROR : Unexpected tag inside element: tag=about abstract alias all and as assoc behavior binding bool by chains class
+classifier comment composite conjugate conjugates conjugation connector const
+crosses datatype default dependency derived differences disjoining disjoint doc
+else end expr false feature featured featuring filter first flow for from
+function hastype if implies import in inout interaction intersects inv inverse
+inverting istype language library locale member meta metaclass metadata
+multiplicity namespace nonunique not null of or ordered out package portion
+predicate private protected public redefines redefinition references rep return
+specialization specializes standard step struct subclassifier subset subsets
+subtype succession then to true type typed typing unions var xor
+INFO : PROCESSING Clause 8.2.2.7 Symbols
+INFO : PROCESSING Clause 8.2.3 Root Concrete Syntax
+INFO : PROCESSING Clause 8.2.3.1 Elements and Relationships Concrete Syntax
+INFO : PROCESSING Clause 8.2.3.2 Dependencies Concrete Syntax
+INFO : PROCESSING Clause 8.2.3.3 Annotations Concrete Syntax
+INFO : PROCESSING Clause 8.2.3.3.1 Annotations
+INFO : PROCESSING Clause 8.2.3.3.2 Comments and Documentation
+INFO : PROCESSING Clause 8.2.3.3.3 Textual Representation
+INFO : PROCESSING Clause 8.2.3.4 Namespaces Concrete Syntax
+INFO : PROCESSING Clause 8.2.3.4.1 Namespaces
+ERROR : Unexpected tag inside element: tag=(See Note 1)
+ERROR : Unexpected tag inside element: tag=(See Note 2)
+ERROR : Unexpected tag inside element: tag=(See Note 3)
+INFO : PROCESSING Clause 8.2.3.4.2 Imports
+WARNING : Production start line does not contain exactly one '=': ImportDeclaration : Import
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.3.4.2 in production:
+ImportDeclaration : Import
+ MembershipImport | NamespaceImport
+
+Unexpected token Token('NONTERMINAL_NAME', 'MembershipImport') at line 2, column 5.
+Expected one of:
+ * EQUAL
+Previous tokens: [Token('NONTERMINAL_NAME', 'Import')]
+
+ERROR : Unexpected tag inside element: tag=(see Note 1)
+INFO : PROCESSING Clause 8.2.3.4.3 Namespace Elements
+INFO : PROCESSING Clause 8.2.3.5 Name Resolution
+INFO : PROCESSING Clause 8.2.3.5.1 Name Resolution Overview
+INFO : PROCESSING Clause 8.2.3.5.2 Local and Global Namespaces
+INFO : PROCESSING Clause 8.2.3.5.3 Local and Visible Resolution
+INFO : PROCESSING Clause 8.2.3.5.4 Full Resolution
+INFO : PROCESSING Clause 8.2.4 Core Concrete Syntax
+INFO : PROCESSING Clause 8.2.4.1 Types Concrete Syntax
+INFO : PROCESSING Clause 8.2.4.1.1 Types
+INFO : PROCESSING Clause 8.2.4.1.2 Specialization
+WARNING : Production start line does not contain exactly one '=': SpecificType : Specialization :
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.4.1.2 in production:
+SpecificType : Specialization :
+ specific = [QualifiedName]
+ | specific += OwnedFeatureChain
+ { ownedRelatedElement += specific }
+
+Unexpected token Token('COLON', ':') at line 1, column 31.
+Expected one of:
+ * EQUAL
+Previous tokens: [Token('NONTERMINAL_NAME', 'Specialization')]
+
+INFO : PROCESSING Clause 8.2.4.1.3 Conjugation
+INFO : PROCESSING Clause 8.2.4.1.4 Disjoining
+INFO : PROCESSING Clause 8.2.4.1.5 Unioning, Intersecting and Differencing
+INFO : PROCESSING Clause 8.2.4.1.6 Feature Membership
+INFO : PROCESSING Clause 8.2.4.2 Classifiers Concrete Syntax
+INFO : PROCESSING Clause 8.2.4.2.1 Classifiers
+INFO : PROCESSING Clause 8.2.4.2.2 Subclassification
+INFO : PROCESSING Clause 8.2.4.3 Features Concrete Syntax
+INFO : PROCESSING Clause 8.2.4.3.1 Features
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.4.3.1 in production:
+Feature =
+ ( FeaturePrefix
+ ( 'feature' | ownedRelationship += PrefixMetadataMember )
+ FeatureDeclaration?
+ )
+ | ( EndFeaturePrefix | BasicFeaturePrefix )
+ FeatureDeclaration
+ )
+ ValuePart? TypeBody
+
+Unexpected token Token('RPAR', ')') at line 8, column 5.
+Expected one of:
+ * _NON_CONTINUATION_LINE
+
+WARNING : Production start line does not contain exactly one '=': BasicFeaturePrefix : Feature :
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.4.3.1 in production:
+BasicFeaturePrefix : Feature :
+ ( direction = FeatureDirection )?
+ ( isDerived ?= 'derived' )?
+ ( isAbstract ?= 'abstract' )?
+ ( isComposite ?= 'composite' | isPortion ?= 'portion' )?
+ ( isVariable ?= 'var' | isConstant ?= 'const' { isVariable = true } )?
+
+Unexpected token Token('COLON', ':') at line 1, column 30.
+Expected one of:
+ * EQUAL
+Previous tokens: [Token('NONTERMINAL_NAME', 'Feature')]
+
+WARNING : Production start line does not contain exactly one '=': FeaturePrefix :
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.4.3.1 in production:
+FeaturePrefix :
+ ( EndFeaturePrefix ( ownedRelationship += OwnedCrossFeatureMember )?
+ | BasicFeaturePrefix
+ )
+ ( ownedRelationship += PrefixMetadataMember )*
+
+Unexpected token Token('LPAR', '(') at line 2, column 5.
+Expected one of:
+ * NONTERMINAL_NAME
+Previous tokens: [Token('COLON', ':')]
+
+ERROR : Unexpected tag inside element: tag=(See Note 1)
+ERROR : Unexpected tag inside element: tag=(see Note 1)
+INFO : PROCESSING Clause 8.2.4.3.2 Feature Typing
+INFO : PROCESSING Clause 8.2.4.3.3 Subsetting
+INFO : PROCESSING Clause 8.2.4.3.4 Redefinition
+INFO : PROCESSING Clause 8.2.4.3.5 Feature Chaining
+INFO : PROCESSING Clause 8.2.4.3.6 Feature Inverting
+INFO : PROCESSING Clause 8.2.4.3.7 Type Featuring
+INFO : PROCESSING Clause 8.2.5 Kernel Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.1 Data Types Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.2 Classes Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.3 Structures Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.4 Associations Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.5 Connectors Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.5.1 Connectors
+INFO : PROCESSING Clause 8.2.5.5.2 Binding Connectors
+INFO : PROCESSING Clause 8.2.5.5.3 Successions
+INFO : PROCESSING Clause 8.2.5.6 Behaviors Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.6.1 Behaviors
+INFO : PROCESSING Clause 8.2.5.6.2 Steps
+INFO : PROCESSING Clause 8.2.5.7 Functions Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.7.1 Functions
+INFO : PROCESSING Clause 8.2.5.7.2 Expressions
+INFO : PROCESSING Clause 8.2.5.7.3 Predicates
+INFO : PROCESSING Clause 8.2.5.7.4 Boolean Expressions and Invariants
+INFO : PROCESSING Clause 8.2.5.8 Expressions Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.8.1 Operator Expressions
+INFO : PROCESSING Clause 8.2.5.8.2 Primary Expressions
+INFO : PROCESSING Clause 8.2.5.8.3 Base Expressions
+INFO : PROCESSING Clause 8.2.5.8.4 Literal Expressions
+INFO : PROCESSING Clause 8.2.5.9 Interactions Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.9.1 Interactions
+INFO : PROCESSING Clause 8.2.5.9.2 Flows
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.5.9.2 in production:
+PayloadFeature =
+ Identification PayloadFeatureSpecializationPart ValuePart?
+ | Identification ValuePart
+ | ( ownedRelationship += OwnedFeatureTyping
+ ( ownedRelationship += OwnedMultiplicity )?
+ | ownedRelationship += OwnedMultiplicity
+ ( ownedRelationship += OwnedFeatureTyping )?
+
+Unexpected token Token('_NON_CONTINUATION_LINE', '\n') at line 7, column 51.
+Expected one of:
+ * RPAR
+
+ERROR : Unexpected tag inside element: tag=(See Note 1)
+INFO : PROCESSING Clause 8.2.5.10 Feature Values Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.11 Multiplicities Concrete Syntax
+INFO : PROCESSING Clause 8.2.5.12 Metadata Concrete Syntax
+WARNING : Production start line does not contain exactly one '=': PrefixMetadataFeature : MetadataFeature :
+ERROR : Parse error in tests\KerML_and_SysML_spec_sources\KerML-spec.html 8.2.5.12 in production:
+PrefixMetadataFeature : MetadataFeature :
+ ownedRelationship += OwnedFeatureTyping
+
+Unexpected token Token('COLON', ':') at line 1, column 41.
+Expected one of:
+ * EQUAL
+Previous tokens: [Token('NONTERMINAL_NAME', 'MetadataFeature')]
+
+INFO : PROCESSING Clause 8.2.5.13 Packages Concrete Syntax
+INFO : ===== Start of Textual Notation Grammar Checks
+INFO : Keywords extracted from textual BNF grammar scan:
+ about abstract alias all and as assoc behavior binding bool by chains class classifier comment composite conjugate
+ conjugates conjugation connector const crosses datatype default dependency derived differences disjoining disjoint
+ doc else end expr false feature featured featuring filter first flow for from function hastype if implies import in
+ inout interaction intersects inv inverse inverting istype language library locale member meta metaclass metadata
+ multiplicity namespace new nonunique not null of or ordered out package portion predicate private protected public
+ redefines redefinition references rep return specialization specializes standard step struct subclassifier subset
+ subsets subtype succession then to true type typed typing unions var xor
+INFO : Comparison of declared reserved keywords versus extracted keywords
+INFO : Declared reserved keywords not in extracted keywords:
+
+WARNING : Extracted keywords not in declared reserved keywords:
+ new
+INFO : ===== End of Textual Notation Grammar Checks
+INFO : Dumping BNF grammar elements into tests\KerML_and_SysML_grammars\KerML-textual-bnf-elements.json
+INFO : Writing BNF grammar file tests\KerML_and_SysML_grammars\KerML-textual-bnf-marked_up.kebnf
+INFO : Writing BNF grammar file tests\KerML_and_SysML_grammars\KerML-textual-bnf.kebnf
+INFO : Writing BNF HTML file tests\KerML_and_SysML_grammars\KerML-textual-bnf.html
+WARNING : Grammar KerML-textual-bnf contains 4 unresolved non-terminal(s) ...
+ERROR : Cannot resolve InstatiatedTypeMember in
+ 8.2.5.8.3: ownedRelationship += InstatiatedTypeMember
+ERROR : Cannot resolve InvocationTypeMember in
+ 8.2.5.8.2: ownedRelationship += InvocationTypeMember
+ERROR : Cannot resolve ItemFlowDeclaration in
+ 8.2.5.9.2: ItemFlowDeclaration TypeBody
+ 8.2.5.9.2: ItemFlowDeclaration TypeBody
+ERROR : Cannot resolve MetaClassificationTestOperator in
+ 8.2.5.8.1: ( operator = MetaClassificationTestOperator
+INFO : ====================
+INFO : Extract BNF from tests\KerML_and_SysML_spec_sources\SysML-spec.html syntax-kind=textual-bnf clause=8.2.2 at 2026-01-05T11:42:22Z
+INFO : ====================
+INFO : PROCESSING Part 2 - Systems Modeling Language (SysML)
+INFO : PROCESSING Clause 8.2.2 Textual Notation
+INFO : PROCESSING Clause 8.2.2.1 Textual Notation Overview
+INFO : PROCESSING Clause 8.2.2.1.1 EBNF Conventions
+INFO : PROCESSING Clause 8.2.2.1.2 Lexical Structure
+WARNING : appearing inside
about abstract accept action actor after alias all allocate allocation analysis +and as assert assign assume at attribute bind binding by calc case comment +concern connect connection constant constraint crosses decide def default +defined dependency derived do doc else end entry enum event exhibit exit expose +false filter first flow for fork frame from hastype if implies import in include +individual inout interface istype item join language library locale loop merge +message meta metadata nonunique not null objective occurrence of or ordered out +package parallel part perform port private protected public redefines ref +references render rendering rep require requirement return satisfy send snapshot +specializes stakeholder standard state subject subsets succession terminate then +timeslice to transition true until use variant variation verification verify via +view viewpoint when while xor+ERROR : Unexpected tag inside
element: tag=about abstract accept action actor after alias all allocate allocation analysis +and as assert assign assume at attribute bind binding by calc case comment +concern connect connection constant constraint crosses decide def default +defined dependency derived do doc else end entry enum event exhibit exit expose +false filter first flow for fork frame from hastype if implies import in include +individual inout interface istype item join language library locale loop merge +message meta metadata nonunique not null objective occurrence of or ordered out +package parallel part perform port private protected public redefines ref +references render rendering rep require requirement return satisfy send snapshot +specializes stakeholder standard state subject subsets succession terminate then +timeslice to transition true until use variant variation verification verify via +view viewpoint when while xor +WARNING :appearing inside
DEFINED_BY = ':' | 'defined' 'by' +SPECIALIZES = ':>' | 'specializes' +SUBSETS = ':>' | 'subsets' +REFERENCES = '::>' | 'references' +CROSSES = '=>' | 'crosses' +REDEFINES = ':>>' | 'redefines' ++INFO : PROCESSING Clause 8.2.2.2 Elements and Relationships Textual Notation +INFO : PROCESSING Clause 8.2.2.3 Dependencies Textual Notation +INFO : PROCESSING Clause 8.2.2.4 Annotations Textual Notation +INFO : PROCESSING Clause 8.2.2.4.1 Annotations +INFO : PROCESSING Clause 8.2.2.4.2 Comments and Documentation +INFO : PROCESSING Clause 8.2.2.4.3 Textual Representation +INFO : PROCESSING Clause 8.2.2.5 Namespaces and Packages Textual Notation +INFO : PROCESSING Clause 8.2.2.5.1 Packages +WARNING : Production start line does not contain exactly one '=': PackageMember : OwningMembership +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.5.1 in production: +PackageMember : OwningMembership + MemberPrefix + ( ownedRelatedElement += DefinitionElement + | ownedRelatedElement = UsageElement ) + +Unexpected token Token('NONTERMINAL_NAME', 'MemberPrefix') at line 2, column 5. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'OwningMembership')] + +INFO : PROCESSING Clause 8.2.2.5.2 Package Elements +INFO : PROCESSING Clause 8.2.2.6 Definition and Usage Textual Notation +INFO : PROCESSING Clause 8.2.2.6.1 Definitions +WARNING : Production start line does not contain exactly one '=': DefinitionDeclaration : Definition +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.6.1 in production: +DefinitionDeclaration : Definition + Identification SubclassificationPart? + +Unexpected token Token('NONTERMINAL_NAME', 'Identification') at line 2, column 5. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'Definition')] + +INFO : PROCESSING Clause 8.2.2.6.2 Usages +WARNING : Production start line does not contain exactly one '=': UsagePrefix : Usage +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.6.2 in production: +UsagePrefix : Usage + UnextendedUsagePrefix UsageExtensionKeyword* + +Unexpected token Token('NONTERMINAL_NAME', 'UnextendedUsagePrefix') at line 2, column 5. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'Usage')] + +ERROR : Unexpected tag inside
element: tag=(see Note 1) +INFO : PROCESSING Clause 8.2.2.6.3 Reference Usages +INFO : PROCESSING Clause 8.2.2.6.4 Body Elements +INFO : PROCESSING Clause 8.2.2.6.5 Specialization +INFO : PROCESSING Clause 8.2.2.6.6 Multiplicity +INFO : PROCESSING Clause 8.2.2.7 Attributes Textual Notation +INFO : PROCESSING Clause 8.2.2.8 Enumerations Textual Notation +INFO : PROCESSING Clause 8.2.2.9 Occurrences Textual Notation +INFO : PROCESSING Clause 8.2.2.9.1 Occurrence Definitions +INFO : PROCESSING Clause 8.2.2.9.2 Occurrence Usages +INFO : PROCESSING Clause 8.2.2.9.3 Occurrence Successions +INFO : PROCESSING Clause 8.2.2.10 Items Textual Notation +INFO : PROCESSING Clause 8.2.2.11 Parts Textual Notation +INFO : PROCESSING Clause 8.2.2.12 Ports Textual Notation +ERROR : Unexpected tag insideelement: tag=(See Note 1) + +ERROR : Unexpected tag insideelement: tag=(See Note 2) +INFO : PROCESSING Clause 8.2.2.13 Connections Textual Notation +INFO : PROCESSING Clause 8.2.2.13.1 Connection Definition and Usage +WARNING : Production start line does not contain exactly one '=': ConnectorEndMember : EndFeatureMembership : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.13.1 in production: +ConnectorEndMember : EndFeatureMembership : + ownedRelatedElement += ConnectorEnd + +Unexpected token Token('COLON', ':') at line 1, column 43. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'EndFeatureMembership')] + +INFO : PROCESSING Clause 8.2.2.13.2 Binding Connectors +INFO : PROCESSING Clause 8.2.2.13.3 Successions +INFO : PROCESSING Clause 8.2.2.14 Interfaces Textual Notation +INFO : PROCESSING Clause 8.2.2.14.1 Interface Definitions +INFO : PROCESSING Clause 8.2.2.14.2 Interface Usages +WARNING : Production start line does not contain exactly one '=': InterfaceEnd : PortUsage : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.14.2 in production: +InterfaceEnd : PortUsage : + ( ownedRelationship += OwnedCrossMultiplicityMember )? + ( declaredName = NAME REFERENCES )? + ownedRelationship += OwnedReferenceSubsetting + +Unexpected token Token('COLON', ':') at line 1, column 26. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'PortUsage')] + +INFO : PROCESSING Clause 8.2.2.15 Allocations Textual Notation +INFO : PROCESSING Clause 8.2.2.16 Flows Textual Notation +WARNING : Production start line does not contain exactly one '=': FlowDefinition : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.16 in production: +FlowDefinition : + OccurrenceDefinitionPrefix 'flow' 'def' Definition + +Unexpected token Token('TERMINAL', "'flow'") at line 2, column 32. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'OccurrenceDefinitionPrefix')] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.16 in production: +PayloadFeatureSpecializationPart : Feature = + ( -> FeatureSpecialization )+ MultiplicityPart? + FeatureSpecialization* + | MultiplicityPart FeatureSpecialization+ + +No terminal matches '-' in the current parser context, at line 2 col 9 + + ( -> FeatureSpecialization )+ Multiplicity + ^ +Expected one of: + * TERMINAL + * TILDE + * QUALIFIED_NAME + * PROPERTY_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + +Previous tokens: Token('LPAR', '(') + +ERROR : Unexpected tag insideelement: tag=(See Note 1) +INFO : PROCESSING Clause 8.2.2.17 Actions Textual Notation +INFO : PROCESSING Clause 8.2.2.17.1 Action Definitions +INFO : PROCESSING Clause 8.2.2.17.2 Action Usages +INFO : PROCESSING Clause 8.2.2.17.3 Control Nodes +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.17.3 in production: +ControlNodePrefix : OccurrenceUsage = + RefPrefix + ( isIndividual ?= 'individual )? + ( portionKind = PortionKind + { isPortion = true } + )? + UsageExtensionKeyword* + +No terminal matches ''' in the current parser context, at line 3 col 23 + + ( isIndividual ?= 'individual )? + ^ +Expected one of: + * TERMINAL + * TILDE + * QUALIFIED_NAME + * LEXICAL_NAME + * LPAR + * NONTERMINAL_NAME + * BOOLEAN_VALUE + +Previous tokens: Token('__ANON_1', '?=') + +INFO : PROCESSING Clause 8.2.2.17.4 Send and Accept Action Usages +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.17.4 in production: +TriggerExpression : TriggerInvocationExpression = + kind = ( 'at | 'after' ) + ownedRelationship += ArgumentMember + | kind = 'when' + ownedRelationship += ArgumentExpressionMember + +Unexpected token Token('PROPERTY_NAME', 'after') at line 2, column 23. +Expected one of: + * VBAR + +INFO : PROCESSING Clause 8.2.2.17.5 Assignment Action Usages +INFO : PROCESSING Clause 8.2.2.17.6 Terminate Action Usages +INFO : PROCESSING Clause 8.2.2.17.7 Structured Control Action Usages +INFO : PROCESSING Clause 8.2.2.17.8 Action Successions +INFO : PROCESSING Clause 8.2.2.18 States Textual Notation +INFO : PROCESSING Clause 8.2.2.18.1 State Definitions +WARNING : Production start line does not contain exactly one '=': EntryTransitionMember : FeatureMembership : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.18.1 in production: +EntryTransitionMember : FeatureMembership : + MemberPrefix + ( ownedRelatedElement += GuardedTargetSuccession + | 'then' ownedRelatedElement += TargetSuccession + ) ';' + +Unexpected token Token('COLON', ':') at line 1, column 43. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'FeatureMembership')] + +WARNING : Production start line does not contain exactly one '=': StateSendActionUsage : SendActionUsage +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.18.1 in production: +StateSendActionUsage : SendActionUsage + SendNodeDeclaration ActionBody + +Unexpected token Token('NONTERMINAL_NAME', 'SendNodeDeclaration') at line 2, column 5. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'SendActionUsage')] + +INFO : PROCESSING Clause 8.2.2.18.2 State Usages +INFO : PROCESSING Clause 8.2.2.18.3 Transition Usages +INFO : PROCESSING Clause 8.2.2.19 Calculations Textual Notation +INFO : PROCESSING Clause 8.2.2.20 Constraints Textual Notation +INFO : PROCESSING Clause 8.2.2.21 Requirements Textual Notation +INFO : PROCESSING Clause 8.2.2.21.1 Requirement Definitions +INFO : PROCESSING Clause 8.2.2.21.2 Requirement Usages +INFO : PROCESSING Clause 8.2.2.21.3 Concerns +INFO : PROCESSING Clause 8.2.2.22 Cases Textual Notation +INFO : PROCESSING Clause 8.2.2.23 Analysis Cases Textual Notation +INFO : PROCESSING Clause 8.2.2.24 Verification Cases Textual Notation +INFO : PROCESSING Clause 8.2.2.25 Use Cases Textual Notation +WARNING : Production start line does not contain exactly one '=': IncludeUseCaseUsage : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.25 in production: +IncludeUseCaseUsage : + OccurrenceUsagePrefix 'include' + ( ownedRelationship += OwnedReferenceSubsetting + FeatureSpecializationPart? + | 'use' 'case' UsageDeclaration ) + ValuePart? + CaseBody + +Unexpected token Token('TERMINAL', "'include'") at line 2, column 27. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'OccurrenceUsagePrefix')] + +INFO : PROCESSING Clause 8.2.2.26 Views and Viewpoints Textual Notation +INFO : PROCESSING Clause 8.2.2.26.1 View Definitions +INFO : PROCESSING Clause 8.2.2.26.2 View Usages +INFO : PROCESSING Clause 8.2.2.26.3 Viewpoints +INFO : PROCESSING Clause 8.2.2.26.4 Renderings +INFO : PROCESSING Clause 8.2.2.27 Metadata Textual Notation +WARNING : Production start line does not contain exactly one '=': MetadataBodyUsage : ReferenceUsage : +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.2.27 in production: +MetadataBodyUsage : ReferenceUsage : + 'ref'? ( ':>>' | 'redefines' )? ownedRelationship += OwnedRedefinition + FeatureSpecializationPart? ValuePart? + MetadataBody + +Unexpected token Token('COLON', ':') at line 1, column 36. +Expected one of: + * EQUAL +Previous tokens: [Token('NONTERMINAL_NAME', 'ReferenceUsage')] + +INFO : ===== Start of Textual Notation Grammar Checks +INFO : Keywords extracted from textual BNF grammar scan: + about abstract accept action actor after alias all allocate allocation analysis and as assert assign assume + assumption at attribute bind binding by calc case comment concern connect connection constant constraint crosses + decide def default defined dependency derived do doc effect else end entry enum event exhibit exit expose false + filter first flow for fork frame from guard hastype if implies import in include individual inout interface istype + item join language library locale loop merge message meta metadata nonunique not null objective occurrence of or + ordered out package parallel part perform port private protected public redefines ref references render rendering + rep require requirement return satisfy send snapshot specializes stakeholder standard state subject subsets + succession terminate then timeslice to transition trigger true typed until use variant variation verification verify + via view viewpoint when while xor +INFO : Comparison of declared reserved keywords versus extracted keywords +INFO : Declared reserved keywords not in extracted keywords: + +WARNING : Extracted keywords not in declared reserved keywords: + assumption effect guard trigger typed +INFO : ===== End of Textual Notation Grammar Checks +INFO : Dumping BNF grammar elements into tests\KerML_and_SysML_grammars\SysML-textual-bnf-elements.json +INFO : Writing BNF grammar file tests\KerML_and_SysML_grammars\SysML-textual-bnf-marked_up.kebnf +INFO : Writing BNF grammar file tests\KerML_and_SysML_grammars\SysML-textual-bnf.kebnf +INFO : Writing BNF HTML file tests\KerML_and_SysML_grammars\SysML-textual-bnf.html +WARNING : Tokenize: Unexpected character '-' in state None at position 8 in line: ( -> FeatureSpecialization )+ MultiplicityPart? +WARNING : Tokenize: Missing single quote -> incomplete TERMINAL in line: ( isIndividual ?= 'individual )? +WARNING : Tokenize: Space inside TERMINAL 'at | ' in line kind = ( 'at | 'after' ) +WARNING : Tokenize: Unexpected character ''' in state TokenKind.NON_TERMINAL at position 27 in line: kind = ( 'at | 'after' ) +WARNING : Grammar SysML-textual-bnf contains 6 unresolved non-terminal(s) ... +ERROR : Cannot resolve CalculationUsageDeclaration in + 8.2.2.21.1: CalculationUsageDeclaration CalculationBody +ERROR : Cannot resolve DefinitionExtensionKeyWord in + 8.2.2.27: ( isAbstract ?= 'abstract')? DefinitionExtensionKeyWord* +ERROR : Cannot resolve EndFeatureMembership in + 8.2.2.13.1: ConnectorEndMember : EndFeatureMembership : +ERROR : Cannot resolve FeatureMembership in + 8.2.2.18.1: EntryTransitionMember : FeatureMembership : +ERROR : Cannot resolve FilterPackageImport in + 8.2.2.5.1: ownedRelationship += FilterPackageImport +ERROR : Cannot resolve SendReceiverPart in + 8.2.2.17.4: | ownedRelationship += EmptyParameterMember SendReceiverPart )? +INFO : ==================== +INFO : Extract BNF from tests\KerML_and_SysML_spec_sources\SysML-spec.html syntax-kind=graphical-bnf clause=8.2.3 at 2026-01-05T11:42:22Z +INFO : ==================== +INFO : PROCESSING Part 2 - Systems Modeling Language (SysML) +INFO : PROCESSING Clause 8.2.3 Graphical Notation +INFO : PROCESSING Clause 8.2.3.1 Graphical Notation Overview +INFO : PROCESSING Clause 8.2.3.2 Elements and Relationships Graphical Notation +ERROR : Unexpected tag insideelement: tag=+ERROR : Production start line starts with a space or tab: element-inside-textual-compartment = +ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.3 Dependencies Graphical Notation +ERROR : Non-unique production name: element-node in 8.2.3.3: +element-node = + usage-node | definition-node | annotation-node | namespace-node +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.4 Annotations Graphical Notation +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.5 Namespaces and Packages Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.5 in production: +relationship-name = 'defines', 'defined by', 'specializes', 'specialized by', 'connect to', + 'subsets', 'subsetted by', 'performs', 'performed by', 'allocated', 'allocated to', + 'satisfy', 'satisfied by' + +No terminal matches ',' in the current parser context, at line 1 col 30 + +relationship-name = 'defines', 'defined by', 'specializes', 'speciali + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('TERMINAL', "'defines'") + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.6 Definition and Usage Graphical Notation +WARNING : Production start line does not contain exactly one '=' or '=|': general-node |= usage-node definition-node< +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +general-node |= usage-node definition-node< + +Unexpected token Token('VBAR', '|') at line 1, column 14. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-node')] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +compartment =| + | features-compartment + | variants-compartment + | variant-elementusages-compartment + +Unexpected token Token('VBAR', '|') at line 2, column 5. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('__ANON_0', '=|')] + +WARNING : Graphical note found in
, but should beelement: Note. This production is only valid for cases where one or more +WARNING : Production start line does not contain exactly one '=' or '=|': DefinitionExtensionKeyword names a MetadataDefinition that is a direct +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +DefinitionExtensionKeyword names a MetadataDefinition that is a direct + +Unexpected token Token('NONTERMINAL_NAME', 'DefinitionExtensionKeyword') at line 1, column 1. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +WARNING : Production start line does not contain exactly one '=' or '=|': or indirect specialization of KerML metaclass SemanticMetadata. +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +or indirect specialization of KerML metaclass SemanticMetadata. + +Unexpected token Token('GRAPHICAL_NAME', 'indirect') at line 1, column 4. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'or')] + +WARNING : Production start line does not contain exactly one '=' or '=|': definition-node |= extended-def +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +definition-node |= extended-def + +Unexpected token Token('VBAR', '|') at line 1, column 17. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'definition-node')] + +WARNING : Graphical note found in
, but should beelement: Note. This production is only valid for cases where one or more +WARNING : Production start line does not contain exactly one '=' or '=|': UsageExtensionKeyword names a MetadataDefinition that is a direct +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +UsageExtensionKeyword names a MetadataDefinition that is a direct + +Unexpected token Token('NONTERMINAL_NAME', 'UsageExtensionKeyword') at line 1, column 1. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +ERROR : Non-unique production name: or indirect specialization of KerML metaclass SemanticMetadata. in 8.2.3.6: +or indirect specialization of KerML metaclass SemanticMetadata. +WARNING : Production start line does not contain exactly one '=' or '=|': or indirect specialization of KerML metaclass SemanticMetadata. +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +or indirect specialization of KerML metaclass SemanticMetadata. + +Unexpected token Token('GRAPHICAL_NAME', 'indirect') at line 1, column 4. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'or')] + +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= extended-usage +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.6 in production: +usage-node |= extended-usage + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.7 Attributes Graphical Notation +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.8 Enumerations Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.8 in production: +enums-compartment_contents = (enums-compartment-element)* '…'? + +No terminal matches '_' in the current parser context, at line 1 col 18 + +enums-compartment_contents = (enums-compartment-element)* + ^ +Expected one of: + * "=|" + * EQUAL + +Previous tokens: Token('GRAPHICAL_NAME', 'enums-compartment') + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.9 Occurrences Graphical Notation +WARNING : Production start line does not contain exactly one '=' or '=|': snapshots-name-compartment +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.9 in production: +snapshots-name-compartment + '«snapshot»' + usage-name-with-alias + +Unexpected token Token('TERMINAL', "'«snapshot»'") at line 2, column 7. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'snapshots-name-compartment')] + +ERROR : Non-unique production name: definition-node | in 8.2.3.9: +definition-node |= event-occurrence-def +WARNING : Production start line does not contain exactly one '=' or '=|': definition-node |= event-occurrence-def +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.9 in production: +definition-node |= event-occurrence-def + +Unexpected token Token('VBAR', '|') at line 1, column 17. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'definition-node')] + +ERROR : Non-unique production name: usage-node | in 8.2.3.9: +usage-node |= event-occurrence +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= event-occurrence +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.9 in production: +usage-node |= event-occurrence + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.9 in production: +eventer = usage-node | definition-node< + +No terminal matches '<' in the current parser context, at line 1 col 39 + +eventer = usage-node | definition-node< + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('GRAPHICAL_NAME', 'definition-node') + +ERROR : Non-unique production name: succession-label in 8.2.3.9: +succession-label = Identification +WARNING : Graphical note found in
, but should beelement: Note: the proxy nodes attached to a succession must refer to an event +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.10 Items Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.10 in production: +interconnection-element = | item| item-ref + +Unexpected token Token('VBAR', '|') at line 1, column 27. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.11 Parts Graphical Notation +ERROR : Non-unique production name: interconnection-element in 8.2.3.11: +interconnection-element = | part | part-ref +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.11 in production: +interconnection-element = | part | part-ref + +Unexpected token Token('VBAR', '|') at line 1, column 27. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.11 in production: +directed-features-compartment-element = + el-prefix FeatureDirection Definition-Body-Item* + +No terminal matches '-' in the current parser context, at line 2 col 40 + + el-prefix FeatureDirection Definition-Body-Item* + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('NONTERMINAL_NAME', 'Definition') + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.12 Ports Graphical Notation +ERROR : Unexpected empty line in candidate production: + | +
+ | + proxy-v +ERROR : Production start line starts with a space or tab: | +WARNING : Production start line does not contain exactly one '=' or '=|': | +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.12 in production: + | +
+ | + proxy-v + +Unexpected token Token('VBAR', '|') at line 1, column 5. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.13 Connections Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.13 in production: +connection-def-graphical = +
+ | +
general-relationship |= connection-def-graphical + +Unexpected token Token('EQUAL', '=') at line 4, column 98. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('VBAR', '|')] + +ERROR : Non-unique production name: definition-node | in 8.2.3.13: +definition-node |= n-ary-def-connection-dot +WARNING : Production start line does not contain exactly one '=' or '=|': definition-node |= n-ary-def-connection-dot +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.13 in production: +definition-node |= n-ary-def-connection-dot + +Unexpected token Token('VBAR', '|') at line 1, column 17. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'definition-node')] + +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= n-ary-def-segment +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.13 in production: +general-relationship |= n-ary-def-segment + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Non-unique production name: usage-node | in 8.2.3.13: +usage-node |= n-ary-connection-dot +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= n-ary-connection-dot +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.13 in production: +usage-node |= n-ary-connection-dot + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.14 Interfaces Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.14 in production: +interface-def-name-compartment = + '«' DefinitionPrefix 'interface' 'def' '»' + definition-name-with-alias< + +No terminal matches '<' in the current parser context, at line 3 col 33 + + definition-name-with-alias< + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('GRAPHICAL_NAME', 'definition-name-with-alias') + +ERROR : Non-unique production name: connection-relationship in 8.2.3.14: +connection-relationship = + | interface-connection +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.14 in production: +connection-relationship = + | interface-connection + +Unexpected token Token('VBAR', '|') at line 2, column 5. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.15 Allocations Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.15 in production: +usage-edge = |allocate-relationship + +Unexpected token Token('VBAR', '|') at line 1, column 14. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.16 Flows Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.16 in production: +flows-compartment = + ________________________________________ + 'flows' + flows-compartment-contents + +No terminal matches '_' in the current parser context, at line 2 col 7 + + ________________________________________ + ^ +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + +Previous tokens: Token('EQUAL', '=') + +WARNING : Graphical note found in
, but should beelement: Note: proxy nodes and ends of messages must refer to occurrences +WARNING : Graphical note found in
, but should beelement: Note: proxy nodes at ends of flows must refer to directed features +ERROR : Non-unique production name: flow-node in 8.2.3.16: +flow-node = + flow-node-r + | flow-node-l + | sflow-node-r + | sflow-node-l + | message-node-r + | message-node-l +ERROR : Non-unique production name: flow-label in 8.2.3.16: +flow-label = + Identification | FlowPayloadFeatureMember +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.17 Actions Graphical Notation +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.17 in production: +action-def-name-compartment = + '«' DefinitionPrefix 'action' 'def' '»' + definition-name-with-alias< + +No terminal matches '<' in the current parser context, at line 3 col 33 + + definition-name-with-alias< + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('GRAPHICAL_NAME', 'definition-name-with-alias') + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.17 in production: +action-name-compartment = + '«' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias< + +No terminal matches '<' in the current parser context, at line 3 col 28 + + usage-name-with-alias< + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('GRAPHICAL_NAME', 'usage-name-with-alias') + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.17 in production: +param-label = QualifiedName (‘:’ QualifiedName)* + +No terminal matches '‘' in the current parser context, at line 1 col 30 + +param-label = QualifiedName (‘:’ QualifiedName)* + ^ +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + +Previous tokens: Token('LPAR', '(') + +ERROR : Non-unique production name: usage-edge in 8.2.3.17: +usage-edge = |succession perform-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.17 in production: +usage-edge = |succession perform-edge + +Unexpected token Token('VBAR', '|') at line 1, column 14. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.18 States Graphical Notation +ERROR :
element appears at start of line: + definition-node =| state-def + +state-def = + + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +entry-action-name-comp = + +Unexpected token Token('_NON_CONTINUATION_LINE', '\n') at line 1, column 25. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +WARNING : Production start line does not contain exactly one '=' or '=|': '«' 'entry' OccurrenceUsagePrefix 'action' '»' +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +'«' 'entry' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +Unexpected token Token('TERMINAL', "'«'") at line 1, column 1. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +exit-action-name-comp = + +Unexpected token Token('_NON_CONTINUATION_LINE', '\n') at line 1, column 24. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +WARNING : Production start line does not contain exactly one '=' or '=|': '«' 'exit' OccurrenceUsagePrefix 'action' '»' +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +'«' 'exit' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +Unexpected token Token('TERMINAL', "'«'") at line 1, column 1. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +do-action-name-comp = + +Unexpected token Token('_NON_CONTINUATION_LINE', '\n') at line 1, column 22. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +WARNING : Production start line does not contain exactly one '=' or '=|': '«' 'do' OccurrenceUsagePrefix 'action' '»' +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +'«' 'do' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +Unexpected token Token('TERMINAL', "'«'") at line 1, column 1. +Expected one of: + * LINE_COMMENT + * GRAPHICAL_NAME + * LEXICAL_NAME +Previous tokens: [None] + +ERROR : Non-unique production name: general-relationship | in 8.2.3.18: +general-relationship |= exhibit-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= exhibit-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +general-relationship |= exhibit-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Non-unique production name: usage-edge in 8.2.3.18: +usage-edge = |transition | st-succession | exhibit-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.18 in production: +usage-edge = |transition | st-succession | exhibit-edge + +Unexpected token Token('VBAR', '|') at line 1, column 14. +Expected one of: + * TERMINAL + * QUALIFIED_NAME + * IMAGE + * GRAPHICAL_NAME + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME +Previous tokens: [Token('EQUAL', '=')] + +ERROR : Unexpected tag inside+ +state-def-name-compartment = + '«' DefinitionPrefix 'state' 'def' '»' + definition-name-with-alias + ('«' 'parallel' '»')? + +usage-node =| + state-node + | exhibit-state-usage + +state = + +
+ +state-ref = + +
+ +state-name-compartment = + '«' OccurrenceUsagePrefix 'state' '»' + usage-name-with-alias + ('«' 'parallel' '»')? + +exhibit-state-usage = +
+ +state-subaction-body = state-subaction-body-textual | action-flow-view + +state-subaction-body-textual = state-subaction-declaration? ( '{' ActionBodyItem* '}' )? + +state-subaction-declaration = + PerformActionUsageDeclaration + | AcceptNodeDeclaration + | SendNodeDeclaration + | AssignmentNodeDeclaration + + +state-do-action = +
+ state-subaction-body + +state-entry-action = + +
+ state-subaction-body + +state-exit-action = +
+ state-subaction-body + +entry-action = +
| + +
+ +entry-action-name-comp = +'«' 'entry' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +exit-action = +
+ +exit-action-name-comp = +'«' 'exit' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +do-action = +
+ +do-action-name-comp = +'«' 'do' OccurrenceUsagePrefix 'action' '»' + usage-name-with-alias + +exhibit-state-name-compartment = + '«exhibit-state»' + state-name-compartment + +compartment =| + states-compartment + | states-actions-compartment + | exhibit-states-compartment + | successions-compartment + | state-transition-compartment + +states-compartment = + +
+ states-compartment-contents + +states-compartment-contents = (states-compartment-element)* '…'? +states-compartment-element = + el-prefix? OccurrencePrefix ActionUsageDeclaration + +state-actions-compartment = + +
+ state-actions-compartment-contents + +state-actions-compartment-contents = (state-actions-compartment-element)* '…'? +state-actions-compartment-element = + el-prefix? EntryActionMember | DoActionMember | ExitActionMember + +exhibit-states-compartment = + +
+ exhibit-states-compartment-contents + +exhibit-states-compartment-contents = exhibit-state-scompartment-element* '…'? +exhibit-states-compartment-element-compartment = UsageDeclaration + +succession-compartment = + +
+ succession-compartment-contents + +succession-compartment-contents = QualifiedName* '…'? + +state-transition-compartment = + +
+ state-transition-view + +state-transition-view = + (state-transition-element)* + (dependencies-and-annotations-element)* + + +state-transition-element = + state-transition-node + | transition + | st-succession + +state-transition-node = + state-node + | state-ref-node + | start-node + | entry-action + | do-action + | exit-action + | done-node + | fork-node + | join-node + | decision-node + | merge-node + | terminate-node + | action + | perform-action-usage + | action-ref + +transition = +
+ | +
+ +state-source = + state-node | state-ref-node + +transition-label = trigger-expression '/' ActionUsage + +trigger-expression = AcceptParameterPart (guard-expression)? + +st-succession = +
+ | +
+ +exhibit-edge = +
+ +exhibitor = part | part-def + +general-relationship |= exhibit-edge + +usage-edge = |transition | st-succession | exhibit-edge
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.19 Calculations Graphical Notation +ERROR : Non-unique production name: calc-name-compartment in 8.2.3.19: +calc-name-compartment = + '«' OccurrenceUsagePrefix 'calc' '»' + usage-name-with-alias +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.20 Constraints Graphical Notation +ERROR :
element appears at start of line: + definition-node =| constraint-def + +constraint-def = + ++ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.20 in production: +usage-node =| assume-constraint-node assert-constraint-node< + +No terminal matches '<' in the current parser context, at line 1 col 60 + +e-constraint-node assert-constraint-node< + ^ +Expected one of: + * TERMINAL + * RPAR + * QUALIFIED_NAME + * _NON_CONTINUATION_LINE + * IMAGE + * GRAPHICAL_NAME + * REPETITION_SYMBOL + * LEXICAL_NAME + * LBRACE + * LPAR + * NONTERMINAL_NAME + * VBAR + +Previous tokens: Token('GRAPHICAL_NAME', 'assert-constraint-node') + +ERROR : Non-unique production name: general-relationship | in 8.2.3.20: +general-relationship |= assume-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= assume-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.20 in production: +general-relationship |= assume-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Non-unique production name: general-relationship | in 8.2.3.20: +general-relationship |= assert-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= assert-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.20 in production: +general-relationship |= assert-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Unexpected tag inside+ +constraint-def-name-compartment = + '«' DefinitionPrefix 'constraint' 'def' '»' + definition-name-with-alias + +usage-node = + constraint + | assert-constraint-usage + +constraint = + +
+ +constraint-ref = + +
+ +constraint-name-compartment = + '«' OccurrenceUsagePrefix 'constraint' '»' + usage-name-with-alias + +assert-constraint-node = + +
+ +assert-constraint-name-compartment = + '«assert constraint»' + constraint-name-compartment + +assume-constraint-node = +
+ +assume-constraint-name-compartment = + '«' OccurrenceUsagePrefix 'assume' 'constraint' '»' + usage-name-with-alias + +usage-node =| assume-constraint-node assert-constraint-node< + +assume-edge = +
+assumer = requirement | requirement-def + +general-relationship |= assume-edge + +assert-edge = +
+assertor = usage-node | definition-node + +general-relationship |= assert-edge + +compartment =| + constraints-compartment + | assert-constraints-compartment + +constraints-compartment = + +
+ constraints-compartment-contents + +constraints-compartment-contents = (constraints-usage-compartment-element)* '…'? +constraints-usage-compartment-element = + el-prefix? OccurrenceUsagePrefix ConstraintUsageDeclaration CalculationBody* + +assert-constraints-compartment = + +
+ assert-constraints-compartment-contents + +assert-constraints-compartment-contents = (assert-constraints-compartment-element)* '…'? +assert-constraints-compartment-element = + el-prefix? OccurrenceUsagePrefix ( 'not' )? + ( OwnedSubsetting FeatureSpecializationPart? | UsageDeclaration ) + CalculationUsageParameterPart CalculationBody + +interconnection-element =| + constraint-ref + | constraint +
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.21 Requirements Graphical Notation +ERROR : Non-unique production name: usage-node in 8.2.3.21: +usage-node = + requirement + | satisfy-requirement-usage + | concern +ERROR : Non-unique production name: general-relationship | in 8.2.3.21: +general-relationship |= satisfy-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= satisfy-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.21 in production: +general-relationship |= satisfy-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Non-unique production name: general-relationship | in 8.2.3.21: +general-relationship |= require-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= require-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.21 in production: +general-relationship |= require-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Non-unique production name: usage-node | in 8.2.3.21: +usage-node |= require-constraint-node +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= require-constraint-node +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.21 in production: +usage-node |= require-constraint-node + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Non-unique production name: usage-node | in 8.2.3.21: +usage-node |= frame-concern-node +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= frame-concern-node +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.21 in production: +usage-node |= frame-concern-node + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Non-unique production name: general-relationship | in 8.2.3.21: +general-relationship |= frame-edge +WARNING : Production start line does not contain exactly one '=' or '=|': general-relationship |= frame-edge +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.21 in production: +general-relationship |= frame-edge + +Unexpected token Token('VBAR', '|') at line 1, column 22. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'general-relationship')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.22 Cases Graphical Notation +ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.23 Analysis Cases Graphical Notation +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+INFO : PROCESSING Clause 8.2.3.24 Verification Cases Graphical Notation +ERROR : Non-unique production name: usage-node | in 8.2.3.24: +usage-node |= verify-requirement-node +WARNING : Production start line does not contain exactly one '=' or '=|': usage-node |= verify-requirement-node +ERROR : Parse error in tests\KerML_and_SysML_spec_sources\SysML-spec.html 8.2.3.24 in production: +usage-node |= verify-requirement-node + +Unexpected token Token('VBAR', '|') at line 1, column 12. +Expected one of: + * "=|" + * EQUAL +Previous tokens: [Token('GRAPHICAL_NAME', 'usage-node')] + +ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=+ERROR : Unexpected tag inside
element: tag=