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
34 changes: 34 additions & 0 deletions bionetgen/modelapi/bngparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,43 @@ def _normalize_action_text(action: str) -> str:
"""
text = _strip_comment_outside_quotes(action)
text = _collapse_unquoted_whitespace(text)
text = _strip_unquoted_backslashes(text)
return text.strip()


def _strip_unquoted_backslashes(text: str) -> str:
"""Drop ``\\`` characters that appear outside string literals."""
return _filter_outside_quotes(text, lambda ch: ch != "\\")


def _filter_outside_quotes(text: str, keep) -> str:
out = []
in_single = False
in_double = False
escaped = False
for ch in text:
if escaped:
out.append(ch)
escaped = False
continue
if ch == "\\" and (in_single or in_double):
out.append(ch)
escaped = True
continue
if ch == '"' and not in_single:
in_double = not in_double
out.append(ch)
continue
if ch == "'" and not in_double:
in_single = not in_single
out.append(ch)
continue
if not in_single and not in_double and not keep(ch):
continue
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_drops_stray_backslashes_outside_quotes():
from bionetgen.modelapi.bngparser import _normalize_action_text

out = _normalize_action_text(
'parameter_scan({n_scan_pts=>101,\\log_scale=>1,method=>"ode"})'
)
assert "\\" not in out
assert "log_scale=>1" in out


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

out = _normalize_action_text('action({arg=>"a\\b"})')
assert '"a\\b"' in out
Loading