Skip to content

Commit

Permalink
Merge pull request #92 from mopichalova/89-complexes-in-abstr-seq
Browse files Browse the repository at this point in the history
enable direct usage of complexes
  • Loading branch information
xtrojak authored Feb 26, 2024
2 parents 230b374 + ef609a7 commit 52f30b5
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 16 deletions.
5 changes: 5 additions & 0 deletions Testing/models/model_cmplx_in_abstr_seq1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#! rules
S{i}:A():A2::cell => A()::cell

#! complexes
A2 = A().A()
2 changes: 2 additions & 0 deletions Testing/models/model_cmplx_in_abstr_seq2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#! rules
S{i}:A():A().A()::cell => A()::cell
17 changes: 17 additions & 0 deletions Testing/parsing/test_cmplx_in_abstr_seq.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import pytest

from Testing.models.get_model_str import get_model_str
import Testing.objects_testing as objects


def test_complexes_in_abstract_sequence():
# is allowed
model = get_model_str("model_cmplx_in_abstr_seq1")
ret1 = objects.model_parser.parse(model)
assert ret1.success

# should be allowed
model = get_model_str("model_cmplx_in_abstr_seq2")
ret2 = objects.model_parser.parse(model)
assert ret2.success
assert ret1.data == ret2.data
40 changes: 24 additions & 16 deletions eBCSgen/Parsing/ParseBCSL.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ def to_side(self):

EXTENDED_GRAMMAR = """
abstract_sequence: atomic_complex | atomic_structure_complex | structure_complex
atomic_complex: atomic ":" (cmplx_name|VAR)
atomic_structure_complex: atomic ":" structure ":" (cmplx_name|VAR)
structure_complex: structure ":" (cmplx_name|VAR)
atomic_complex: atomic ":" (VAR | value)
atomic_structure_complex: atomic ":" structure ":" (VAR | value)
structure_complex: structure ":" (VAR | value)
variable: VAR "=" "{" cmplx_name ("," cmplx_name)+ "}"
VAR: "?"
Expand Down Expand Up @@ -401,18 +401,23 @@ def insert_struct_to_complex(self, struct, complex):
Raises:
ComplexParsingError: If no matching struct is found in the complex.
"""
for i in range(len(complex.children)):
if self.get_name(struct) == self.get_name(complex.children[i].children[0]):
if isinstance(complex.children[0].children[0].children[0].children[0], Tree):
search = complex.children[0]
else:
search = complex

for i in range(len(search.children)):
if self.get_name(struct) == self.get_name(search.children[i].children[0]):
struct_found = True
# search same name structs - if they contain atomics with matching names, they are considered incompatible
for j in range(len(struct.children[1].children)):
for k in range(
len(complex.children[i].children[0].children[1].children)
len(search.children[i].children[0].children[1].children)
):
if self.get_name(
struct.children[1].children[j]
) == self.get_name(
complex.children[i].children[0].children[1].children[k]
search.children[i].children[0].children[1].children[k]
):
struct_found = False
break
Expand All @@ -422,13 +427,11 @@ def insert_struct_to_complex(self, struct, complex):

if struct_found:
# if the complex's struct is empty, replace it with the struct
if self.is_empty(complex.children[i]):
complex.children[i] = Tree("agent", [struct])
if self.is_empty(search.children[i]):
search.children[i] = Tree("agent", [struct])
else:
# if the complex's struct is not empty merge the struct's children into the complex's struct
complex.children[i].children[0].children[
1
].children += struct.children[1].children
search.children[i].children[0].children[1].children += struct.children[1].children
return complex

raise ComplexParsingError(
Expand All @@ -450,10 +453,15 @@ def insert_atomic_to_complex(self, atomic, complex):
Raises:
ComplexParsingError: If an atomic with the same name is already present in the complex.
"""
for i in range(len(complex.children)):
if self.get_name(atomic) == self.get_name(complex.children[i].children[0]):
if self.is_empty(complex.children[i].children[0]):
complex.children[i] = Tree("agent", [atomic])
if isinstance(complex.children[0].children[0].children[0].children[0], Tree):
search = complex.children[0]
else:
search = complex

for i in range(len(search.children)):
if self.get_name(atomic) == self.get_name(search.children[i].children[0]):
if self.is_empty(search.children[i].children[0]):
search.children[i] = Tree("agent", [atomic])
return complex
raise ComplexParsingError(
f"Illegal atomic nesting or duplication: {atomic}:{complex}", complex
Expand Down

0 comments on commit 52f30b5

Please sign in to comment.