mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-21 10:51:35 +00:00
board_inspector: refactor tree visitors and transformers
Tree visitors usually have a fixed direction (either top-down or bottom-up) and invoking a visitor with a wrong direction typically leads to unintended behavior. However, the current implementation exposes both `visit_topdown` and `visit_bottomup` methods to users, allowing callers to invoke the visitors in an undesigned way. The same issue exists in the implementation of transformers. This patch refactors the base classes of visitors and transformers so that they require an explicit direction from their sub-classes to initialize. Callers of the visitors and transformers are now expected to invoke the `visit` or `transform` methods without assuming the correct direction of the visitor or transformer. The original `visit_topdown` or `visit_bottomup` methods (or their transformer counterparts) are now used to initialize the `visit` method and can be used by the subclasses in case those subclasses visits the tree in a customized manner. Tracked-On: #6287 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
55554e7d56
commit
e91ace7341
@ -8,7 +8,7 @@ import logging
|
|||||||
from . import grammar
|
from . import grammar
|
||||||
from .context import *
|
from .context import *
|
||||||
from .exception import *
|
from .exception import *
|
||||||
from .tree import Tree, Transformer
|
from .tree import Tree, Transformer, Direction
|
||||||
|
|
||||||
class Factory:
|
class Factory:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -406,7 +406,7 @@ class OptionFactory(Factory):
|
|||||||
|
|
||||||
class DeferredExpansion(Transformer):
|
class DeferredExpansion(Transformer):
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
super().__init__()
|
super().__init__(Direction.TOPDOWN)
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
nodes = ["DefScope", "DefDevice", "DefMethod", "DefPowerRes", "DefProcessor", "DefThermalZone",
|
nodes = ["DefScope", "DefDevice", "DefMethod", "DefPowerRes", "DefProcessor", "DefThermalZone",
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
# SPDX-License-Identifier: BSD-3-Clause
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
#
|
#
|
||||||
|
|
||||||
|
from enum import Enum
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
from . import grammar
|
from . import grammar
|
||||||
@ -44,38 +45,54 @@ class Tree:
|
|||||||
setattr(self, elem, self.children[i])
|
setattr(self, elem, self.children[i])
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
class Visitor:
|
class Direction(Enum):
|
||||||
def __init__(self):
|
TOPDOWN = 1
|
||||||
self.depth = 0
|
BOTTOMUP = 2
|
||||||
|
CUSTOMIZED = 3
|
||||||
|
|
||||||
def __visit(self, tree):
|
class Visitor:
|
||||||
|
def __init__(self, direction):
|
||||||
|
self.depth = 0
|
||||||
|
if direction == Direction.TOPDOWN:
|
||||||
|
self.visit = self._visit_topdown
|
||||||
|
elif direction == Direction.BOTTOMUP:
|
||||||
|
self.visit = self._visit_bottomup
|
||||||
|
|
||||||
|
def __visit_node(self, tree):
|
||||||
fn = getattr(self, tree.label, None)
|
fn = getattr(self, tree.label, None)
|
||||||
if not fn:
|
if not fn:
|
||||||
fn = getattr(self, "default", None)
|
fn = getattr(self, "default", None)
|
||||||
if fn:
|
if fn:
|
||||||
fn(tree)
|
fn(tree)
|
||||||
|
|
||||||
def visit_topdown(self, tree):
|
def _visit_topdown(self, tree):
|
||||||
self.__visit(tree)
|
self.__visit_node(tree)
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for child in tree.children:
|
for child in tree.children:
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
self.visit_topdown(child)
|
self.visit(child)
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
|
|
||||||
def visit_bottomup(self, tree):
|
def _visit_bottomup(self, tree):
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for child in tree.children:
|
for child in tree.children:
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
self.visit_bottomup(child)
|
self.visit(child)
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
self.__visit(tree)
|
self.__visit_node(tree)
|
||||||
|
|
||||||
|
def visit(self, tree):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
class Transformer:
|
class Transformer:
|
||||||
def __init__(self):
|
def __init__(self, direction):
|
||||||
self.depth = 0
|
self.depth = 0
|
||||||
|
if direction == Direction.TOPDOWN:
|
||||||
|
self.transform = self._transform_topdown
|
||||||
|
elif direction == Direction.BOTTOMUP:
|
||||||
|
self.transform = self._transform_bottomup
|
||||||
|
|
||||||
def __transform(self, tree):
|
def __transform_node(self, tree):
|
||||||
fn = getattr(self, tree.label, None)
|
fn = getattr(self, tree.label, None)
|
||||||
if not fn:
|
if not fn:
|
||||||
fn = getattr(self, "default", None)
|
fn = getattr(self, "default", None)
|
||||||
@ -84,22 +101,25 @@ class Transformer:
|
|||||||
else:
|
else:
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def transform_topdown(self, tree):
|
def _transform_topdown(self, tree):
|
||||||
new_tree = self.__transform(tree)
|
new_tree = self.__transform_node(tree)
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for i, child in enumerate(tree.children):
|
for i, child in enumerate(tree.children):
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
tree.children[i] = self.transform_topdown(child)
|
tree.children[i] = self.transform(child)
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
return new_tree
|
return new_tree
|
||||||
|
|
||||||
def transform_bottomup(self, tree):
|
def _transform_bottomup(self, tree):
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for i, child in enumerate(tree.children):
|
for i, child in enumerate(tree.children):
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
tree.children[i] = self.transform_bottomup(child)
|
tree.children[i] = self.transform(child)
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
return self.__transform(tree)
|
return self.__transform_node(tree)
|
||||||
|
|
||||||
|
def transform(self, tree):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
class Interpreter:
|
class Interpreter:
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from .tree import Visitor
|
from .tree import Visitor, Direction
|
||||||
from . import grammar
|
from . import grammar
|
||||||
|
|
||||||
class PrintLayoutVisitor(Visitor):
|
class PrintLayoutVisitor(Visitor):
|
||||||
@ -13,6 +13,9 @@ class PrintLayoutVisitor(Visitor):
|
|||||||
def __is_printable(s):
|
def __is_printable(s):
|
||||||
return all(ord(c) >= 0x20 and ord(c) < 0xFF for c in s)
|
return all(ord(c) >= 0x20 and ord(c) < 0xFF for c in s)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(Direction.TOPDOWN)
|
||||||
|
|
||||||
def default(self, tree):
|
def default(self, tree):
|
||||||
indent = " " * self.depth
|
indent = " " * self.depth
|
||||||
print(f"{indent}{tree.label}", end="")
|
print(f"{indent}{tree.label}", end="")
|
||||||
@ -30,7 +33,7 @@ class PrintLayoutVisitor(Visitor):
|
|||||||
|
|
||||||
class ConditionallyUnregisterSymbolVisitor(Visitor):
|
class ConditionallyUnregisterSymbolVisitor(Visitor):
|
||||||
def __init__(self, interpreter):
|
def __init__(self, interpreter):
|
||||||
super().__init__()
|
super().__init__(Direction.CUSTOMIZED)
|
||||||
self.context = interpreter.context
|
self.context = interpreter.context
|
||||||
self.interpreter = interpreter
|
self.interpreter = interpreter
|
||||||
self.conditionally_hidden = False
|
self.conditionally_hidden = False
|
||||||
@ -48,7 +51,7 @@ class ConditionallyUnregisterSymbolVisitor(Visitor):
|
|||||||
self.context.unregister_object(realpath)
|
self.context.unregister_object(realpath)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def visit_topdown(self, tree):
|
def visit(self, tree):
|
||||||
if not self.conditionally_hidden and tree.label == "DefIfElse":
|
if not self.conditionally_hidden and tree.label == "DefIfElse":
|
||||||
self.context.change_scope(tree.scope)
|
self.context.change_scope(tree.scope)
|
||||||
cond = self.interpreter.interpret(tree.children[1]).get()
|
cond = self.interpreter.interpret(tree.children[1]).get()
|
||||||
@ -57,25 +60,25 @@ class ConditionallyUnregisterSymbolVisitor(Visitor):
|
|||||||
self.depth += 1
|
self.depth += 1
|
||||||
if cond:
|
if cond:
|
||||||
if hasattr(tree, "TermList"):
|
if hasattr(tree, "TermList"):
|
||||||
self.visit_topdown(tree.TermList)
|
self.visit(tree.TermList)
|
||||||
if hasattr(tree, "DefElse") and tree.DefElse:
|
if hasattr(tree, "DefElse") and tree.DefElse:
|
||||||
self.conditionally_hidden = True
|
self.conditionally_hidden = True
|
||||||
self.visit_topdown(tree.DefElse)
|
self.visit(tree.DefElse)
|
||||||
self.conditionally_hidden = False
|
self.conditionally_hidden = False
|
||||||
else:
|
else:
|
||||||
if hasattr(tree, "TermList"):
|
if hasattr(tree, "TermList"):
|
||||||
self.conditionally_hidden = True
|
self.conditionally_hidden = True
|
||||||
self.visit_topdown(tree.TermList)
|
self.visit(tree.TermList)
|
||||||
self.conditionally_hidden = False
|
self.conditionally_hidden = False
|
||||||
if hasattr(tree, "DefElse") and tree.DefElse:
|
if hasattr(tree, "DefElse") and tree.DefElse:
|
||||||
self.visit_topdown(tree.DefElse)
|
self.visit(tree.DefElse)
|
||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
elif tree.label not in ["DefMethod"]:
|
elif tree.label not in ["DefMethod"]:
|
||||||
super().visit_topdown(tree)
|
self._visit_topdown(tree)
|
||||||
|
|
||||||
class GenerateBinaryVisitor(Visitor):
|
class GenerateBinaryVisitor(Visitor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__(Direction.BOTTOMUP)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __format_length(length):
|
def __format_length(length):
|
||||||
|
@ -27,7 +27,7 @@ def DSDT(val):
|
|||||||
context.switch_stream(t)
|
context.switch_stream(t)
|
||||||
tree = Tree()
|
tree = Tree()
|
||||||
AMLCode.parse(context, tree)
|
AMLCode.parse(context, tree)
|
||||||
tree = DeferredExpansion(context).transform_topdown(tree)
|
tree = DeferredExpansion(context).transform(tree)
|
||||||
context.trees[os.path.basename(t)] = tree
|
context.trees[os.path.basename(t)] = tree
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
context.current_stream.dump()
|
context.current_stream.dump()
|
||||||
@ -36,5 +36,5 @@ def DSDT(val):
|
|||||||
context.skip_external_on_lookup()
|
context.skip_external_on_lookup()
|
||||||
visitor = ConditionallyUnregisterSymbolVisitor(ConcreteInterpreter(context))
|
visitor = ConditionallyUnregisterSymbolVisitor(ConcreteInterpreter(context))
|
||||||
for tree in context.trees.values():
|
for tree in context.trees.values():
|
||||||
visitor.visit_topdown(tree)
|
visitor.visit(tree)
|
||||||
return context
|
return context
|
||||||
|
Loading…
Reference in New Issue
Block a user