Mercurial > lbo > hg > pcombinators
changeset 24:4e31b0326501 draft
Implement full JSON parser with pcombinators.
It doesn't work well on escaped strings containing \", but the rest seems to go nicely.
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Tue, 21 May 2019 00:57:34 +0200 |
parents | c7ebd52fe5cb |
children | 9831b7c577a3 |
files | pcombinators/json_test.py |
diffstat | 1 files changed, 37 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pcombinators/json_test.py Tue May 21 00:57:34 2019 +0200 @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Example on how to write a JSON parser. + +@author: lbo +""" + +from combinators import * +from primitives import * + +def JString(): + return Last(Skip(String('"')) + NoneInSet('"') + Skip(String('"'))) + +def List(): + wrapl = lambda l: [l] #if isinstance(l, list) else l + entry = (Skip(Whitespace()) + (Value())) + midentry = entry + Skip(String(',')) + return ( + Skip(String('[')) + + Repeat(midentry, -1) + + entry + + Skip(String(']'))) >> wrapl # Wrap list inside another list to protect it from flattening. + +def Dict(): + wrapl = lambda l: [l] + separator = Skip((Whitespace() + String(":") + Whitespace())) + entry = (JString() + separator + (Value() >> wrapl)) >> (lambda l: tuple(l)) + midentry = entry + Skip(String(',') + Whitespace()) + dct = Skip(String("{")) + Repeat(midentry, -1) + entry + Skip(String("}")) + fulldict = dct >> dict + return fulldict + +class Value(Parser): + + def parse(self, st): + return Last(Skip(Whitespace()) + (Dict() | List() | JString() | Float()) + Skip(Whitespace())).parse(st) \ No newline at end of file