Source code for lyra.engine.result

from itertools import zip_longest
from typing import List

from lyra.abstract_domains.state import State
from lyra.core.cfg import Node, ControlFlowGraph, Edge


[docs]class AnalysisResult: def __init__(self, cfg: ControlFlowGraph): """Analysis result representation. :param cfg: analyzed control flow graph """ self._cfg = cfg self._result = dict() @property def cfg(self): return self._cfg @property def result(self): return self._result
[docs] def get_node_result(self, node: Node) -> List[State]: """Get the analysis result for a node. :param node: analyzed node :return: list of states representing the result of the analysis for the block """ return self.result[node]
[docs] def set_node_result(self, node: Node, states: List[State]) -> None: """Set the analysis result for a node. :param node: analyzed node :param states: list of states representing the result of the analysis for the block """ self.result[node] = states
def __str__(self): """Analysis result string representation. :return: string representing the result of the analysis """ visited, pending = set(), list() pending.append(self.cfg.in_node) result = [] while pending: current = pending.pop() # retrieve the current pending item if current not in visited: if isinstance(current, Node): # print a node result.append("********* {} *********".format(current)) states = self.get_node_result(current) node = [item for items in zip_longest(states, current.stmts) for item in items if item is not None] result.append("\n".join("{}".format(item) for item in node)) # retrieve out edges of the node and add them to the pending items for edge in self.cfg.out_edges(current): if edge not in visited: pending.append(edge) elif isinstance(current, Edge): result.append("\n{0!s}\n".format(current)) # retrieve target of the edge and add it to the pending items if current.target not in visited: pending.append(current.target) visited.add(current) return "\n".join(res for res in result)