@@ -25,6 +25,16 @@ class Move(EditOperation):
2525class Delete (EditOperation ):
2626 pass
2727
28+ # Edit script ----------------------------------------------------------------
29+
30+ class EditScript (list ):
31+
32+ def __init__ (self , operations ):
33+ super ().__init__ (operations )
34+
35+ def __repr__ (self ):
36+ return serialize_script (self , indent = 2 )
37+
2838
2939# Serialization --------------------------------
3040
@@ -285,11 +295,11 @@ def json_serialize(edit_script):
285295 else : # Leaf node
286296 new_node_str = ["%s:%s" % new_node , "T" ]
287297
288- edit_ops .append ([operation_name , target_node_str , new_node_str ])
298+ edit_ops .append ([operation_name , target_node_str , new_node_str , operation . position ])
289299
290300 elif operation_name == "Move" :
291301
292- new_node_str = _serialize_node (new_node_index , operation .node )
302+ new_node_str = _json_serialize_node (new_node_index , operation .node )
293303
294304 edit_ops .append ([operation_name , target_node_str , new_node_str , operation .position ])
295305
@@ -299,4 +309,81 @@ def json_serialize(edit_script):
299309 return json .dumps (edit_ops )
300310
301311
302- # Fast deserialize ----------------------------------------------------------------------
312+ # Fast deserialize ----------------------------------------------------------------------
313+
314+ def _json_deserialize_node (node_index , node_info ):
315+
316+ if not isinstance (node_info , list ) and node_info != "T" :
317+ node_id = int (node_info [1 :])
318+ return node_index [node_id ]
319+
320+ node_type , position = node_info [0 ], node_info [1 :]
321+ node_text = None
322+
323+ if ":" in node_type :
324+ node_type , node_text = node_type .split (":" , 1 )
325+
326+ if len (position ) == 4 :
327+ return DASTNode (node_type , ((position [0 ], position [1 ]), (position [2 ], position [3 ])), node_text )
328+
329+ return InsertNode (position [0 ], node_type , node_text )
330+
331+
332+ def _json_deserialize_node_constructor (node_index , cn_info ):
333+ node_type , node_id = cn_info
334+ node_text = None
335+
336+ if ":" in node_type :
337+ node_type , node_text = node_type .split (":" , 1 )
338+
339+ if node_id != "T" :
340+ node_id = int (node_id [1 :])
341+ node_index [node_id ] = InsertNode (node_id , node_type , node_text )
342+ return node_index [node_id ]
343+
344+ return InsertNode (node_id , node_type , node_text )
345+
346+
347+ def _json_deserialize_update (node_index , operation ):
348+ _ , target , update = operation
349+ target = _json_deserialize_node (node_index , target )
350+ return Update (target , update )
351+
352+
353+ def _json_deserialize_insert (node_index , operation ):
354+ _ , target , new_node , position = operation
355+ target = _json_deserialize_node (node_index , target )
356+ new_node = _json_deserialize_node_constructor (node_index , new_node )
357+
358+ return Insert (target , (new_node .type , new_node .text ), position , new_node .node_id )
359+
360+
361+ def _json_deserialize_delete (node_index , operation ):
362+ return Delete (_json_deserialize_node (node_index , operation [1 ]))
363+
364+
365+ def _json_deserialize_move (node_index , operation ):
366+ _ , target , move_node , position = operation
367+ target = _json_deserialize_node (node_index , target )
368+ move_node = _json_deserialize_node (node_index , move_node )
369+ return Move (target , move_node , position )
370+
371+
372+ DESERIALIZE = {
373+ "Update" : _json_deserialize_update ,
374+ "Insert" : _json_deserialize_insert ,
375+ "Delete" : _json_deserialize_delete ,
376+ "Move" : _json_deserialize_move
377+ }
378+
379+
380+ def json_deserialize (edit_json ):
381+ edit_ops = json .loads (edit_json )
382+ output = []
383+ node_index = {}
384+
385+ for operation in edit_ops :
386+ operation_name = operation [0 ]
387+ output .append (DESERIALIZE [operation_name ](node_index , operation ))
388+
389+ return EditScript (output )
0 commit comments