def _parse_formula(s):
scanner = re.compile(r'''<STR_LIT>''', re.DOTALL | re.VERBOSE)<EOL>def transform_subformula(form):<EOL><INDENT>"""<STR_LIT>"""<EOL>if isinstance(form, dict) and len(form) == <NUM_LIT:1>:<EOL><INDENT>element, value = next(iteritems(form))<EOL>if isinstance(element, Radical):<EOL><INDENT>return Radical('<STR_LIT>'.format(element.symbol, value))<EOL><DEDENT><DEDENT>return form<EOL><DEDENT>stack = []<EOL>formula = {}<EOL>expect_count = False<EOL>def close(formula, count=<NUM_LIT:1>):<EOL><INDENT>if len(stack) == <NUM_LIT:0>:<EOL><INDENT>raise ParseError('<STR_LIT>')<EOL><DEDENT>subformula = transform_subformula(formula)<EOL>if isinstance(subformula, dict):<EOL><INDENT>subformula = Formula(subformula)<EOL><DEDENT>formula = stack.pop()<EOL>if subformula not in formula:<EOL><INDENT>formula[subformula] = <NUM_LIT:0><EOL><DEDENT>formula[subformula] += count<EOL>return formula<EOL><DEDENT>for match in re.finditer(scanner, s):<EOL><INDENT>(whitespace, group, element, number, variable, end,<EOL>error) = match.groups()<EOL>if error is not None:<EOL><INDENT>raise ParseError(<EOL>'<STR_LIT>'.format(match.group(<NUM_LIT:0>)),<EOL>span=(match.start(), match.end()))<EOL><DEDENT>elif whitespace is not None:<EOL><INDENT>continue<EOL><DEDENT>elif group is not None and group == '<STR_LIT:(>':<EOL><INDENT>if expect_count:<EOL><INDENT>formula = close(formula)<EOL><DEDENT>stack.append(formula)<EOL>formula = {}<EOL>expect_count = False<EOL><DEDENT>elif group is not None and group == '<STR_LIT:)>':<EOL><INDENT>if expect_count:<EOL><INDENT>formula = close(formula)<EOL><DEDENT>expect_count = True<EOL><DEDENT>elif element is not None:<EOL><INDENT>if expect_count:<EOL><INDENT>formula = close(formula)<EOL><DEDENT>stack.append(formula)<EOL>if element in '<STR_LIT>':<EOL><INDENT>formula = Radical(element)<EOL><DEDENT>else:<EOL><INDENT>formula = Atom(element)<EOL><DEDENT>expect_count = True<EOL><DEDENT>elif number is not None and expect_count:<EOL><INDENT>formula = close(formula, int(number))<EOL>expect_count = False<EOL><DEDENT>elif variable is not None and expect_count:<EOL><INDENT>formula = close(formula, Expression(variable))<EOL>expect_count = False<EOL><DEDENT>elif end is not None:<EOL><INDENT>if expect_count:<EOL><INDENT>formula = close(formula)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ParseError(<EOL>'<STR_LIT>'.format(match.group(<NUM_LIT:0>)),<EOL>span=(match.start(), match.end()))<EOL><DEDENT><DEDENT>if len(stack) > <NUM_LIT:0>:<EOL><INDENT>raise ParseError('<STR_LIT>')<EOL><DEDENT>return Formula(formula)<EOL>
Parse formula string.