Skip to content

Commit 317b944

Browse files
authored
add parser support for arithmetic expressions in array dimensions (#232)
1 parent d293943 commit 317b944

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

OMPython/OMTypedParser.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@
5353
delimitedList,
5454
nums,
5555
replaceWith,
56+
infixNotation,
57+
opAssoc,
5658
)
5759

5860
import sys
@@ -87,6 +89,28 @@ def convertTuple(t):
8789
return tuple(t[0])
8890

8991

92+
93+
def evaluateExpression(s, loc, toks):
94+
# Convert the tokens (ParseResults) into a string expression
95+
flat_list = [item for sublist in toks[0] for item in sublist]
96+
expr = " ".join(flat_list)
97+
try:
98+
# Evaluate the expression safely
99+
return eval(expr)
100+
except Exception as e:
101+
print(f"Error evaluating expression: {expr}")
102+
return None
103+
104+
# Number parsing (supports arithmetic expressions in dimensions) (e.g., {1 + 1, 1})
105+
arrayDimension = infixNotation(
106+
Word(nums),
107+
[
108+
(Word("+-", exact=1), 1, opAssoc.RIGHT),
109+
(Word("*/", exact=1), 2, opAssoc.LEFT),
110+
(Word("+-", exact=1), 2, opAssoc.LEFT),
111+
],
112+
).setParseAction(evaluateExpression)
113+
90114
omcRecord = Forward()
91115
omcValue = Forward()
92116

@@ -107,7 +131,8 @@ def convertTuple(t):
107131
omcValues = delimitedList(omcValue)
108132
omcTuple = Group(Suppress('(') + Optional(omcValues) + Suppress(')')).setParseAction(convertTuple)
109133
omcArray = Group(Suppress('{') + Optional(omcValues) + Suppress('}')).setParseAction(convertTuple)
110-
omcValue << (omcString | omcNumber | omcRecord | omcArray | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident))
134+
omcArraySpecialTypes = Group(Suppress('{') + delimitedList(arrayDimension) + Suppress('}')).setParseAction(convertTuple)
135+
omcValue << (omcString | omcNumber | omcRecord | omcArray | omcArraySpecialTypes | omcTuple | SOME | TRUE | FALSE | NONE | Combine(fqident))
111136
recordMember = delimitedList(Group(ident + Suppress('=') + omcValue))
112137
omcRecord << Group(Suppress('record') + Suppress(fqident) + Dict(recordMember) + Suppress('end') + Suppress(fqident) + Suppress(';')).setParseAction(convertDict)
113138

tests/test_ArrayDimension.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import OMPython
2+
import tempfile, shutil, os
3+
import pytest
4+
5+
6+
"""
7+
do not change the prefix class name, the class name should have prefix "Test"
8+
according to the documenation of pytest
9+
"""
10+
class Test_ArrayDimension:
11+
12+
def test_ArrayDimension(self):
13+
omc = OMPython.OMCSessionZMQ()
14+
15+
## create a temp dir for each session
16+
tempdir = tempfile.mkdtemp()
17+
if not os.path.exists(tempdir):
18+
return print(tempdir, " cannot be created")
19+
20+
tempdirExp="".join(["cd(","\"",tempdir,"\"",")"]).replace("\\","/")
21+
omc.sendExpression(tempdirExp)
22+
23+
omc.sendExpression("loadString(\"model A Integer x[5+1,1+6]; end A;\")")
24+
omc.sendExpression("getErrorString()")
25+
26+
result = omc.sendExpression("getComponents(A)")
27+
assert result[0][-1] == (6,7), f"array dimension does not match the expected value. Got: {result[0][-1]}, Expected: {(6, 7)}"
28+
29+
omc.__del__()
30+
shutil.rmtree(tempdir, ignore_errors= True)
31+

0 commit comments

Comments
 (0)