Advertisement
Guest User

script.py

a guest
Nov 24th, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.03 KB | None | 0 0
  1. import sys
  2. from os.path import join, dirname, basename
  3. from textx.metamodel import metamodel_from_file
  4. from textx.export import metamodel_export, model_export
  5. import json
  6.  
  7.  
  8. class Node(object):
  9.     def __init__(self, type, label, icon, start, end):
  10.         self.type = type
  11.         self.label = label
  12.         self.icon = icon
  13.         self.start = start
  14.         self.end = end
  15.         self.children = []
  16.  
  17.  
  18. class Tree(object):
  19.     def __init__(self):
  20.         self.text = sys.argv[1]
  21.         self.language_model = self.get_language_model()
  22.         self.outline_model = self.get_outline_model()
  23.         self.nodes = []
  24.         self.start_position_in_lines = []
  25.         self.fill_end_position_in_lines()
  26.         self.visit_rule(self.language_model, 1)
  27.         self.make_tree()
  28.  
  29.     def get_language_model(self):
  30.         language = metamodel_from_file(join(dirname(__file__), 'language.tx'))
  31.         metamodel_export(language, join(dirname(__file__), 'language.dot'))
  32.         grammar_model = language.model_from_str(self.text)
  33.         return grammar_model
  34.  
  35.     def get_outline_model(self):
  36.         this_folder = dirname(__file__)
  37.         language = metamodel_from_file(join(dirname(__file__), 'outline.tx'))
  38.         metamodel_export(language, join(dirname(__file__), 'outline.dot'))
  39.         grammar_model = language.model_from_file(join(this_folder, 'outline.ol'))
  40.         model_export(grammar_model, join(this_folder, 'outline.dot'))
  41.         return grammar_model
  42.  
  43.     def fill_end_position_in_lines(self):
  44.         counter = 0
  45.         for line in self.text.splitlines():
  46.             self.start_position_in_lines.append(counter)
  47.             counter += len(line) + 2
  48.         self.start_position_in_lines.append(sys.maxsize)
  49.  
  50.     def visit_rule(self, rule, mult):
  51.         if (mult == 1):
  52.             subrules = rule._tx_attrs
  53.             values = {}
  54.             for subrule in subrules:
  55.                 child = getattr(rule, subrule)
  56.                 attr = subrules[subrule]
  57.                 if attr.cont == False:
  58.                     if self.convert_mult(attr.mult) == 1:
  59.                         self.proccess_rule(values, rule, child.name)
  60.                         continue
  61.                     else:
  62.                         for item in child:
  63.                             self.proccess_rule(values, rule, item.name)
  64.                         continue
  65.                 if child == None:
  66.                     continue
  67.                 if attr.ref == False:
  68.                     values[subrule] = child
  69.                     continue
  70.                 self.visit_rule(child, self.convert_mult(attr.mult))
  71.             self.proccess_rule(values, rule)
  72.         else:
  73.             for item in rule:
  74.                 self.visit_rule(item, 1)
  75.             pass
  76.  
  77.     def convert_mult(self, mult):
  78.         if (mult == '1'):
  79.             return 1
  80.         else:
  81.             return 2
  82.  
  83.     def proccess_rule(self, values, rule, label=None):
  84.         rule_name = type(rule).__name__
  85.         if len(values) == 0 and label == None:
  86.             return
  87.         for outline_rule in self.outline_model.rules:
  88.             if outline_rule.name == rule_name:
  89.                 if label == None:
  90.                     label = self.get_label(values, outline_rule.choices.label[0].names)
  91.                 node = Node(rule_name, label, basename(outline_rule.choices.icon[0].path), rule._tx_position, rule._tx_position_end)
  92.                 self.nodes.append(node)
  93.  
  94.     def get_label(self, values, names):
  95.         label = ""
  96.         for name in names:
  97.             for key, value in values.items():
  98.                 if name.id == key:
  99.                     label += value
  100.                     break
  101.                 if name.string != '':
  102.                     label += name.string
  103.                     break
  104.         return label
  105.  
  106.     def make_tree(self):
  107.         children = self.determine_parent_child_relation()
  108.         for node in self.nodes:
  109.             self.remove_grandchildren(node)
  110.         for child in children:
  111.             self.nodes.remove(child)
  112.         self.tree = self.make_nodes()
  113.  
  114.     def determine_parent_child_relation(self):
  115.         children = []
  116.         for parent in self.nodes:
  117.             for child in self.nodes:
  118.                 if self.is_parent_child_relation_valid(parent, child):
  119.                     children.append(child)
  120.                     parent.children.append(child)
  121.         return children
  122.  
  123.     def is_parent_child_relation_valid(self, parent, child):
  124.         if parent.start < child.start and parent.end > child.end:
  125.             return True
  126.         return False
  127.  
  128.     def remove_grandchildren(self, node):
  129.         children = []
  130.         for child in node.children:
  131.             for grandchild in child.children:
  132.                 if grandchild not in children:
  133.                     children.append(grandchild)
  134.         for child in children:
  135.             node.children.remove(child)
  136.  
  137.     def make_nodes(self, nodes=None):
  138.         objects = []
  139.         if nodes == None:
  140.             nodes = self.nodes
  141.         else:
  142.             nodes = nodes.children
  143.         for node in nodes:
  144.             obj = {}
  145.             obj['type'] = node.type
  146.             obj['label'] = node.label
  147.             obj['icon'] = node.icon
  148.             obj['children'] = self.make_nodes(node)
  149.             point = self.convert_position_in_point(node.start)
  150.             obj['start_line'] = point['row']
  151.             obj['start_point_in_line'] = point['column']
  152.             point = self.convert_position_in_point(node.end)
  153.             obj['end_line'] = point['row']
  154.             obj['end_point_in_line'] = point['column']
  155.             objects.append(obj)
  156.         return objects
  157.  
  158.     def convert_position_in_point(self, position):
  159.         point = {}
  160.         for line in range(len(self.start_position_in_lines)):
  161.             if position < self.start_position_in_lines[line]:
  162.                 point['row'] = line - 1
  163.                 point['column'] = position - self.start_position_in_lines[line - 1]
  164.                 break
  165.         return point
  166.  
  167.  
  168. tree = Tree()
  169. print(json.dumps(tree.tree))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement