diff --git a/OMPython/OMTypedParser.py b/OMPython/OMTypedParser.py index 84a4f6015..6e40195e6 100644 --- a/OMPython/OMTypedParser.py +++ b/OMPython/OMTypedParser.py @@ -53,6 +53,8 @@ delimitedList, nums, replaceWith, + infixNotation, + opAssoc, ) import sys @@ -87,6 +89,28 @@ def convertTuple(t): return tuple(t[0]) + +def evaluateExpression(s, loc, toks): + # Convert the tokens (ParseResults) into a string expression + flat_list = [item for sublist in toks[0] for item in sublist] + expr = " ".join(flat_list) + try: + # Evaluate the expression safely + return eval(expr) + except Exception as e: + print(f"Error evaluating expression: {expr}") + return None + +# Number parsing (supports arithmetic expressions in dimensions) (e.g., {1 + 1, 1}) +arrayDimension = infixNotation( + Word(nums), + [ + (Word("+-", exact=1), 1, opAssoc.RIGHT), + (Word("*/", exact=1), 2, opAssoc.LEFT), + (Word("+-", exact=1), 2, opAssoc.LEFT), + ], +).setParseAction(evaluateExpression) + omcRecord = Forward() omcValue = Forward() @@ -107,7 +131,8 @@ def convertTuple(t): omcValues = delimitedList(omcValue) omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).setParseAction(convertTuple) omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).setParseAction(convertTuple) -omcValue << (omcString | omcNumber | omcRecord | omcArray | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident)) +omcArraySpecialTypes = Group(Suppress('{') + delimitedList(arrayDimension) + Suppress('}')).setParseAction(convertTuple) +omcValue << (omcString | omcNumber | omcRecord | omcArray | omcArraySpecialTypes | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident)) recordMember = delimitedList(Group(ident + Suppress('=') + omcValue)) omcRecord << Group(Suppress('record') + Suppress(fqident) + Dict(recordMember) + Suppress('end') + Suppress(fqident) + Suppress(';')).setParseAction(convertDict) diff --git a/tests/test_ArrayDimension.py b/tests/test_ArrayDimension.py new file mode 100644 index 000000000..ac8d2dfad --- /dev/null +++ b/tests/test_ArrayDimension.py @@ -0,0 +1,31 @@ +import OMPython +import tempfile, shutil, os +import pytest + + +""" +do not change the prefix class name, the class name should have prefix "Test" +according to the documenation of pytest +""" +class Test_ArrayDimension: + + def test_ArrayDimension(self): + omc = OMPython.OMCSessionZMQ() + + ## create a temp dir for each session + tempdir = tempfile.mkdtemp() + if not os.path.exists(tempdir): + return print(tempdir, " cannot be created") + + tempdirExp="".join(["cd(","\"",tempdir,"\"",")"]).replace("\\","/") + omc.sendExpression(tempdirExp) + + omc.sendExpression("loadString(\"model A Integer x[5+1,1+6]; end A;\")") + omc.sendExpression("getErrorString()") + + result = omc.sendExpression("getComponents(A)") + assert result[0][-1] == (6,7), f"array dimension does not match the expected value. Got: {result[0][-1]}, Expected: {(6, 7)}" + + omc.__del__() + shutil.rmtree(tempdir, ignore_errors= True) +