Skip to content

Parser output

Leon Starr edited this page Jul 30, 2026 · 2 revisions

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'))

The result

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']]}
  • alias is the row's alias, or None
  • row holds the values, each either a string or a {'ref to': alias} dictionary
  • initial_state is 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.

What the parser does not do

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 @alias that 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

Errors

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 own sip.peg could 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.

Clone this wiki locally