def parse_reaction(s):
def parse_count(s):<EOL><INDENT>m = re.match(r'<STR_LIT>', s)<EOL>if m is not None:<EOL><INDENT>s = m.group(<NUM_LIT:1>)<EOL><DEDENT>m = re.match(r'<STR_LIT>', s)<EOL>if m is not None:<EOL><INDENT>return int(m.group(<NUM_LIT:0>))<EOL><DEDENT>return Expression(s)<EOL><DEDENT>def parse_compound(s):<EOL><INDENT>m = re.match(r'<STR_LIT>', s)<EOL>if m is not None:<EOL><INDENT>return Compound(m.group(<NUM_LIT:1>), arguments=[Expression(m.group(<NUM_LIT:2>))])<EOL><DEDENT>return Compound(s)<EOL><DEDENT>def parse_compound_list(s):<EOL><INDENT>for cpd in s.split('<STR_LIT>'):<EOL><INDENT>if cpd == '<STR_LIT>':<EOL><INDENT>continue<EOL><DEDENT>fields = cpd.strip().split('<STR_LIT:U+0020>')<EOL>if len(fields) > <NUM_LIT:2>:<EOL><INDENT>raise ParseError(<EOL>'<STR_LIT>'.format(cpd))<EOL><DEDENT>if len(fields) == <NUM_LIT:1>:<EOL><INDENT>count = <NUM_LIT:1><EOL>compound = parse_compound(fields[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>count = parse_count(fields[<NUM_LIT:0>])<EOL>compound = parse_compound(fields[<NUM_LIT:1>])<EOL><DEDENT>yield compound, count<EOL><DEDENT><DEDENT>cpd_left, cpd_right = s.split('<STR_LIT>')<EOL>left = parse_compound_list(cpd_left.strip())<EOL>right = parse_compound_list(cpd_right.strip())<EOL>return Reaction(Direction.Both, left, right)<EOL>
Parse a KEGG reaction string