Mercurial > lbo > hg > pcombinators
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