nodes: 0, module; 1, function_definition; 2, function_name:reading_order; 3, parameters; 4, block; 5, identifier:e1; 6, identifier:e2; 7, expression_statement; 8, expression_statement; 9, expression_statement; 10, if_statement; 11, return_statement; 12, comment:"""
      A comparator to sort bboxes from top to bottom, left to right
      """; 13, assignment; 14, assignment; 15, boolean_operator; 16, block; 17, call; 18, identifier:b1; 19, attribute; 20, identifier:b2; 21, attribute; 22, comparison_operator:round(b1[y0]) == round(b2[y0]); 23, comparison_operator:round(b1[y1]) == round(b2[y1]); 24, return_statement; 25, identifier:float_cmp; 26, argument_list; 27, identifier:e1; 28, identifier:bbox; 29, identifier:e2; 30, identifier:bbox; 31, call; 32, call; 33, call; 34, call; 35, call; 36, subscript; 37, subscript; 38, identifier:round; 39, argument_list; 40, identifier:round; 41, argument_list; 42, identifier:round; 43, argument_list; 44, identifier:round; 45, argument_list; 46, identifier:float_cmp; 47, argument_list; 48, identifier:b1; 49, identifier:y0; 50, identifier:b2; 51, identifier:y0; 52, subscript; 53, subscript; 54, subscript; 55, subscript; 56, subscript; 57, subscript; 58, identifier:b1; 59, identifier:y0; 60, identifier:b2; 61, identifier:y0; 62, identifier:b1; 63, identifier:y1; 64, identifier:b2; 65, identifier:y1; 66, identifier:b1; 67, identifier:x0; 68, identifier:b2; 69, identifier:x0
code: def reading_order(e1, e2):
      """
      A comparator to sort bboxes from top to bottom, left to right
      """
      b1 = e1.bbox
      b2 = e2.bbox
      if round(b1[y0]) == round(b2[y0]) or round(b1[y1]) == round(b2[y1]):
          return float_cmp(b1[x0], b2[x0])
      return float_cmp(b1[y0], b2[y0])