From 2fb963183a8abab22b380eb5a1996f74ef2cdaa5 Mon Sep 17 00:00:00 2001 From: Bill Hlavacek Date: Sun, 10 May 2026 15:43:57 -0600 Subject: [PATCH] Allow bareword keys in nested action-arg hashes BNGL inherits Perl's `=>` fat-comma semantics, so action arguments like `generate_network({overwrite=>1,max_stoich=>{R=>6}})` are syntactically valid even though the inner hash key `R` is unquoted. The pyparsing grammar in `ActionList.define_parser()` required `quote_word` for nested-curly keys, so any model that relied on bareword keys (notably `max_stoich=>{=>}`) failed at parse time before BNG2.pl was ever invoked. Accept either bareword or quoted keys inside nested hashes: curly_arg_token = (base_name ^ quote_word) + "=>" + arg_type_int The existing dict-handling path in `BNGParser._parse_action_line` rebuilds the literal substring verbatim, so round-trip via `Action.gen_string()` is unchanged. --- bionetgen/core/utils/utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bionetgen/core/utils/utils.py b/bionetgen/core/utils/utils.py index 7d19fd23..34fd0354 100644 --- a/bionetgen/core/utils/utils.py +++ b/bionetgen/core/utils/utils.py @@ -487,7 +487,10 @@ def define_parser(self): arg_type_list = "[" + pp.delimitedList((quote_word ^ arg_type_float)) + "]" arg_type_string = quote_word # - curly_arg_token = quote_word + "=>" + arg_type_int + # BNGL/Perl `=>` auto-quotes its left operand, so dict keys + # may be either bareword (max_stoich=>{R=>6}) or quoted + # (max_stoich=>{"R"=>6}). Accept both. + curly_arg_token = (base_name ^ quote_word) + "=>" + arg_type_int # TODO: handle 0 case arg_type_curly = "{" + pp.delimitedList(curly_arg_token) + "}" arg_types = (