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:
The
__locals__
variables are parsedThe element
iA
of the__locals__
dictionary is parsedThe element
iA
results in the an object of typestring
, with the content$sum{1, a}
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}
.The function
$sum{}
is called with the arguments as shown.The function
$sum{}
raises the error, because not all elements can be converted tofloat
. In particular, it is elementa
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{}
:
Without arguments the current working directory is used a logging path and a filename is automatically generated.
Give a path without filename. In this case, a filename is automatically generated and the path is created.
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"
}
}