mirror of https://github.com/lark-parser/lark.git
79 lines
1.8 KiB
Python
79 lines
1.8 KiB
Python
#
|
|
# 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()))
|
|
|