diff --git a/systems/errors.py b/systems/errors.py index d867f77..a4fc70f 100644 --- a/systems/errors.py +++ b/systems/errors.py @@ -47,6 +47,10 @@ def __str__(self): return "%s for formula '%s'" % (self.__class__.__name__, self.formula) +class MismatchedParens(FormulaError): + pass + + class CircularReferences(IllegalSystemException): def __init__(self, cycle, graph): self.cycle = cycle diff --git a/systems/lexer.py b/systems/lexer.py index 1626bcb..80a1a28 100644 --- a/systems/lexer.py +++ b/systems/lexer.py @@ -67,7 +67,13 @@ def lex_formula(txt): prev_tokens = groups.pop() prev_tokens.append((TOKEN_FORMULA, tokens)) tokens = prev_tokens - elif c in (WHITESPACE, NEWLINE): + elif c == WHITESPACE: + if acc: + tokens.append(lex_value(acc)) + acc = "" + elif c == NEWLINE: + if groups: + raise systems.errors.MismatchedParens(txt) if acc: tokens.append(lex_value(acc)) acc = "" diff --git a/tests/test_parse.py b/tests/test_parse.py index e5bf94c..ef59c1a 100644 --- a/tests/test_parse.py +++ b/tests/test_parse.py @@ -51,7 +51,7 @@ def test_parse_complex_formula(self): names = ['Hires', 'Developers', 'Ideas', 'Projects', 'Started', 'Finished'] for name in names: - self.assertEquals(name, model.get_stock(name).name) + self.assertEqual(name, model.get_stock(name).name) results = model.run(rounds=10) for row in results: @@ -128,6 +128,16 @@ def test_parens(self): self.assertEqual(7.5, final['C']) self.assertEqual(40, final['D']) + def test_missing_parens(self): + "There is a missing paren in the rate definition" + txt = """ + [A] + A > B @ Rate(1 * (1 + (1 * 1)) + """ + with self.assertRaises(systems.errors.MismatchedParens): + m = parse.parse(txt) + results = m.run() + def test_conflicting_stock_values(self): txt = """ a(10) > b @ 1