Basic Usage#

The parser is part of the Python module ison and is simply imported with the command import ison.

Error Messages#

The following example shows how to print out an error message of the ISON parser and then we will look at how to interpret it.

import ison

dicData = {
    "__locals__": {
        # Error here, because 'a' cannot be added to a number
        "iA": "$sum{1, a}"
    },
    "result": "${iA}"
}

# Use a try-except block to catch error exceptions and print them.
try:
    dicResult = ison.run.Run(xData=dicData, bStripVars=False)
    print(ison.run.ToString(dicResult))
except Exception as xEx:
    print(str(xEx))
# endtry
Error running ISON parser:
 1> Error parsing '__locals__'
 2> Error parsing variable 'iA'
 3> String: $sum{1, a}
 4> String element: >>$sum{1, a}<<
 5> Function '$sum{}' with 2 argument(s):
  |   0: 1
  |   1: a
 6> Function '$sum{}': Error converting list of summation elements to 'float': could not convert string to float: 'a'

This error output shows the parsing steps until the error occured. Since the object that is parsed need not be related to a JSON file, no line numbers can be output, to show where the error occurred. Instead, the parsing steps are shown, so you can follow them to understand where and in which context the error occurred. In this example the steps are:

  1. The __locals__ variables are parsed

  2. The element iA of the __locals__dictionary is parsed

  3. The element iA results in the an object of type string, with the content $sum{1, a}

  4. With this string all variables and functions of type $[...]{[...]} are parsed. The element parsed in this instance is the only variable element in this string, which is $sum{1, a}.

  5. The function $sum{} is called with the arguments as shown.

  6. The function $sum{} raises the error, because not all elements can be converted to float. In particular, it is element a that cannot be converted.

These error outputs can become quite long, but they help to find the error, especially in cases of multiply nested references.

Warnings#

One feature of ISON is, that undefined variables do not cause an error. The idea is, that as much is parsed as possible at the moment, so that the remainder can be parsed when the currently unknown variables are defined. However, this behaviour an lead to errors that are caused by undefined variables, but which are not reported as such. For these cases, the ISON parser also outputs warnings for those variables that were accessed but are undefined. If an error is thrown, these warnings are added to the error message. If no error is thrown, the warnings can be accessed from the parser object or printed by setting a flag in the call to Run(). Here is an example,

import ison

dicData = {
    "result": "${iA}"
}

try:
    dicResult = ison.run.Run(xData=dicData, bPrintWarnings=True)
    print(ison.run.ToString(dicResult))

except Exception as xEx:
    print(str(xEx))
# endtry
WARNINGS:
Undefined variable 'iA'
| 1: dict
| 2: [result]
| 3: ${iA}
{
    "result": "${iA}"
}

Here is an example of an error that also outputs the warnings about undefined variables.

import ison

dicData = {
    "__locals__": {
        "dicA": "${dicB}"
    },
    # Undefined variable 'iA'
    "result": "${dicA:a}"
}

try:
    dicResult = ison.run.Run(xData=dicData, bPrintWarnings=True)
    print(ison.run.ToString(dicResult))

except Exception as xEx:
    print(str(xEx))
# endtry
Error running ISON parser:
 1> Dictionary element 'result' -> string
 2> String: ${dicA:a}
 3> String element: >>${dicA:a}<<
 4> Function '${}' with 1 argument(s):
  |   0: dicA:a
 5> Referencing variables with:
  | > 0: dicA
  |   1: a
 6> Referencing dictionary element 'dicA' with:
  | > 0: a
 7> String result '${dicB}' cannot have further specialization 'a': dicA:>>a<<

Also consider these WARNING(s):
Undefined variable 'dicB'
| 1: __locals__
| 2: var: dicA
| 3: ${dicB}

Logging & Print Debugging#

Sometimes it is helpful to print the state of variables during parsing, or to log parsed values. This can be done with the functions $print{} and $set-log-path{}. If no logging path or file is defined with the latter, the former prints to stdout. If a path to a logging file is set, $print{} writes to the log file.

import ison

dicData = {
    "__locals__": {
        "lA": ["Hello", "World"],
        "dicA": { "Hello": "World" },
        "sLog": "$print{Variable 'dicA':, $json{$dicA}, $lA}"
    },
    "result": "$dicA"
}

try:
    dicResult = ison.run.Run(xData=dicData, bPrintWarnings=True)
    print(ison.run.ToString(dicResult))

except Exception as xEx:
    print(str(xEx))
# endtry
Variable 'dicA':
{
    "Hello": "World"
}
['Hello', 'World']
{
    "result": {
        "Hello": "World"
    }
}

You can set a logging path in three ways with $set-log-path{}:

  1. Without arguments the current working directory is used a logging path and a filename is automatically generated.

  2. Give a path without filename. In this case, a filename is automatically generated and the path is created.

  3. Give a full filepath. If the path does not exist, it is created.

import ison

dicData = {
    "__locals__": {
        "sLogPath": "$set-log-path{}",
        "dicA": { "Hello": "World" },
        "sLog": "$print{Variable 'dicA':, $json{$dicA}, }"
    },
    # Uncomment the following line to see the path of the log file
    # in the printed output.
    # "log-path": "${sLogPath}",
    "result": "$dicA"
}

try:
    dicResult = ison.run.Run(xData=dicData, bPrintWarnings=True)
    print(ison.run.ToString(dicResult))

except Exception as xEx:
    print(str(xEx))
# endtry
{
    "result": {
        "Hello": "World"
    }
}