def relex(self, node): if isinstance(node, BOS): return start = node while True: if isinstance(start.symbol, IndentationTerminal): start = start.next_term break if isinstance(start, BOS): start = start.next_term break if start.lookup == "<return>": start = start.next_term break if isinstance(start.symbol, MagicTerminal): start = start.next_term break start = start.prev_term # find end node end = node while True: if isinstance(end.symbol, IndentationTerminal): end = end.prev_term break if isinstance(end, EOS): end = end.prev_term break if isinstance(end.symbol, MagicTerminal): end = end.prev_term break if end.lookup == "<return>": end = end.prev_term break end = end.next_term token = start relex_string = [] if start is end: relex_string = [start.symbol.name] else: while token is not end.next_term: if isinstance(token.symbol, MagicTerminal): # found a language box # start another relexing process after the box next_token = token.next_term self.relex(next_token) break if isinstance(token, EOS): # reached end of language box break relex_string.append(token.symbol.name) token = token.next_term success = self.lex("".join(relex_string)) old_node = start old_x = 0 new_x = 0 after_startnode = False debug_old = [] debug_new = [] for match in success: if after_startnode: if old_node.symbol.name == match[0] and old_node.lookup == match[1]: # XXX optimisation only # from here everything is going to be relexed to the same # XXX check construction location break # 1) len(relexed) == len(old) => update old with relexed # 2) len(relexed) > len(old) => update old with relexed and delete following previous until counts <= # 3) len(relexed) < len(old) => insert token if new_x < old_x: # insert if self.language == "Chemicals": filename = "chemicals/" + node.symbol.name + ".png" if os.path.isfile(filename): additional_node = ImageNode(node, 0) additional_node.image = QImage(filename) old_node.image_src = filename else: additional_node.image = None old_node.image_src = None else: additional_node = TextNode(Terminal(match[0]), -1, [], -1) additional_node.lookup = match[1] old_node.prev_term.parent.insert_after_node(old_node.prev_term, additional_node) old_x += 0 new_x += len(match[0]) debug_old.append("") debug_new.append(match[0]) else: #overwrite old_x += len(old_node.symbol.name) new_x += len(match[0]) debug_old.append(old_node.symbol.name) debug_new.append(match[0]) old_node.symbol.name = match[0] old_node.lookup = match[1] if self.language == "Chemicals": filename = "chemicals/" + old_node.symbol.name + ".png" if os.path.isfile(filename): old_node.image = QImage(filename) old_node.image_src = filename else: old_node.image = None old_node.image_src = None old_node = old_node.next_term # relexed was bigger than old_node => delete as many nodes that fit into len(relexed) while old_x < new_x: if old_x + len(old_node.symbol.name) <= new_x: old_x += len(old_node.symbol.name) delete_node = old_node old_node = delete_node.next_term delete_node.parent.remove_child(delete_node) else: break if old_x != new_x: # sanity check raise AssertionError("old_x(%s) != new_x(%s) %s => %s" % (old_x, new_x, debug_old, debug_new)) return
def relex(self, node): if isinstance(node, BOS): return start = node while True: if isinstance(start.symbol, IndentationTerminal): start = start.next_term break if isinstance(start, BOS): start = start.next_term break if start.lookup == "<return>": start = start.next_term break if isinstance(start.symbol, MagicTerminal): start = start.next_term break start = start.prev_term # find end node end = node while True: if isinstance(end.symbol, IndentationTerminal): end = end.prev_term break if isinstance(end, EOS): end = end.prev_term break if isinstance(end.symbol, MagicTerminal): end = end.prev_term break if end.lookup == "<return>": end = end.prev_term break end = end.next_term token = start relex_string = [] if start is end: relex_string = [start.symbol.name] else: while token is not end.next_term: if isinstance(token.symbol, MagicTerminal): # found a language box # start another relexing process after the box next_token = token.next_term self.relex(next_token) break if isinstance(token, EOS): # reached end of language box break relex_string.append(token.symbol.name) token = token.next_term success = self.lex("".join(relex_string)) old_node = start old_x = 0 new_x = 0 after_startnode = False debug_old = [] debug_new = [] for match in success: if after_startnode: if old_node.symbol.name == match[0] and old_node.lookup == match[1]: # XXX optimisation only # from here everything is going to be relexed to the same # XXX check construction location break # 1) len(relexed) == len(old) => update old with relexed # 2) len(relexed) > len(old) => update old with relexed and delete following previous until counts <= # 3) len(relexed) < len(old) => insert token if new_x < old_x: # insert if self.language == "Chemicals": filename = "chemicals/" + node.symbol.name + ".png" if os.path.isfile(filename): additional_node = ImageNode(node, 0) additional_node.image = QImage(filename) old_node.image_src = filename else: additional_node.image = None old_node.image_src = None else: additional_node = TextNode(Terminal(match[0]), -1, [], -1) additional_node.lookup = match[1] old_node.prev_term.parent.insert_after_node(old_node.prev_term, additional_node) #self.add_node(old_node.prev_term, additional_node) old_x += 0 new_x += len(match[0]) debug_old.append("") debug_new.append(match[0]) else: #overwrite old_x += len(old_node.symbol.name) new_x += len(match[0]) debug_old.append(old_node.symbol.name) debug_new.append(match[0]) old_node.symbol.name = match[0] old_node.lookup = match[1] if self.language == "Chemicals": filename = "chemicals/" + old_node.symbol.name + ".png" if os.path.isfile(filename): old_node.image = QImage(filename) old_node.image_src = filename else: old_node.image = None old_node.image_src = None old_node = old_node.next_term # relexed was bigger than old_node => delete as many nodes that fit into len(relexed) while old_x < new_x: if old_x + len(old_node.symbol.name) <= new_x: old_x += len(old_node.symbol.name) delete_node = old_node old_node = delete_node.next_term delete_node.parent.remove_child(delete_node) else: break if old_x != new_x: # sanity check raise AssertionError("old_x(%s) != new_x(%s) %s => %s" % (old_x, new_x, debug_old, debug_new)) return