Mercurial > lbo > hg > pcombinators
changeset 20:91026ea6211d draft
Fix bad whitespace parse and don't accept bad operator expressions
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Mon, 20 May 2019 22:44:58 +0200 |
parents | 8072bf66cba3 |
children | 4761135ff5f7 |
files | pcombinators/arith_test.py |
diffstat | 1 files changed, 16 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/pcombinators/arith_test.py Sun May 19 21:26:37 2019 +0200 +++ b/pcombinators/arith_test.py Mon May 20 22:44:58 2019 +0200 @@ -15,38 +15,42 @@ def Variable(): """A variable consists of several letters.""" - return Last(Whitespace() + Regex('[a-zA-Z]+[0-9]*')) + return (Skip(Whitespace()) + Regex('[a-zA-Z]+[0-9]*')) def Atom(): """An atom is a variable or a float or a parentheses term.""" - return (Variable() | Parens() | Float()) + return (Variable() | Parens() | (Skip(Whitespace()) + Float())) def Operator(set): """An operator or parenthesis.""" return Last(Skip(Whitespace()) + OneOf(set)) +def operator_result_to_tuple(l): + if len(l) == 1: + return l[0] + elif len(l) == 3: + return tuple(l) + else: + # Parse failed if not either 1 or 3. + raise Exception("Parse failed: Missing operand") + def Power(): - return ( - OptimisticSequence(Last(Atom()), Operator('^'), Last(Atom())) >> - (lambda l: (l[0], l[1], l[2]) if len(l) == 3 else l[0]) - ) + return (OptimisticSequence(Last(Atom()), Operator('^') + Atom()) >> operator_result_to_tuple) class Product(Parser): def parse(self, st): # Try to parse an atom, a product operator, and another product. - p = OptimisticSequence(Power(), Operator('*/'), Product()) - to_tuple = p >> (lambda l: (l[0], l[1], l[2]) if len(l) == 3 else l[0]) - return to_tuple.parse(st) + p = OptimisticSequence(Power(), Operator('*/') + Product()) >> operator_result_to_tuple + return p.parse(st) class Term(Parser): def parse(self, st): # Try to parse a product, then a sum operator, then another term. # OptimisticSequence will just return a product if there is no sum operator. - p = OptimisticSequence(Product(), Operator('+-'), Term()) - to_tuple = p >> (lambda l: (l[0], l[1], l[2]) if len(l) == 3 else l[0]) - return to_tuple.parse(st) + p = OptimisticSequence(Product(), Operator('+-') + Term()) >> operator_result_to_tuple + return p.parse(st) def pretty_print(tpl): # tpl is a (left, op, right) tuple or a scalar.