Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions bionetgen/modelapi/bngparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,49 @@ def _normalize_action_text(action: str) -> str:
"""
text = _strip_comment_outside_quotes(action)
text = _collapse_unquoted_whitespace(text)
text = _collapse_unquoted_double_commas(text)
return text.strip()


def _collapse_unquoted_double_commas(text: str) -> str:
"""Collapse repeated commas that appear outside string literals."""
out = []
in_single = False
in_double = False
escaped = False
prev_was_comma = False
for ch in text:
if escaped:
out.append(ch)
escaped = False
prev_was_comma = False
continue
if ch == "\\" and (in_single or in_double):
out.append(ch)
escaped = True
prev_was_comma = False
continue
if ch == '"' and not in_single:
in_double = not in_double
out.append(ch)
prev_was_comma = False
continue
if ch == "'" and not in_double:
in_single = not in_single
out.append(ch)
prev_was_comma = False
continue
if ch == "," and not in_single and not in_double:
if prev_was_comma:
continue
prev_was_comma = True
out.append(ch)
continue
prev_was_comma = False
out.append(ch)
return "".join(out)


def _strip_comment_outside_quotes(text: str) -> str:
out = []
in_single = False
Expand Down
17 changes: 17 additions & 0 deletions tests/test_bng_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,20 @@ def test_pattern_canonicalization():
break
# assert that everything matched up
assert res is True


def test_action_normalization_collapses_unquoted_double_commas():
from bionetgen.modelapi.bngparser import _normalize_action_text

out = _normalize_action_text(
'simulate({method=>"ode",t_end=>3000,n_steps=>20,,print_functions=>1})'
)
assert ",," not in out
assert ",n_steps=>20,print_functions=>1" in out


def test_action_normalization_preserves_double_commas_inside_quotes():
from bionetgen.modelapi.bngparser import _normalize_action_text

out = _normalize_action_text('something({xs=>"0,,1,,2"})')
assert '"0,,1,,2"' in out
Loading