|
- #
- # This example shows how to write a basic JSON parser
- #
- # The code is short and clear, but has good performance.
- # For an explanation, check out the JSON parser tutorial at /docs/json_tutorial.md
- #
-
- import sys
-
- from lark import Lark, inline_args, Transformer
-
- json_grammar = r"""
- ?start: value
-
- ?value: object
- | array
- | string
- | SIGNED_NUMBER -> number
- | "true" -> true
- | "false" -> false
- | "null" -> null
-
- array : "[" [value ("," value)*] "]"
- object : "{" [pair ("," pair)*] "}"
- pair : string ":" value
-
- string : ESCAPED_STRING
-
- %import common.ESCAPED_STRING
- %import common.SIGNED_NUMBER
- %import common.WS
-
- %ignore WS
- """
-
- class TreeToJson(Transformer):
- @inline_args
- def string(self, s):
- return s[1:-1].replace('\\"', '"')
-
- array = list
- pair = tuple
- object = dict
- number = inline_args(float)
-
- null = lambda self, _: None
- true = lambda self, _: True
- false = lambda self, _: False
-
- json_parser = Lark(json_grammar, parser='earley', lexer='standard')
- def parse(x):
- return TreeToJson().transform(json_parser.parse(x))
-
- # json_parser = Lark(json_grammar, parser='lalr', transformer=TreeToJson())
- # parse = json_parser.parse
-
- def test():
- test_json = '''
- {
- "empty_object" : {},
- "empty_array" : [],
- "booleans" : { "YES" : true, "NO" : false },
- "numbers" : [ 0, 1, -2, 3.3, 4.4e5, 6.6e-7 ],
- "strings" : [ "This", [ "And" , "That", "And a \\"b" ] ],
- "nothing" : null
- }
- '''
-
- j = parse(test_json)
- print(j)
- import json
- assert j == json.loads(test_json)
-
- if __name__ == '__main__':
- # test()
- with open(sys.argv[1]) as f:
- print(parse(f.read()))
|