Skip to content

Commit e9c3e5e

Browse files
authored
Merge pull request #90 from wshlavacek/modelapi-b4-collapse-double-commas
Collapse repeated commas in action normalization
2 parents 43b44ed + 8f505e9 commit e9c3e5e

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

bionetgen/modelapi/bngparser.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,49 @@ def _normalize_action_text(action: str) -> str:
2828
text = _strip_comment_outside_quotes(action)
2929
text = _collapse_unquoted_whitespace(text)
3030
text = _strip_unquoted_backslashes(text)
31+
text = _collapse_unquoted_double_commas(text)
3132
return text.strip()
3233

3334

35+
def _collapse_unquoted_double_commas(text: str) -> str:
36+
"""Collapse repeated commas that appear outside string literals."""
37+
out = []
38+
in_single = False
39+
in_double = False
40+
escaped = False
41+
prev_was_comma = False
42+
for ch in text:
43+
if escaped:
44+
out.append(ch)
45+
escaped = False
46+
prev_was_comma = False
47+
continue
48+
if ch == "\\" and (in_single or in_double):
49+
out.append(ch)
50+
escaped = True
51+
prev_was_comma = False
52+
continue
53+
if ch == '"' and not in_single:
54+
in_double = not in_double
55+
out.append(ch)
56+
prev_was_comma = False
57+
continue
58+
if ch == "'" and not in_double:
59+
in_single = not in_single
60+
out.append(ch)
61+
prev_was_comma = False
62+
continue
63+
if ch == "," and not in_single and not in_double:
64+
if prev_was_comma:
65+
continue
66+
prev_was_comma = True
67+
out.append(ch)
68+
continue
69+
prev_was_comma = False
70+
out.append(ch)
71+
return "".join(out)
72+
73+
3474
def _strip_unquoted_backslashes(text: str) -> str:
3575
"""Drop ``\\`` characters that appear outside string literals."""
3676
return _filter_outside_quotes(text, lambda ch: ch != "\\")

tests/test_bng_parsing.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,20 @@ def test_action_normalization_preserves_backslashes_inside_quotes():
9090

9191
out = _normalize_action_text('action({arg=>"a\\b"})')
9292
assert '"a\\b"' in out
93+
94+
95+
def test_action_normalization_collapses_unquoted_double_commas():
96+
from bionetgen.modelapi.bngparser import _normalize_action_text
97+
98+
out = _normalize_action_text(
99+
'simulate({method=>"ode",t_end=>3000,n_steps=>20,,print_functions=>1})'
100+
)
101+
assert ",," not in out
102+
assert ",n_steps=>20,print_functions=>1" in out
103+
104+
105+
def test_action_normalization_preserves_double_commas_inside_quotes():
106+
from bionetgen.modelapi.bngparser import _normalize_action_text
107+
108+
out = _normalize_action_text('something({xs=>"0,,1,,2"})')
109+
assert '"0,,1,,2"' in out

0 commit comments

Comments
 (0)