1+ from subprocess import Popen , PIPE
2+
3+ from larkjs .__main__ import generate_js_standalone
4+ from lark import Lark
5+
6+ TEST_CODE = r"""
7+
8+ const parser = get_parser({transformer})
9+
10+ console.log(JSON.stringify(parser.parse(input_text)))
11+ """
12+
13+
14+ class JsParser :
15+ def __init__ (self , lark_instance ):
16+ self .code = generate_js_standalone (lark_instance )
17+
18+ def parse (self , text , transformer = None ):
19+ js_code = self .code
20+ js_code += 'const input_text = `' + text + '`;'
21+ if transformer :
22+ js_code += transformer
23+ js_code += TEST_CODE
24+
25+ p = Popen (["node" , "-" ], stdin = PIPE , stdout = PIPE , stderr = PIPE )
26+ stdout , stderr = p .communicate (js_code .encode ())
27+
28+ if stderr :
29+ raise ValueError (stderr .decode ())
30+ return stdout .decode ()
31+
32+
33+
34+
35+ def test_json_parser ():
36+ parser = Lark .open ('json.lark' , rel_to = __file__ , parser = "lalr" )
37+ js_parser = JsParser (parser )
38+
39+ transformer = """
40+ let transformer = {
41+ number: ([n]) => parseFloat(n.value),
42+ string: ([s]) => s.value.slice(1, -1),
43+ array: Array.from,
44+ pair: Array.from,
45+ object: Object.fromEntries,
46+
47+ null: () => null,
48+ true: () => true,
49+ false: () => false,
50+ }
51+ """
52+
53+ text = r"""
54+ {
55+ "empty_object" : {},
56+ "empty_array" : [],
57+ "booleans" : { "YES" : true, "NO" : false },
58+ "numbers" : [ 0, 1, -2, 3.3, 4.4e5, 6.6e-7 ],
59+ "strings" : [ "This", [ "And" , "That", "And a \\"b" ] ],
60+ "nothing" : null
61+ }
62+ """
63+
64+ res = js_parser .parse (text , transformer )
65+ expected = r"""{"empty_object":{},"empty_array":[],"booleans":{"YES":true,"NO":false},"numbers":[0,1,-2,3.3,440000,6.6e-7],"strings":["This",["And","That","And a \\\"b"]],"nothing":null}"""
66+ assert res .strip () == expected
67+
68+ def test ():
69+ test_json_parser ()
70+
71+ if __name__ == '__main__' :
72+ test ()
0 commit comments