-
Notifications
You must be signed in to change notification settings - Fork 0
Parser output
The sip parser is a library first. A model execution engine calls it with a file path and gets back the parsed population:
from pathlib import Path
from sip_parser.parser import SIParser
result = SIParser.parse_file(file_input=Path('EVMAN_three_bank1.sip'))Two named tuples describe what comes back:
Scenario = namedtuple('Scenario', 'name classes')
ClassModelPopulation = namedtuple('ClassModelPopulation', 'header population')Scenario.name is the Scenario name and Scenario.classes is a dictionary keyed by
class name, in the order the classes appear in the
file. Each value is a ClassModelPopulation holding the
header and the list of instance rows.
For the Shaft population:
Shaft
ID | In service | R1>Bank
--
{ [S1] [true] @L } R53> NO TRANSFER > IDLE
--
the header is a list mixing plain attribute names with reference entries, in file order:
['ID', 'In service', [{'rnum': 'R1', 'to class': 'Bank'}]]and each row is a dictionary:
{'alias': None,
'row': ['S1', 'true', {'ref to': 'L'}],
'initial_state': [['R53', 'NO TRANSFER'], ['IDLE']]}-
aliasis the row's alias, orNone -
rowholds the values, each either a string or a{'ref to': alias}dictionary -
initial_stateis always a list, empty when the row gives no state. See Initial states
A reference column is reported as a list of rnum entries even when there is only one, so a consumer can handle the single and multiple relationship cases the same way. References are left inline among the attribute columns rather than collected separately, so that header positions still line up with row positions.
The parser checks syntax and nothing else. It never reads the xcm class model or the xsm state models, so all of the following pass without complaint and are left for the consumer to catch:
- a class, attribute, relationship or state that does not exist in the model
- a row with more or fewer values than the header has columns
- an
@aliasthat no row ever declared - a value that does not fit the attribute's type
- a second population block for a class already populated — the result is keyed by class name, so the later block silently replaces the earlier one
Everything the parser raises descends from SIParserException:
-
SIParseError— the file did not match the grammar. The message includes arpeggio's report of what was expected and where. -
SIInputFileOpen— the scenario file could not be opened -
SIInputFileEmpty— nothing was read from the scenario file -
SIGrammarFileOpen— the parser's ownsip.pegcould not be opened, which points at a broken installation
Each message is bracketed and prefixed with Scenario instance population parser: so it can be shown to a user
as is.
Copyright 2025-2026 © Leon Starr under MIT Open Source License