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