changeset 25:9831b7c577a3 draft

Comment on JSON parser.
author Lewin Bormann <lbo@spheniscida.de>
date Tue, 21 May 2019 01:18:21 +0200
parents 4e31b0326501
children 25aab2c2a695
files pcombinators/json_test.py
diffstat 1 files changed, 22 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/pcombinators/json_test.py	Tue May 21 00:57:34 2019 +0200
+++ b/pcombinators/json_test.py	Tue May 21 01:18:21 2019 +0200
@@ -13,9 +13,13 @@
     return Last(Skip(String('"')) + NoneInSet('"') + Skip(String('"')))
 
 def List():
-    wrapl = lambda l: [l] #if isinstance(l, list) else l
-    entry = (Skip(Whitespace()) + (Value()))
+    wrapl = lambda l: [l]
+    # An entry is any value.
+    entry = Value()
+    # A mid entry is a value followed by a comma.
     midentry = entry + Skip(String(','))
+    # A list is a [, followed by mid entries, followed by a final entry, and a
+    # closing ]. The list is wrapped in a list to prevent merging in other parsers.
     return (
             Skip(String('[')) +
             Repeat(midentry, -1) +
@@ -24,14 +28,30 @@
 
 def Dict():
     wrapl = lambda l: [l]
+    # A separator is whitespace, a colon, and more whitespace (Whitespace() also accepts empty string)
     separator = Skip((Whitespace() + String(":") + Whitespace()))
+    # Entry is a String followed by a separator and a value. Wrap the value in a list to prevent merging.
+    # 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())
+    # 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("}"))
+    # Convert the list of tuples into a dict.
     fulldict = dct >> dict
     return fulldict
 
 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