Mercurial > lbo > hg > pcombinators
changeset 31:084d753d5b6a draft
Update parser examples to new model.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 21 May 2019 15:46:41 +0200 |
parents | 56b097b690c2 |
children | 233370104f9d |
files | pcombinators/arith_test.py pcombinators/json_test.py |
diffstat | 2 files changed, 23 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/pcombinators/arith_test.py Tue May 21 15:46:18 2019 +0200 +++ b/pcombinators/arith_test.py Tue May 21 15:46:41 2019 +0200 @@ -15,11 +15,11 @@ def Variable(): """A variable consists of several letters.""" - return (Skip(Whitespace()) + Regex('[a-zA-Z]+[0-9]*')) + return Last(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() | (Skip(Whitespace()) + Float())) + return (Variable() | Parens() | Last(Skip(Whitespace()) + Float())) def Operator(set): """An operator or parenthesis.""" @@ -28,14 +28,14 @@ def operator_result_to_tuple(l): if len(l) == 1: return l[0] - elif len(l) == 3: - return tuple(l) + elif len(l) == 2 and len(l[1]) == 2: + return (l[0], l[1][0], l[1][1]) else: # Parse failed if not either 1 or 3. raise Exception("Parse failed: Missing operand") def Power(): - return (OptimisticSequence(Last(Atom()), Operator('^') + Atom()) >> operator_result_to_tuple) + return (OptimisticSequence(Atom(), Operator('^') + Atom()) >> operator_result_to_tuple) class Product(Parser):
--- a/pcombinators/json_test.py Tue May 21 15:46:18 2019 +0200 +++ b/pcombinators/json_test.py Tue May 21 15:46:41 2019 +0200 @@ -13,6 +13,21 @@ wrapl = lambda l: [l] +class Value(Parser): + """Bare-bones, but fully functioning, JSON parser. Doesn't like escaped quotes. + + Example: + >>> Value().parse(ParseState(my_json_string)) + ({'id': 1.0, + 'name': 'Foo', + 'price': 123.0, + 'tags': ['Bar', 'Eek'], + 'stock': {'warehouse': 300.0, 'retail': 20.0}}, + ParseState({"id":1,"name":"Foo","price":123,"tags":["Bar","Eek"],"stock":{"warehouse":300, "retail":20}}<>)) + """ + def parse(self, st): + return Last(Skip(Whitespace()) + (Dict | List | JString | Float()) + Skip(Whitespace())).parse(st) + # We moved out all the piece parsers out of functions to reduce allocation overhead. # It improves performance by roughly 2x. @@ -37,23 +52,9 @@ # The two-element list is converted to a tuple. entry = (JString + separator + (Value() >> wrapl)) >> (lambda l: tuple(l)) # A mid entry is followed by a comma. -midentry = entry + Skip(String(',') + Whitespace()) +midentry = Last(entry + Skip(String(',') + Skip(Whitespace()))) # A dict is a {, followed by entries, followed by a final entry, followed by a closing } -dct = Skip(String("{")) + Repeat(midentry, -1) + entry + Skip(String("}")) +dct = Flatten( + Skip(String("{")) + ((Repeat(midentry, -1) + entry)) + Skip(String("}"))) # Convert the list of tuples into a dict. Dict = dct >> dict - -class Value(Parser): - """Bare-bones, but fully functioning, JSON parser. Doesn't like escaped quotes. - - Example: - >>> Value().parse(ParseState(my_json_string)) - ({'id': 1.0, - 'name': 'Foo', - 'price': 123.0, - 'tags': ['Bar', 'Eek'], - 'stock': {'warehouse': 300.0, 'retail': 20.0}}, - ParseState({"id":1,"name":"Foo","price":123,"tags":["Bar","Eek"],"stock":{"warehouse":300, "retail":20}}<>)) - """ - def parse(self, st): - return Last(Skip(Whitespace()) + (Dict | List | JString | Float()) + Skip(Whitespace())).parse(st) \ No newline at end of file