1# Copyright (C) 2021-2022 Intel Corporation. 2# 3# SPDX-License-Identifier: BSD-3-Clause 4# 5 6from enum import Enum 7from copy import copy 8 9from . import grammar 10 11class Tree: 12 def __init__(self, label=None, children=[]): 13 self.label = label 14 self.children = copy(children) 15 self.scope = None 16 17 self.structure = None 18 19 self.package_range = None 20 21 self.deferred_range = None 22 self.context_scope = None 23 self.factory = None 24 25 def append_child(self, child): 26 self.children.append(child) 27 28 def register_structure(self, structure): 29 self.structure = structure 30 31 def complete_parsing(self): 32 i = 0 33 for elem in self.structure: 34 if isinstance(elem, str): 35 if elem.endswith("?"): 36 if i < len(self.children): 37 setattr(self, elem[:-1], self.children[i]) 38 else: 39 setattr(self, elem[:-1], None) 40 break 41 elif elem.endswith("*"): 42 setattr(self, elem[:-1] + "s", self.children[i:]) 43 break 44 else: 45 setattr(self, elem, self.children[i]) 46 i += 1 47 48class Direction(Enum): 49 TOPDOWN = 1 50 BOTTOMUP = 2 51 CUSTOMIZED = 3 52 53class Visitor: 54 def __init__(self, direction): 55 self.depth = 0 56 if direction == Direction.TOPDOWN: 57 self.visit = self._visit_topdown 58 elif direction == Direction.BOTTOMUP: 59 self.visit = self._visit_bottomup 60 61 def __visit_node(self, tree): 62 fn = getattr(self, tree.label, None) 63 if not fn: 64 fn = getattr(self, "default", None) 65 if fn: 66 return fn(tree) 67 else: 68 return True 69 70 def _visit_topdown(self, tree): 71 go_on = self.__visit_node(tree) 72 if go_on != False: 73 self.depth += 1 74 for child in tree.children: 75 if isinstance(child, Tree): 76 self.visit(child) 77 self.depth -= 1 78 79 def _visit_bottomup(self, tree): 80 self.depth += 1 81 for child in tree.children: 82 if isinstance(child, Tree): 83 self.visit(child) 84 self.depth -= 1 85 self.__visit_node(tree) 86 87 def visit(self, tree): 88 raise NotImplementedError 89 90class Transformer: 91 def __init__(self, direction): 92 self.depth = 0 93 if direction == Direction.TOPDOWN: 94 self.transform = self._transform_topdown 95 elif direction == Direction.BOTTOMUP: 96 self.transform = self._transform_bottomup 97 98 def __transform_node(self, tree): 99 fn = getattr(self, tree.label, None) 100 if not fn: 101 fn = getattr(self, "default", None) 102 if fn: 103 return fn(tree) 104 else: 105 return tree 106 107 def _transform_topdown(self, tree): 108 new_tree = self.__transform_node(tree) 109 self.depth += 1 110 for i, child in enumerate(tree.children): 111 if isinstance(child, Tree): 112 tree.children[i] = self.transform(child) 113 self.depth -= 1 114 return new_tree 115 116 def _transform_bottomup(self, tree): 117 self.depth += 1 118 for i, child in enumerate(tree.children): 119 if isinstance(child, Tree): 120 tree.children[i] = self.transform(child) 121 self.depth -= 1 122 return self.__transform_node(tree) 123 124 def transform(self, tree): 125 raise NotImplementedError 126 127class Interpreter: 128 def __init__(self, context): 129 self.context = context 130 131 def interpret(self, expr): 132 assert isinstance(expr, Tree) 133 fn = getattr(self, expr.label, None) 134 if not fn: 135 fn = getattr(self, "default", None) 136 if fn: 137 return fn(expr) 138 else: 139 raise NotImplementedError(f"don't know how to interpret a tree node with label {expr.label}") 140