Compare commits
19 Commits
530c597fc1
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c83fcc4d47 | ||
|
|
9462ccd3ed | ||
|
|
438447e6de | ||
|
|
605eaf3278 | ||
|
|
de46c67129 | ||
|
|
691d6eba8c | ||
|
|
8a40cb2636 | ||
|
|
9c18e5e044 | ||
|
|
d3b518974c | ||
|
|
d1bfba81f0 | ||
|
|
f0877b5685 | ||
|
|
add07249dc | ||
|
|
188cba7fa6 | ||
|
|
51028555de | ||
|
|
3abe8581b5 | ||
|
|
489f385161 | ||
|
|
c66222050b | ||
|
|
36ef2fd23d | ||
|
|
dfd4b4f305 |
BIN
PortfolioFormular2025_Signed.pdf
Normal file
BIN
PortfolioFormular2025_Signed.pdf
Normal file
Binary file not shown.
1
Project-02-03-04-05/README.md
Normal file
1
Project-02-03-04-05/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Author: Jan-Niclas Loosen (1540907)
|
||||||
BIN
Project-02-03-04-05/Source.gv.png
Normal file
BIN
Project-02-03-04-05/Source.gv.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 301 KiB |
128
Project-02-03-04-05/cfa/BackwardAnalysis.py
Normal file
128
Project-02-03-04-05/cfa/BackwardAnalysis.py
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from collections import deque
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
import cfg_build
|
||||||
|
import syntax
|
||||||
|
from cfg.CFG_Node import CFG_START
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
|
||||||
|
GLOBAL_SCOPE = ""
|
||||||
|
|
||||||
|
# A scoped variable: the function it belongs to, and its name.
|
||||||
|
# The scope is GLOBAL_SCOPE ("") for variables outside any function.
|
||||||
|
# e.g. ("f", "x") → variable "x" defined in function "f"
|
||||||
|
# ("", "x") → variable "x" at global scope
|
||||||
|
Var = tuple[str, str]
|
||||||
|
|
||||||
|
class BackwardAnalysis:
|
||||||
|
def __init__(self, cfg: "CFG") -> None:
|
||||||
|
self.cfg = cfg
|
||||||
|
self.uses: dict[int, set[Var]] = {}
|
||||||
|
self.defs: dict[int, set[Var]] = {}
|
||||||
|
|
||||||
|
self.__funcs: dict[str, tuple] = dict(cfg_build.FUNCTIONS)
|
||||||
|
self.__func_parent, self._func_params = self.__collect_function_metadata()
|
||||||
|
self.func_scope: dict[int, str] = self.__compute_function_scope()
|
||||||
|
self.__extract_uses_and_defs()
|
||||||
|
|
||||||
|
# Walk the AST and collect function-parent and parameter information.
|
||||||
|
def __collect_function_metadata(self) -> tuple[dict[str, str | None], dict[str, tuple[str, ...]]]:
|
||||||
|
func_parent: dict[str, str | None] = {}
|
||||||
|
func_params: dict[str, tuple[str, ...]] = {}
|
||||||
|
|
||||||
|
def visit(expr: syntax.EXPRESSION | None, current_func: str | None) -> None:
|
||||||
|
if expr is None:
|
||||||
|
return
|
||||||
|
if isinstance(expr, syntax.LET):
|
||||||
|
decls = expr.decl if isinstance(expr.decl, list) else [expr.decl]
|
||||||
|
# Register metadata for each declared function.
|
||||||
|
for d in decls:
|
||||||
|
if isinstance(d, syntax.DECL):
|
||||||
|
func_parent[d.f_name] = current_func
|
||||||
|
func_params[d.f_name] = tuple(d.params)
|
||||||
|
# Recurse into function bodies and the in-expression.
|
||||||
|
for d in decls:
|
||||||
|
if isinstance(d, syntax.DECL):
|
||||||
|
visit(d.body, d.f_name)
|
||||||
|
else:
|
||||||
|
visit(d, current_func)
|
||||||
|
visit(expr.body, current_func)
|
||||||
|
return
|
||||||
|
for _, child in expr.children():
|
||||||
|
visit(child, current_func)
|
||||||
|
|
||||||
|
visit(self.cfg.ast, None)
|
||||||
|
return func_parent, func_params
|
||||||
|
|
||||||
|
# Calculates the scope (in which function is it?) of each node in the CFG.
|
||||||
|
def __compute_function_scope(self) -> dict[int, str]:
|
||||||
|
# The first function whose BFS claims a node wins.
|
||||||
|
functions = self.__funcs
|
||||||
|
func_scope: dict[int, str] = {}
|
||||||
|
all_f_start_ids: set[int] = {fs.id for _, (fs, _) in functions.items()}
|
||||||
|
|
||||||
|
for f_name, (f_start, f_end) in functions.items():
|
||||||
|
queue: deque = deque([f_start])
|
||||||
|
while queue:
|
||||||
|
node = queue.popleft()
|
||||||
|
if node.id in func_scope:
|
||||||
|
continue # already claimed by an earlier function
|
||||||
|
func_scope[node.id] = f_name
|
||||||
|
# Stop here — do not follow into the caller context.
|
||||||
|
if node.id == f_end.id:
|
||||||
|
continue
|
||||||
|
for child in node.children:
|
||||||
|
# Do not follow into a different function's START.
|
||||||
|
if (
|
||||||
|
isinstance(child, CFG_START)
|
||||||
|
and child.id in all_f_start_ids
|
||||||
|
and child.id != f_start.id
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
queue.append(child)
|
||||||
|
|
||||||
|
return func_scope
|
||||||
|
|
||||||
|
# Populate uses and defs for every node in the CFG.
|
||||||
|
def __extract_uses_and_defs(self) -> None:
|
||||||
|
for node in self.cfg.nodes():
|
||||||
|
nid = node.id
|
||||||
|
func = self.func_scope.get(nid)
|
||||||
|
ast = node.ast_node
|
||||||
|
|
||||||
|
uses: set[Var] = set()
|
||||||
|
defs: set[Var] = set()
|
||||||
|
|
||||||
|
if isinstance(node, CFG_START) and isinstance(ast, syntax.DECL):
|
||||||
|
# Function entry defines each formal parameter.
|
||||||
|
for param in ast.params:
|
||||||
|
defs.add((ast.f_name, param))
|
||||||
|
elif ast is not None:
|
||||||
|
if isinstance(ast, syntax.ID):
|
||||||
|
resolved = self.resolve_var(func, ast.name)
|
||||||
|
uses.add(resolved)
|
||||||
|
elif isinstance(ast, syntax.ASSIGN):
|
||||||
|
resolved = self.resolve_var(func, ast.var.name)
|
||||||
|
defs.add(resolved)
|
||||||
|
|
||||||
|
self.uses[nid] = uses
|
||||||
|
self.defs[nid] = defs
|
||||||
|
|
||||||
|
# Resolve a variables name and scope by walking up the hierarchy
|
||||||
|
def resolve_var(self, func: str | None, name: str) -> Var:
|
||||||
|
if func is None:
|
||||||
|
return GLOBAL_SCOPE, name
|
||||||
|
|
||||||
|
cur: str | None = func
|
||||||
|
seen: set[str] = set()
|
||||||
|
while cur is not None and cur not in seen:
|
||||||
|
seen.add(cur)
|
||||||
|
if name in self._func_params.get(cur, ()):
|
||||||
|
return cur, name
|
||||||
|
cur = self.__func_parent.get(cur)
|
||||||
|
|
||||||
|
# Fallback: local variable in the current function scope
|
||||||
|
return func, name
|
||||||
64
Project-02-03-04-05/cfa/LiveVariables.py
Normal file
64
Project-02-03-04-05/cfa/LiveVariables.py
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from cfa.BackwardAnalysis import BackwardAnalysis, Var
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
|
||||||
|
class LiveVariables(BackwardAnalysis):
|
||||||
|
def __init__(self, cfg: "CFG") -> None:
|
||||||
|
# Base populates uses, defs, _func_scope, etc.
|
||||||
|
super().__init__(cfg)
|
||||||
|
|
||||||
|
self.gen: dict[int, set[Var]] = {}
|
||||||
|
self.kill: dict[int, set[Var]] = {}
|
||||||
|
self.incoming: dict[int, set[Var]] = {}
|
||||||
|
self.outgoing: dict[int, set[Var]] = {}
|
||||||
|
|
||||||
|
self.__init_sets()
|
||||||
|
self.solve()
|
||||||
|
|
||||||
|
# Initialize gen, kill, in, and out sets for all CFG nodes.
|
||||||
|
def __init_sets(self) -> None:
|
||||||
|
for node in self.cfg.nodes():
|
||||||
|
nid = node.id
|
||||||
|
|
||||||
|
# GEN(n) = USE(n); KILL(n) = DEF(n)
|
||||||
|
self.gen[nid] = set(self.uses[nid])
|
||||||
|
self.kill[nid] = set(self.defs[nid])
|
||||||
|
|
||||||
|
# IN(n) = GEN(n) = USE(n); OUT(n) = empty
|
||||||
|
self.incoming[nid] = set(self.gen[nid])
|
||||||
|
self.outgoing[nid] = set()
|
||||||
|
|
||||||
|
# Update the lists until the fixpoint.
|
||||||
|
def solve(self) -> None:
|
||||||
|
nodes = list(self.cfg.nodes())
|
||||||
|
known: set[int] = set(n.id for n in nodes)
|
||||||
|
|
||||||
|
# while there are changes do
|
||||||
|
changes = True
|
||||||
|
while changes:
|
||||||
|
changes = False
|
||||||
|
|
||||||
|
# for all v IN V do
|
||||||
|
for node in nodes:
|
||||||
|
nid = node.id
|
||||||
|
|
||||||
|
# OUT(n) = UNION IN(s) for all successors s
|
||||||
|
new_out: set[Var] = set()
|
||||||
|
for child in node.children:
|
||||||
|
if child.id in known:
|
||||||
|
new_out |= self.incoming[child.id]
|
||||||
|
|
||||||
|
# IN(n) = (OUT(n) MINUS KILL(n)) UNION GEN(n)
|
||||||
|
new_in: set[Var] = (new_out - self.kill[nid]) | self.gen[nid]
|
||||||
|
|
||||||
|
if new_out != self.outgoing[nid] or new_in != self.incoming[nid]:
|
||||||
|
self.outgoing[nid] = new_out
|
||||||
|
self.incoming[nid] = new_in
|
||||||
|
changes = True # there are changes -> loop again
|
||||||
|
|
||||||
|
# Return the living variables within each node
|
||||||
|
def live_vars_by_node(self) -> dict[int, set[Var]]:
|
||||||
|
return {nid: set(vs) for nid, vs in self.incoming.items() if vs}
|
||||||
97
Project-02-03-04-05/cfa/ReachedUses.py
Normal file
97
Project-02-03-04-05/cfa/ReachedUses.py
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
from cfa.BackwardAnalysis import BackwardAnalysis, Var
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
|
||||||
|
# A single use-fact: the CFG node at which a variable is used.
|
||||||
|
# e.g. (42, ("f", "x")) -> variable "x" in function "f" is used at node 42
|
||||||
|
UseFact = tuple[int, Var]
|
||||||
|
|
||||||
|
class ReachedUses(BackwardAnalysis):
|
||||||
|
def __init__(self, cfg: "CFG") -> None:
|
||||||
|
# Base populates: uses, defs, _func_scope, _func_parent, _func_params.
|
||||||
|
super().__init__(cfg)
|
||||||
|
|
||||||
|
self.gen: dict[int, set[UseFact]] = {}
|
||||||
|
self.kill: dict[int, set[UseFact]] = {}
|
||||||
|
self.in_sets: dict[int, set[UseFact]] = {}
|
||||||
|
self.out_sets: dict[int, set[UseFact]] = {}
|
||||||
|
self.all_uses_by_var: dict[Var, set[UseFact]] = {}
|
||||||
|
|
||||||
|
self.__init_sets()
|
||||||
|
self.solve()
|
||||||
|
|
||||||
|
# Initialize gen, kill, in, and out sets for all CFG nodes.
|
||||||
|
def __init_sets(self) -> None:
|
||||||
|
for node in self.cfg.nodes():
|
||||||
|
nid = node.id
|
||||||
|
|
||||||
|
# GEN(n) = { (n.id, var) | var IN USE(n) }
|
||||||
|
self.gen[nid] = {(nid, var) for var in self.uses[nid]}
|
||||||
|
|
||||||
|
# IN(n) = GEN(n); OUT(n) = empty
|
||||||
|
self.in_sets[nid] = set(self.gen[nid])
|
||||||
|
self.out_sets[nid] = set()
|
||||||
|
|
||||||
|
# KILL(n) requires knowing all use-facts for a given variable — "at which nodes is variable x used anywhere?"
|
||||||
|
# all_uses_by_var builds this lookup once upfront: ("f", "x") -> { (42, ("f","x")), (17, ("f","x")) }
|
||||||
|
for nid, facts in self.gen.items():
|
||||||
|
for (uid, var) in facts:
|
||||||
|
self.all_uses_by_var.setdefault(var, set()).add((uid, var))
|
||||||
|
|
||||||
|
for node in self.cfg.nodes():
|
||||||
|
nid = node.id
|
||||||
|
|
||||||
|
# KILL(n) = { (uid, var) | var IN DEF(n), (uid, var) IN use_facts_by_var[var] }
|
||||||
|
# When n defines a variable, it kills all use-facts for that variable, because no use reachable from n
|
||||||
|
# can have been reached by an earlier definition of the same variable.
|
||||||
|
kill_n: set[UseFact] = set()
|
||||||
|
for var in self.defs[nid]:
|
||||||
|
if var in self.all_uses_by_var:
|
||||||
|
kill_n |= self.all_uses_by_var[var]
|
||||||
|
self.kill[nid] = kill_n
|
||||||
|
|
||||||
|
# Update the lists until the fixpoint.
|
||||||
|
def solve(self) -> None:
|
||||||
|
nodes = list(self.cfg.nodes())
|
||||||
|
known: set[int] = set(n.id for n in nodes)
|
||||||
|
|
||||||
|
# while there are changes do
|
||||||
|
changes = True
|
||||||
|
while changes:
|
||||||
|
changes = False
|
||||||
|
|
||||||
|
# for all v in V do
|
||||||
|
for node in nodes:
|
||||||
|
nid = node.id
|
||||||
|
|
||||||
|
# OUT(n) = UNION IN(s) for all successors s
|
||||||
|
new_out: set[UseFact] = set()
|
||||||
|
for child in node.children:
|
||||||
|
if child.id in known:
|
||||||
|
new_out |= self.in_sets[child.id]
|
||||||
|
|
||||||
|
# IN(n) = GEN(n) UNION (OUT(n) MINUS KILL(n))
|
||||||
|
new_in: set[UseFact] = self.gen[nid] | (new_out - self.kill[nid])
|
||||||
|
|
||||||
|
if new_out != self.out_sets[nid] or new_in != self.in_sets[nid]:
|
||||||
|
self.out_sets[nid] = new_out
|
||||||
|
self.in_sets[nid] = new_in
|
||||||
|
changes = True # there are changes -> loop again
|
||||||
|
|
||||||
|
# Return the final reached-uses result
|
||||||
|
def reached_uses_by_node(self) -> dict[int, list[int]]:
|
||||||
|
result: dict[int, list[int]] = {}
|
||||||
|
for node in self.cfg.nodes():
|
||||||
|
nid = node.id
|
||||||
|
defs_n = self.defs[nid]
|
||||||
|
if not defs_n:
|
||||||
|
continue
|
||||||
|
reached: set[int] = set()
|
||||||
|
for (uid, var) in self.out_sets[nid]:
|
||||||
|
if var in defs_n:
|
||||||
|
reached.add(uid)
|
||||||
|
result[nid] = sorted(reached)
|
||||||
|
return result
|
||||||
11
Project-02-03-04-05/cfa/__init__.py
Normal file
11
Project-02-03-04-05/cfa/__init__.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from .BackwardAnalysis import BackwardAnalysis, Var
|
||||||
|
from .LiveVariables import LiveVariables
|
||||||
|
from .ReachedUses import ReachedUses, UseFact
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Var",
|
||||||
|
"UseFact",
|
||||||
|
"BackwardAnalysis",
|
||||||
|
"LiveVariables",
|
||||||
|
"ReachedUses",
|
||||||
|
]
|
||||||
179
Project-02-03-04-05/cfa/to_dot.py
Normal file
179
Project-02-03-04-05/cfa/to_dot.py
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
import syntax
|
||||||
|
import colorsys
|
||||||
|
from cfg.CFG_Node import CFG_DIAMOND
|
||||||
|
|
||||||
|
# Builds annotations for the LiveVariables analysis.
|
||||||
|
def build_lv_annotations(cfg, lv) -> dict[int, str]:
|
||||||
|
node_by_id = {n.id: n for n in cfg.nodes()}
|
||||||
|
all_ids = set(lv.incoming.keys()) | set(lv.outgoing.keys())
|
||||||
|
return {
|
||||||
|
nid: (
|
||||||
|
"LivingVariables\\n"
|
||||||
|
f"In := {sorted(__lv_in_set(node_by_id[nid], lv))}\\n"
|
||||||
|
f"Out := {sorted(lv.outgoing.get(nid, set()))}"
|
||||||
|
)
|
||||||
|
for nid in all_ids
|
||||||
|
if lv.incoming.get(nid, set()) or lv.outgoing.get(nid, set())
|
||||||
|
if nid in node_by_id and __should_display_analysis(node_by_id[nid])
|
||||||
|
}
|
||||||
|
|
||||||
|
# For display only: IN(ASSIGN) has GEN = empty, so RHS variables are missing from incoming — they live at their
|
||||||
|
# own ID nodes. Add them here for a proper DOT annotation.
|
||||||
|
def __lv_in_set(node, analysis):
|
||||||
|
in_set = set(analysis.incoming.get(node.id, set()))
|
||||||
|
ast_node = node.ast_node
|
||||||
|
if isinstance(ast_node, syntax.ASSIGN):
|
||||||
|
func = analysis.func_scope.get(node.id)
|
||||||
|
rhs_vars = {
|
||||||
|
analysis.resolve_var(func, name)
|
||||||
|
for name in __expr_used_names(ast_node.expr)
|
||||||
|
}
|
||||||
|
in_set |= rhs_vars
|
||||||
|
return in_set
|
||||||
|
|
||||||
|
# For display only: the right-hand side of an ASSIGN has no dedicated CFG nodes, so LV places uses of "a", "b"
|
||||||
|
# at their own nodes — not at the ASSIGN. Recover them here to complete the DOT annotation at the ASSIGN node.
|
||||||
|
def __expr_used_names(expr) -> set[str]:
|
||||||
|
used: set[str] = set()
|
||||||
|
|
||||||
|
def visit(node):
|
||||||
|
if node is None:
|
||||||
|
return
|
||||||
|
if isinstance(node, syntax.ID):
|
||||||
|
used.add(node.name)
|
||||||
|
return
|
||||||
|
if isinstance(node, syntax.EXPRESSION):
|
||||||
|
for _, child in node.children():
|
||||||
|
visit(child)
|
||||||
|
|
||||||
|
visit(expr)
|
||||||
|
return used
|
||||||
|
|
||||||
|
# Weather a node should display analysis annotations
|
||||||
|
def __should_display_analysis(node) -> bool:
|
||||||
|
ast = node.ast_node
|
||||||
|
if isinstance(node, CFG_DIAMOND):
|
||||||
|
return False
|
||||||
|
if ast is None:
|
||||||
|
return False
|
||||||
|
return isinstance(
|
||||||
|
ast,
|
||||||
|
(
|
||||||
|
syntax.ASSIGN,
|
||||||
|
syntax.CALL,
|
||||||
|
syntax.IF,
|
||||||
|
syntax.WHILE,
|
||||||
|
syntax.DECL,
|
||||||
|
syntax.LET,
|
||||||
|
syntax.SEQ,
|
||||||
|
syntax.COMP,
|
||||||
|
syntax.EQOP,
|
||||||
|
syntax.LOP,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Generates colors for CFG nodes based on their id.
|
||||||
|
def __node_color(node_id: int) -> tuple[str, str]:
|
||||||
|
# Golden-angle hue distribution gives stable, distinct colors.
|
||||||
|
hue = ((node_id * 0.6180339887498949) % 1.0)
|
||||||
|
edge_rgb = colorsys.hsv_to_rgb(hue, 0.70, 0.82)
|
||||||
|
fill_rgb = colorsys.hsv_to_rgb(hue, 0.28, 0.97)
|
||||||
|
|
||||||
|
def to_hex(rgb):
|
||||||
|
r, g, b = (int(round(c * 255)) for c in rgb)
|
||||||
|
return f"#{r:02x}{g:02x}{b:02x}"
|
||||||
|
|
||||||
|
return to_hex(edge_rgb), to_hex(fill_rgb)
|
||||||
|
|
||||||
|
# Return a DOT string for the CFG annotated with analysis results.
|
||||||
|
def analysis_to_dot(cfg, analyses: dict, analysis_name: str) -> str:
|
||||||
|
ru = analyses.get("ru")
|
||||||
|
lv = analyses.get("lv")
|
||||||
|
|
||||||
|
ru_edges = ru.reached_uses_by_node() if ru is not None else None
|
||||||
|
|
||||||
|
# DOT graph header
|
||||||
|
lines = [
|
||||||
|
"digraph CFG {",
|
||||||
|
f' // Analysis: {analysis_name}',
|
||||||
|
' graph [splines=ortho, overlap=false, ranksep=0.7, nodesep=0.45];',
|
||||||
|
' node [fontname="Helvetica"];',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Build LV annotations and assign a color per annotated node
|
||||||
|
annotations = build_lv_annotations(cfg, lv)
|
||||||
|
color_nodes = set(annotations.keys()) | set((ru_edges or {}).keys())
|
||||||
|
node_colors = {nid: __node_color(nid) for nid in color_nodes}
|
||||||
|
|
||||||
|
# Emit each CFG node with its label, shape, and optional LV annotation note
|
||||||
|
def emit(node):
|
||||||
|
base_label = node.dot_label() or ""
|
||||||
|
shape = node.dot_shape
|
||||||
|
style = node.dot_style
|
||||||
|
style_str = f", {style}" if style else ""
|
||||||
|
lines.append(f' n{node.id} [label="{base_label}", shape={shape}{style_str}];')
|
||||||
|
|
||||||
|
if node.id in annotations:
|
||||||
|
ann_id = f"a{node.id}"
|
||||||
|
ann_label = annotations[node.id].replace('"', '\\"')
|
||||||
|
edge_color, fill_color = node_colors.get(node.id, ("#1f77b4", "#d9ecff"))
|
||||||
|
lines.append(
|
||||||
|
f' {ann_id} [label="{ann_label}", shape=note, '
|
||||||
|
f'style="filled", fillcolor="{fill_color}", color="{edge_color}", '
|
||||||
|
f'fontcolor="{edge_color}"];'
|
||||||
|
)
|
||||||
|
lines.append(
|
||||||
|
f' {ann_id} -> n{node.id} [style=dotted, arrowhead=none, '
|
||||||
|
f'color="{edge_color}"];'
|
||||||
|
)
|
||||||
|
|
||||||
|
for i, child in enumerate(sorted(node.children, key=lambda n: n.id)):
|
||||||
|
edge_label = ""
|
||||||
|
if isinstance(node, CFG_DIAMOND):
|
||||||
|
if i == 0:
|
||||||
|
edge_label = ' [label="T"]'
|
||||||
|
elif i == 1:
|
||||||
|
edge_label = ' [label="F"]'
|
||||||
|
lines.append(f" n{node.id} -> n{child.id}{edge_label};")
|
||||||
|
|
||||||
|
cfg.traverse(emit, start=cfg.START)
|
||||||
|
|
||||||
|
# Draw dashed def -> use edges for Reached Uses
|
||||||
|
if ru_edges:
|
||||||
|
for idx, def_id in enumerate(sorted(ru_edges)):
|
||||||
|
use_ids = sorted(set(ru_edges[def_id]))
|
||||||
|
if not use_ids:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# One routing hub per definition node to mimic UML-like
|
||||||
|
# "out to the side, then down/across to targets" connectors.
|
||||||
|
side = "e" if idx % 2 == 0 else "w"
|
||||||
|
source_port = "se" if side == "e" else "sw"
|
||||||
|
hub_id = f"rh{def_id}"
|
||||||
|
edge_color, fill_color = node_colors.get(def_id, ("#1f77b4", "#d9ecff"))
|
||||||
|
|
||||||
|
lines.append(
|
||||||
|
f' {hub_id} [shape=point, width=0.05, height=0.05, '
|
||||||
|
f'color="{edge_color}", fillcolor="{edge_color}", style=filled];'
|
||||||
|
)
|
||||||
|
lines.append(f" {{ rank=same; n{def_id}; {hub_id}; }}")
|
||||||
|
lines.append(
|
||||||
|
f' n{def_id}:{source_port} -> {hub_id} [color="{edge_color}", '
|
||||||
|
f'style=dashed, penwidth=1.2, arrowhead=none, constraint=false, '
|
||||||
|
f'tailclip=true, headclip=true];'
|
||||||
|
)
|
||||||
|
|
||||||
|
for use_id in use_ids:
|
||||||
|
if side == "e":
|
||||||
|
target_port = "ne" if (use_id % 2 == 0) else "se"
|
||||||
|
else:
|
||||||
|
target_port = "nw" if (use_id % 2 == 0) else "sw"
|
||||||
|
lines.append(
|
||||||
|
f' {hub_id} -> n{use_id}:{target_port} [color="{edge_color}", '
|
||||||
|
f'fontcolor="{edge_color}", fontsize=8, style=dashed, '
|
||||||
|
f'penwidth=1.0, arrowsize=0.6, constraint=false, '
|
||||||
|
f'tailclip=true, headclip=true];'
|
||||||
|
)
|
||||||
|
|
||||||
|
lines.append("}")
|
||||||
|
return "\n".join(lines)
|
||||||
188
Project-02-03-04-05/cfadots/complex_analysis.dot
Normal file
188
Project-02-03-04-05/cfadots/complex_analysis.dot
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
digraph CFG {
|
||||||
|
// Analysis: Live Variables + Reached Uses analyses
|
||||||
|
graph [splines=ortho, overlap=false, ranksep=0.7, nodesep=0.45];
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1 -> n52;
|
||||||
|
n52 [label="10", shape=box];
|
||||||
|
n52 -> n53;
|
||||||
|
n53 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
a53 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#d7b2f7", color="#8d3fd1", fontcolor="#8d3fd1"];
|
||||||
|
a53 -> n53 [style=dotted, arrowhead=none, color="#8d3fd1"];
|
||||||
|
n53 -> n3;
|
||||||
|
n53 -> n55;
|
||||||
|
n3 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
a3 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f1', 'b'), ('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f7b2ef", color="#d13fbf", fontcolor="#d13fbf"];
|
||||||
|
a3 -> n3 [style=dotted, arrowhead=none, color="#d13fbf"];
|
||||||
|
n3 -> n8;
|
||||||
|
n8 [label="b", shape=box];
|
||||||
|
n8 -> n9;
|
||||||
|
n9 [label="0", shape=box];
|
||||||
|
n9 -> n10;
|
||||||
|
n10 [label="b == 0", shape=box];
|
||||||
|
a10 [label="LivingVariables\nIn := [('f1', 'b'), ('f2', 'a'), ('f2', 'b')]\nOut := [('f1', 'b'), ('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f2f7b2", color="#c5d13f", fontcolor="#c5d13f"];
|
||||||
|
a10 -> n10 [style=dotted, arrowhead=none, color="#c5d13f"];
|
||||||
|
n10 -> n11;
|
||||||
|
n11 [label="<?>", shape=diamond];
|
||||||
|
n11 -> n15 [label="T"];
|
||||||
|
n11 -> n16 [label="F"];
|
||||||
|
n15 [label="0", shape=box];
|
||||||
|
n15 -> n4;
|
||||||
|
n4 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
a4 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#b2f7ec", color="#3fd1b9", fontcolor="#3fd1b9"];
|
||||||
|
a4 -> n4 [style=dotted, arrowhead=none, color="#3fd1b9"];
|
||||||
|
n4 -> n21;
|
||||||
|
n4 -> n32;
|
||||||
|
n4 -> n36;
|
||||||
|
n4 -> n55;
|
||||||
|
n21 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
a21 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f7b2bb", color="#d13f51", fontcolor="#d13f51"];
|
||||||
|
a21 -> n21 [style=dotted, arrowhead=none, color="#d13f51"];
|
||||||
|
n21 -> n4;
|
||||||
|
n32 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
a32 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#e0b2f7", color="#a03fd1", fontcolor="#a03fd1"];
|
||||||
|
a32 -> n32 [style=dotted, arrowhead=none, color="#a03fd1"];
|
||||||
|
n32 -> n45;
|
||||||
|
n45 [label="a", shape=box];
|
||||||
|
n45 -> n46;
|
||||||
|
n46 [label="b", shape=box];
|
||||||
|
n46 -> n47;
|
||||||
|
n47 [label="a * b", shape=box];
|
||||||
|
n47 -> n48;
|
||||||
|
n48 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
a48 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#b2b3f7", color="#3f40d1", fontcolor="#3f40d1"];
|
||||||
|
a48 -> n48 [style=dotted, arrowhead=none, color="#3f40d1"];
|
||||||
|
n48 -> n37;
|
||||||
|
n48 -> n50;
|
||||||
|
n37 [label="START g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
a37 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b'), ('g', 'c')]", shape=note, style="filled", fillcolor="#f7b2e9", color="#d13fb3", fontcolor="#d13fb3"];
|
||||||
|
a37 -> n37 [style=dotted, arrowhead=none, color="#d13fb3"];
|
||||||
|
n37 -> n40;
|
||||||
|
n40 [label="a", shape=box];
|
||||||
|
n40 -> n41;
|
||||||
|
n41 [label="b", shape=box];
|
||||||
|
n41 -> n42;
|
||||||
|
n42 [label="a * b", shape=box];
|
||||||
|
n42 -> n43;
|
||||||
|
n43 [label="c", shape=box];
|
||||||
|
n43 -> n44;
|
||||||
|
n44 [label="(a * b) * c", shape=box];
|
||||||
|
n44 -> n38;
|
||||||
|
n38 [label="END g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n38 -> n50;
|
||||||
|
n50 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n50 -> n6;
|
||||||
|
n6 [label="END f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n6 -> n78;
|
||||||
|
n78 [label="RET f2", shape=box, style=filled, color=orange];
|
||||||
|
n78 -> n2;
|
||||||
|
n2 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n36 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
a36 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#d5f7b2", color="#89d13f", fontcolor="#89d13f"];
|
||||||
|
a36 -> n36 [style=dotted, arrowhead=none, color="#89d13f"];
|
||||||
|
n36 -> n45;
|
||||||
|
n55 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n55 -> n57;
|
||||||
|
n57 [label="10", shape=box];
|
||||||
|
n57 -> n70;
|
||||||
|
n70 [label="20", shape=box];
|
||||||
|
n70 -> n71;
|
||||||
|
n71 [label="30", shape=box];
|
||||||
|
n71 -> n72;
|
||||||
|
n72 [label="CALL max", shape=box, style=filled, color=orange];
|
||||||
|
n72 -> n58;
|
||||||
|
n72 -> n74;
|
||||||
|
n58 [label="START max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
a58 [label="LivingVariables\nIn := []\nOut := [('max', 'a'), ('max', 'b')]", shape=note, style="filled", fillcolor="#f7b2f2", color="#d13fc6", fontcolor="#d13fc6"];
|
||||||
|
a58 -> n58 [style=dotted, arrowhead=none, color="#d13fc6"];
|
||||||
|
n58 -> n61;
|
||||||
|
n61 [label="a", shape=box];
|
||||||
|
n61 -> n62;
|
||||||
|
n62 [label="b", shape=box];
|
||||||
|
n62 -> n63;
|
||||||
|
n63 [label="a > b", shape=box];
|
||||||
|
a63 [label="LivingVariables\nIn := [('max', 'a'), ('max', 'b')]\nOut := [('max', 'a'), ('max', 'b')]", shape=note, style="filled", fillcolor="#f7b2cd", color="#d13f77", fontcolor="#d13f77"];
|
||||||
|
a63 -> n63 [style=dotted, arrowhead=none, color="#d13f77"];
|
||||||
|
n63 -> n64;
|
||||||
|
n64 [label="<?>", shape=diamond];
|
||||||
|
n64 -> n68 [label="T"];
|
||||||
|
n64 -> n69 [label="F"];
|
||||||
|
n68 [label="a", shape=box];
|
||||||
|
n68 -> n59;
|
||||||
|
n59 [label="END max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n59 -> n74;
|
||||||
|
n74 [label="RET max", shape=box, style=filled, color=orange];
|
||||||
|
n74 -> n76;
|
||||||
|
n76 [label="CALL f2", shape=box, style=filled, color=orange];
|
||||||
|
n76 -> n5;
|
||||||
|
n76 -> n78;
|
||||||
|
n5 [label="START f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
a5 [label="LivingVariables\nIn := []\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f7d8b2", color="#d18e3f", fontcolor="#d18e3f"];
|
||||||
|
a5 -> n5 [style=dotted, arrowhead=none, color="#d18e3f"];
|
||||||
|
n5 -> n22;
|
||||||
|
n22 [label="a", shape=box];
|
||||||
|
n22 -> n23;
|
||||||
|
n23 [label="b", shape=box];
|
||||||
|
n23 -> n24;
|
||||||
|
n24 [label="a > b", shape=box];
|
||||||
|
a24 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f7b2f7", color="#d13fd1", fontcolor="#d13fd1"];
|
||||||
|
a24 -> n24 [style=dotted, arrowhead=none, color="#d13fd1"];
|
||||||
|
n24 -> n25;
|
||||||
|
n25 [label="<?>", shape=diamond];
|
||||||
|
n25 -> n29 [label="T"];
|
||||||
|
n25 -> n33 [label="F"];
|
||||||
|
n29 [label="a", shape=box];
|
||||||
|
n29 -> n30;
|
||||||
|
n30 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
a30 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#b2e6f7", color="#3fadd1", fontcolor="#3fadd1"];
|
||||||
|
a30 -> n30 [style=dotted, arrowhead=none, color="#3fadd1"];
|
||||||
|
n30 -> n3;
|
||||||
|
n30 -> n32;
|
||||||
|
n33 [label="b", shape=box];
|
||||||
|
n33 -> n34;
|
||||||
|
n34 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
a34 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#f7b8b2", color="#d14a3f", fontcolor="#d14a3f"];
|
||||||
|
a34 -> n34 [style=dotted, arrowhead=none, color="#d14a3f"];
|
||||||
|
n34 -> n3;
|
||||||
|
n34 -> n36;
|
||||||
|
n69 [label="b", shape=box];
|
||||||
|
n69 -> n59;
|
||||||
|
n16 [label="b", shape=box];
|
||||||
|
n16 -> n17;
|
||||||
|
n17 [label="1", shape=box];
|
||||||
|
n17 -> n18;
|
||||||
|
n18 [label="b - 1", shape=box];
|
||||||
|
n18 -> n19;
|
||||||
|
n19 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
a19 [label="LivingVariables\nIn := [('f2', 'a'), ('f2', 'b')]\nOut := [('f2', 'a'), ('f2', 'b')]", shape=note, style="filled", fillcolor="#d2b2f7", color="#813fd1", fontcolor="#813fd1"];
|
||||||
|
a19 -> n19 [style=dotted, arrowhead=none, color="#813fd1"];
|
||||||
|
n19 -> n3;
|
||||||
|
n19 -> n21;
|
||||||
|
rh3 [shape=point, width=0.05, height=0.05, color="#d13fbf", fillcolor="#d13fbf", style=filled];
|
||||||
|
{ rank=same; n3; rh3; }
|
||||||
|
n3:se -> rh3 [color="#d13fbf", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh3 -> n8:ne [color="#d13fbf", fontcolor="#d13fbf", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh3 -> n16:ne [color="#d13fbf", fontcolor="#d13fbf", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 [shape=point, width=0.05, height=0.05, color="#d18e3f", fillcolor="#d18e3f", style=filled];
|
||||||
|
{ rank=same; n5; rh5; }
|
||||||
|
n5:sw -> rh5 [color="#d18e3f", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n22:nw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n23:sw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n29:sw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n33:sw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n40:nw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n41:sw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n45:sw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh5 -> n46:nw [color="#d18e3f", fontcolor="#d18e3f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh37 [shape=point, width=0.05, height=0.05, color="#d13fb3", fillcolor="#d13fb3", style=filled];
|
||||||
|
{ rank=same; n37; rh37; }
|
||||||
|
n37:se -> rh37 [color="#d13fb3", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh37 -> n43:se [color="#d13fb3", fontcolor="#d13fb3", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh58 [shape=point, width=0.05, height=0.05, color="#d13fc6", fillcolor="#d13fc6", style=filled];
|
||||||
|
{ rank=same; n58; rh58; }
|
||||||
|
n58:sw -> rh58 [color="#d13fc6", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh58 -> n61:sw [color="#d13fc6", fontcolor="#d13fc6", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh58 -> n62:nw [color="#d13fc6", fontcolor="#d13fc6", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh58 -> n68:nw [color="#d13fc6", fontcolor="#d13fc6", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh58 -> n69:sw [color="#d13fc6", fontcolor="#d13fc6", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
}
|
||||||
183
Project-02-03-04-05/cfadots/dataflow_analysis.dot
Normal file
183
Project-02-03-04-05/cfadots/dataflow_analysis.dot
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
digraph CFG {
|
||||||
|
// Analysis: Live Variables + Reached Uses
|
||||||
|
graph [splines=ortho, overlap=false, ranksep=0.7, nodesep=0.45];
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1 -> n3;
|
||||||
|
n3 [label="33", shape=box];
|
||||||
|
n3 -> n4;
|
||||||
|
n4 [label="s = 33", shape=box];
|
||||||
|
a4 [label="LivingVariables\nIn := []\nOut := [('', 's')]", shape=note, style="filled", fillcolor="#b2f7ec", color="#3fd1b9", fontcolor="#3fd1b9"];
|
||||||
|
a4 -> n4 [style=dotted, arrowhead=none, color="#3fd1b9"];
|
||||||
|
n4 -> n5;
|
||||||
|
n5 [label="0", shape=box];
|
||||||
|
n5 -> n6;
|
||||||
|
n6 [label="i = 0", shape=box];
|
||||||
|
a6 [label="LivingVariables\nIn := [('', 's')]\nOut := [('', 'i'), ('', 's')]", shape=note, style="filled", fillcolor="#c3b2f7", color="#633fd1", fontcolor="#633fd1"];
|
||||||
|
a6 -> n6 [style=dotted, arrowhead=none, color="#633fd1"];
|
||||||
|
n6 -> n7;
|
||||||
|
n7 [label="0", shape=box];
|
||||||
|
n7 -> n8;
|
||||||
|
n8 [label="j = 0", shape=box];
|
||||||
|
a8 [label="LivingVariables\nIn := [('', 'i'), ('', 's')]\nOut := [('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#f7b2c9", color="#d13f70", fontcolor="#d13f70"];
|
||||||
|
a8 -> n8 [style=dotted, arrowhead=none, color="#d13f70"];
|
||||||
|
n8 -> n9;
|
||||||
|
n9 [label="i", shape=box];
|
||||||
|
n9 -> n10;
|
||||||
|
n10 [label="j", shape=box];
|
||||||
|
n10 -> n11;
|
||||||
|
n11 [label="i + j", shape=box];
|
||||||
|
n11 -> n12;
|
||||||
|
n12 [label="t = (i + j)", shape=box];
|
||||||
|
a12 [label="LivingVariables\nIn := [('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#b2f7d5", color="#3fd188", fontcolor="#3fd188"];
|
||||||
|
a12 -> n12 [style=dotted, arrowhead=none, color="#3fd188"];
|
||||||
|
n12 -> n13;
|
||||||
|
n13 [label="6", shape=box];
|
||||||
|
n13 -> n14;
|
||||||
|
n14 [label="f = 6", shape=box];
|
||||||
|
a14 [label="LivingVariables\nIn := [('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#b2b8f7", color="#3f4bd1", fontcolor="#3f4bd1"];
|
||||||
|
a14 -> n14 [style=dotted, arrowhead=none, color="#3f4bd1"];
|
||||||
|
n14 -> n16;
|
||||||
|
n16 [label="s", shape=box];
|
||||||
|
n16 -> n17;
|
||||||
|
n17 [label="42", shape=box];
|
||||||
|
n17 -> n18;
|
||||||
|
n18 [label="s < 42", shape=box];
|
||||||
|
a18 [label="LivingVariables\nIn := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#f7e6b2", color="#d1ac3f", fontcolor="#d1ac3f"];
|
||||||
|
a18 -> n18 [style=dotted, arrowhead=none, color="#d1ac3f"];
|
||||||
|
n18 -> n19;
|
||||||
|
n19 [label="<?>", shape=diamond];
|
||||||
|
n19 -> n2 [label="T"];
|
||||||
|
n19 -> n21 [label="F"];
|
||||||
|
n2 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n21 [label="s", shape=box];
|
||||||
|
n21 -> n22;
|
||||||
|
n22 [label="1", shape=box];
|
||||||
|
n22 -> n23;
|
||||||
|
n23 [label="s - 1", shape=box];
|
||||||
|
n23 -> n24;
|
||||||
|
n24 [label="a = (s - 1)", shape=box];
|
||||||
|
a24 [label="LivingVariables\nIn := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#f7b2f7", color="#d13fd1", fontcolor="#d13fd1"];
|
||||||
|
a24 -> n24 [style=dotted, arrowhead=none, color="#d13fd1"];
|
||||||
|
n24 -> n25;
|
||||||
|
n25 [label="i", shape=box];
|
||||||
|
n25 -> n26;
|
||||||
|
n26 [label="j", shape=box];
|
||||||
|
n26 -> n27;
|
||||||
|
n27 [label="i + j", shape=box];
|
||||||
|
n27 -> n28;
|
||||||
|
n28 [label="f", shape=box];
|
||||||
|
n28 -> n29;
|
||||||
|
n29 [label="1", shape=box];
|
||||||
|
n29 -> n30;
|
||||||
|
n30 [label="f + 1", shape=box];
|
||||||
|
n30 -> n31;
|
||||||
|
n31 [label="(i + j) * (f + 1)", shape=box];
|
||||||
|
n31 -> n32;
|
||||||
|
n32 [label="c = ((i + j) * (f + 1))", shape=box];
|
||||||
|
a32 [label="LivingVariables\nIn := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'c'), ('', 'f'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#e0b2f7", color="#a03fd1", fontcolor="#a03fd1"];
|
||||||
|
a32 -> n32 [style=dotted, arrowhead=none, color="#a03fd1"];
|
||||||
|
n32 -> n33;
|
||||||
|
n33 [label="c", shape=box];
|
||||||
|
n33 -> n34;
|
||||||
|
n34 [label="0", shape=box];
|
||||||
|
n34 -> n35;
|
||||||
|
n35 [label="c > 0", shape=box];
|
||||||
|
a35 [label="LivingVariables\nIn := [('', 'c'), ('', 'f'), ('', 'j'), ('', 's')]\nOut := [('', 'c'), ('', 'f'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#b2c1f7", color="#3f5ed1", fontcolor="#3f5ed1"];
|
||||||
|
a35 -> n35 [style=dotted, arrowhead=none, color="#3f5ed1"];
|
||||||
|
n35 -> n36;
|
||||||
|
n36 [label="<?>", shape=diamond];
|
||||||
|
n36 -> n40 [label="T"];
|
||||||
|
n36 -> n44 [label="F"];
|
||||||
|
n40 [label="j", shape=box];
|
||||||
|
n40 -> n41;
|
||||||
|
n41 [label="c", shape=box];
|
||||||
|
n41 -> n42;
|
||||||
|
n42 [label="j / c", shape=box];
|
||||||
|
n42 -> n43;
|
||||||
|
n43 [label="j = (j / c)", shape=box];
|
||||||
|
a43 [label="LivingVariables\nIn := [('', 'c'), ('', 'f'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#b2d8f7", color="#3f8fd1", fontcolor="#3f8fd1"];
|
||||||
|
a43 -> n43 [style=dotted, arrowhead=none, color="#3f8fd1"];
|
||||||
|
n43 -> n48;
|
||||||
|
n48 [label="j", shape=box];
|
||||||
|
n48 -> n49;
|
||||||
|
n49 [label="2", shape=box];
|
||||||
|
n49 -> n50;
|
||||||
|
n50 [label="j * 2", shape=box];
|
||||||
|
n50 -> n51;
|
||||||
|
n51 [label="f", shape=box];
|
||||||
|
n51 -> n52;
|
||||||
|
n52 [label="(j * 2) / f", shape=box];
|
||||||
|
n52 -> n53;
|
||||||
|
n53 [label="i = ((j * 2) / f)", shape=box];
|
||||||
|
a53 [label="LivingVariables\nIn := [('', 'f'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#d7b2f7", color="#8d3fd1", fontcolor="#8d3fd1"];
|
||||||
|
a53 -> n53 [style=dotted, arrowhead=none, color="#8d3fd1"];
|
||||||
|
n53 -> n54;
|
||||||
|
n54 [label="s", shape=box];
|
||||||
|
n54 -> n55;
|
||||||
|
n55 [label="1", shape=box];
|
||||||
|
n55 -> n56;
|
||||||
|
n56 [label="s + 1", shape=box];
|
||||||
|
n56 -> n57;
|
||||||
|
n57 [label="s = (s + 1)", shape=box];
|
||||||
|
a57 [label="LivingVariables\nIn := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'i'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#def7b2", color="#9bd13f", fontcolor="#9bd13f"];
|
||||||
|
a57 -> n57 [style=dotted, arrowhead=none, color="#9bd13f"];
|
||||||
|
n57 -> n16;
|
||||||
|
n44 [label="j", shape=box];
|
||||||
|
n44 -> n45;
|
||||||
|
n45 [label="c", shape=box];
|
||||||
|
n45 -> n46;
|
||||||
|
n46 [label="j * c", shape=box];
|
||||||
|
n46 -> n47;
|
||||||
|
n47 [label="i = (j * c)", shape=box];
|
||||||
|
a47 [label="LivingVariables\nIn := [('', 'c'), ('', 'f'), ('', 'j'), ('', 's')]\nOut := [('', 'f'), ('', 'j'), ('', 's')]", shape=note, style="filled", fillcolor="#f7c6b2", color="#d1693f", fontcolor="#d1693f"];
|
||||||
|
a47 -> n47 [style=dotted, arrowhead=none, color="#d1693f"];
|
||||||
|
n47 -> n48;
|
||||||
|
rh4 [shape=point, width=0.05, height=0.05, color="#3fd1b9", fillcolor="#3fd1b9", style=filled];
|
||||||
|
{ rank=same; n4; rh4; }
|
||||||
|
n4:se -> rh4 [color="#3fd1b9", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh4 -> n16:ne [color="#3fd1b9", fontcolor="#3fd1b9", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh4 -> n21:se [color="#3fd1b9", fontcolor="#3fd1b9", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh4 -> n54:ne [color="#3fd1b9", fontcolor="#3fd1b9", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh6 [shape=point, width=0.05, height=0.05, color="#633fd1", fillcolor="#633fd1", style=filled];
|
||||||
|
{ rank=same; n6; rh6; }
|
||||||
|
n6:sw -> rh6 [color="#633fd1", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh6 -> n9:sw [color="#633fd1", fontcolor="#633fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh6 -> n25:sw [color="#633fd1", fontcolor="#633fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 [shape=point, width=0.05, height=0.05, color="#d13f70", fillcolor="#d13f70", style=filled];
|
||||||
|
{ rank=same; n8; rh8; }
|
||||||
|
n8:se -> rh8 [color="#d13f70", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 -> n10:ne [color="#d13f70", fontcolor="#d13f70", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 -> n26:ne [color="#d13f70", fontcolor="#d13f70", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 -> n40:ne [color="#d13f70", fontcolor="#d13f70", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 -> n44:ne [color="#d13f70", fontcolor="#d13f70", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh8 -> n48:ne [color="#d13f70", fontcolor="#d13f70", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh14 [shape=point, width=0.05, height=0.05, color="#3f4bd1", fillcolor="#3f4bd1", style=filled];
|
||||||
|
{ rank=same; n14; rh14; }
|
||||||
|
n14:se -> rh14 [color="#3f4bd1", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh14 -> n28:ne [color="#3f4bd1", fontcolor="#3f4bd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh14 -> n51:se [color="#3f4bd1", fontcolor="#3f4bd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh32 [shape=point, width=0.05, height=0.05, color="#a03fd1", fillcolor="#a03fd1", style=filled];
|
||||||
|
{ rank=same; n32; rh32; }
|
||||||
|
n32:se -> rh32 [color="#a03fd1", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh32 -> n33:se [color="#a03fd1", fontcolor="#a03fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh32 -> n41:se [color="#a03fd1", fontcolor="#a03fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh32 -> n45:se [color="#a03fd1", fontcolor="#a03fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh43 [shape=point, width=0.05, height=0.05, color="#3f8fd1", fillcolor="#3f8fd1", style=filled];
|
||||||
|
{ rank=same; n43; rh43; }
|
||||||
|
n43:sw -> rh43 [color="#3f8fd1", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh43 -> n26:nw [color="#3f8fd1", fontcolor="#3f8fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh43 -> n40:nw [color="#3f8fd1", fontcolor="#3f8fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh43 -> n44:nw [color="#3f8fd1", fontcolor="#3f8fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh43 -> n48:nw [color="#3f8fd1", fontcolor="#3f8fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh53 [shape=point, width=0.05, height=0.05, color="#8d3fd1", fillcolor="#8d3fd1", style=filled];
|
||||||
|
{ rank=same; n53; rh53; }
|
||||||
|
n53:sw -> rh53 [color="#8d3fd1", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh53 -> n25:sw [color="#8d3fd1", fontcolor="#8d3fd1", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh57 [shape=point, width=0.05, height=0.05, color="#9bd13f", fillcolor="#9bd13f", style=filled];
|
||||||
|
{ rank=same; n57; rh57; }
|
||||||
|
n57:se -> rh57 [color="#9bd13f", style=dashed, penwidth=1.2, arrowhead=none, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh57 -> n16:ne [color="#9bd13f", fontcolor="#9bd13f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh57 -> n21:se [color="#9bd13f", fontcolor="#9bd13f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
rh57 -> n54:ne [color="#9bd13f", fontcolor="#9bd13f", fontsize=8, style=dashed, penwidth=1.0, arrowsize=0.6, constraint=false, tailclip=true, headclip=true];
|
||||||
|
}
|
||||||
117
Project-02-03-04-05/cfg/CFG.py
Normal file
117
Project-02-03-04-05/cfg/CFG.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
from typing import Any, Callable, Set
|
||||||
|
from .CFG_Node import *
|
||||||
|
|
||||||
|
class CFG:
|
||||||
|
def __init__(self, ast):
|
||||||
|
start = CFG_START()
|
||||||
|
start.dot_style = 'style=filled, color=gray'
|
||||||
|
end = CFG_END()
|
||||||
|
end.dot_style = 'style=filled, color=gray'
|
||||||
|
|
||||||
|
last = ast.cfa(start, end)
|
||||||
|
if last is not None:
|
||||||
|
last.add_child(end)
|
||||||
|
|
||||||
|
self.START = start
|
||||||
|
self.END = end
|
||||||
|
self.ast = ast
|
||||||
|
|
||||||
|
# Remove empty nodes and rewire edges
|
||||||
|
all_nodes = self.nodes()
|
||||||
|
nodes_to_remove = [node for node in all_nodes if node.is_empty()]
|
||||||
|
for node in nodes_to_remove:
|
||||||
|
self.__remove_and_rewire(node)
|
||||||
|
|
||||||
|
def nodes(self):
|
||||||
|
all_nodes = set()
|
||||||
|
self.__collect_nodes(self.START, all_nodes)
|
||||||
|
return all_nodes
|
||||||
|
|
||||||
|
def __collect_nodes(self, node, node_set):
|
||||||
|
if node in node_set:
|
||||||
|
return
|
||||||
|
node_set.add(node)
|
||||||
|
for child in node.children:
|
||||||
|
self.__collect_nodes(child, node_set)
|
||||||
|
|
||||||
|
def __remove_and_rewire(self, node):
|
||||||
|
original_children = list(node.children)
|
||||||
|
|
||||||
|
for parent in list(node.parents):
|
||||||
|
if node in parent.children:
|
||||||
|
# For diamond nodes, preserve the true and false bodies
|
||||||
|
if isinstance(node, CFG_DIAMOND):
|
||||||
|
targets = []
|
||||||
|
if len(original_children) >= 1:
|
||||||
|
true_target = self.__first_filled_child(original_children[0])
|
||||||
|
if true_target:
|
||||||
|
targets.append(true_target)
|
||||||
|
if len(original_children) >= 2:
|
||||||
|
false_target = self.__first_filled_child(original_children[1])
|
||||||
|
if false_target:
|
||||||
|
targets.append(false_target)
|
||||||
|
# For regular nodes, find all non-empty targets
|
||||||
|
else:
|
||||||
|
targets = []
|
||||||
|
for child in original_children:
|
||||||
|
target = self.__first_filled_child(child)
|
||||||
|
if target and target not in targets:
|
||||||
|
targets.append(target)
|
||||||
|
|
||||||
|
# Remove edge from parent to node
|
||||||
|
parent.remove_child(node, propagate=False)
|
||||||
|
|
||||||
|
# Add edges from parent to targets
|
||||||
|
for target in targets:
|
||||||
|
parent.add_child(target, propagate=False)
|
||||||
|
|
||||||
|
# Clear the node's connections
|
||||||
|
node.parents.clear()
|
||||||
|
node.children.clear()
|
||||||
|
|
||||||
|
def __first_filled_child(self, node):
|
||||||
|
if not node.is_empty():
|
||||||
|
return node
|
||||||
|
# Recursively check children
|
||||||
|
for child in sorted(node.children, key=lambda n: n.id):
|
||||||
|
result = self.__first_filled_child(child)
|
||||||
|
if result is not None:
|
||||||
|
return result
|
||||||
|
return None
|
||||||
|
|
||||||
|
def to_dot(self) -> str:
|
||||||
|
lines = ["digraph CFG {", ' node [fontname="Helvetica"];']
|
||||||
|
|
||||||
|
def emit(node: CFG_Node):
|
||||||
|
label = node.dot_label()
|
||||||
|
shape = node.dot_shape
|
||||||
|
style = node.dot_style
|
||||||
|
style_str = f", {style}" if style else ""
|
||||||
|
lines.append(f' n{node.id} [label="{label}", shape={shape}{style_str}];')
|
||||||
|
|
||||||
|
for i, child in enumerate(sorted(node.children, key=lambda n: n.id)):
|
||||||
|
edge_label = ""
|
||||||
|
if isinstance(node, CFG_DIAMOND):
|
||||||
|
if i == 0:
|
||||||
|
edge_label = ' [label="T"]'
|
||||||
|
elif i == 1:
|
||||||
|
edge_label = ' [label="F"]'
|
||||||
|
lines.append(f" n{node.id} -> n{child.id}{edge_label};")
|
||||||
|
|
||||||
|
self.traverse(emit, start=self.START)
|
||||||
|
lines.append("}")
|
||||||
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
# Reusable traversal function
|
||||||
|
def traverse(self, fn: Callable[[CFG_Node], Any], start: CFG_Node | None = None) -> None:
|
||||||
|
start = start or self.START
|
||||||
|
visited: Set[int] = set()
|
||||||
|
|
||||||
|
def visit(node: CFG_Node):
|
||||||
|
if node.id in visited:
|
||||||
|
return
|
||||||
|
visited.add(node.id)
|
||||||
|
fn(node)
|
||||||
|
for child in sorted(node.children, key=lambda n: n.id):
|
||||||
|
visit(child)
|
||||||
|
visit(start)
|
||||||
96
Project-02-03-04-05/cfg/CFG_Node.py
Normal file
96
Project-02-03-04-05/cfg/CFG_Node.py
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
class CFG_Node:
|
||||||
|
__counter = 1
|
||||||
|
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
self.ast_node = ast_node
|
||||||
|
self.children = set()
|
||||||
|
self.parents = set()
|
||||||
|
|
||||||
|
self.label = None
|
||||||
|
self.dot_shape = 'box'
|
||||||
|
self.dot_style = ''
|
||||||
|
|
||||||
|
self.id = CFG_Node.__counter
|
||||||
|
CFG_Node.__counter += 1
|
||||||
|
|
||||||
|
def get_children(self):
|
||||||
|
return self.children
|
||||||
|
|
||||||
|
def get_parents(self):
|
||||||
|
return self.parents
|
||||||
|
|
||||||
|
def add_child(self, child: 'CFG_Node', propagate=True):
|
||||||
|
if propagate:
|
||||||
|
child.parents.add(self)
|
||||||
|
self.children.add(child)
|
||||||
|
|
||||||
|
def add_parent(self, parent: 'CFG_Node', propagate=True):
|
||||||
|
if propagate:
|
||||||
|
parent.add_child(self)
|
||||||
|
self.parents.add(parent)
|
||||||
|
|
||||||
|
def remove_child(self, child: 'CFG_Node', propagate=True):
|
||||||
|
if propagate:
|
||||||
|
child.parents.remove(self)
|
||||||
|
self.children.remove(child)
|
||||||
|
|
||||||
|
def remove_parent(self, parent: 'CFG_Node', propagate=True):
|
||||||
|
if propagate:
|
||||||
|
parent.children.remove(self)
|
||||||
|
self.parents.remove(parent)
|
||||||
|
|
||||||
|
def dot_label(self):
|
||||||
|
# Prioritize custom label
|
||||||
|
if self.label is not None:
|
||||||
|
return self.label
|
||||||
|
|
||||||
|
# Build label from AST node
|
||||||
|
if self.ast_node is not None:
|
||||||
|
return str(self.ast_node)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_filled(self):
|
||||||
|
return not self.is_empty()
|
||||||
|
|
||||||
|
def is_empty(self):
|
||||||
|
# Node is empty if it has no label and no related AST node
|
||||||
|
if self.label is None or self.label == "None":
|
||||||
|
if self.ast_node is not None:
|
||||||
|
# Node belongs to a ast node
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
# Node is required for the control flow
|
||||||
|
return False
|
||||||
|
|
||||||
|
class CFG_START(CFG_Node):
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
super().__init__(ast_node)
|
||||||
|
self.dot_shape = "ellipse"
|
||||||
|
self.dot_style = 'style=filled, color=green'
|
||||||
|
self.label = "START"
|
||||||
|
|
||||||
|
class CFG_END(CFG_Node):
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
super().__init__(ast_node)
|
||||||
|
self.dot_shape = "ellipse"
|
||||||
|
self.dot_style = 'style=filled, color=green'
|
||||||
|
self.label = "END"
|
||||||
|
|
||||||
|
class CFG_DIAMOND(CFG_Node):
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
super().__init__(ast_node)
|
||||||
|
self.dot_shape = "diamond"
|
||||||
|
self.label = "<?>"
|
||||||
|
|
||||||
|
class CFG_CALL(CFG_Node):
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
super().__init__(ast_node)
|
||||||
|
self.dot_style = 'style=filled, color=orange'
|
||||||
|
self.dot_shape = "box"
|
||||||
|
|
||||||
|
class CFG_RETURN(CFG_Node):
|
||||||
|
def __init__(self, ast_node=None):
|
||||||
|
super().__init__(ast_node)
|
||||||
|
self.dot_style = 'style=filled, color=orange'
|
||||||
|
self.dot_shape = "box"
|
||||||
307
Project-02-03-04-05/cfg_build.py
Normal file
307
Project-02-03-04-05/cfg_build.py
Normal file
@@ -0,0 +1,307 @@
|
|||||||
|
from cfg.CFG_Node import (
|
||||||
|
CFG_Node,
|
||||||
|
CFG_CALL,
|
||||||
|
CFG_RETURN,
|
||||||
|
CFG_DIAMOND,
|
||||||
|
CFG_START,
|
||||||
|
CFG_END,
|
||||||
|
)
|
||||||
|
|
||||||
|
import compiler
|
||||||
|
import syntax
|
||||||
|
|
||||||
|
# Global registry for function start/end nodes
|
||||||
|
FUNCTIONS = {}
|
||||||
|
|
||||||
|
# Global variable to track the current function being processed
|
||||||
|
CURRENT_FUNCTION = None
|
||||||
|
|
||||||
|
class CONST(compiler.CONST):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
node = CFG_Node(self)
|
||||||
|
pred.add_child(node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
node.add_child(end)
|
||||||
|
return node
|
||||||
|
|
||||||
|
class ID(compiler.ID):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
node = CFG_Node(self)
|
||||||
|
pred.add_child(node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
node.add_child(end)
|
||||||
|
return node
|
||||||
|
|
||||||
|
class AOP(compiler.AOP):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Create nodes for the used expressions and attach
|
||||||
|
left_node = self.arg1.cfa(pred)
|
||||||
|
right_node = self.arg2.cfa(left_node)
|
||||||
|
|
||||||
|
# Create the operator node and attach
|
||||||
|
op_node = CFG_Node(self)
|
||||||
|
op_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||||
|
right_node.add_child(op_node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
op_node.add_child(end)
|
||||||
|
return op_node
|
||||||
|
|
||||||
|
class COMP(compiler.COMP):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Create nodes for the used expressions and attach
|
||||||
|
left_node = self.arg1.cfa(pred)
|
||||||
|
right_node = self.arg2.cfa(left_node)
|
||||||
|
|
||||||
|
# Create the comparison node and attach
|
||||||
|
comp_node = CFG_Node(self)
|
||||||
|
comp_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||||
|
right_node.add_child(comp_node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
comp_node.add_child(end)
|
||||||
|
return comp_node
|
||||||
|
|
||||||
|
class EQOP(compiler.EQOP):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Create nodes for the used expressions and attach
|
||||||
|
left_node = self.arg1.cfa(pred)
|
||||||
|
right_node = self.arg2.cfa(left_node)
|
||||||
|
|
||||||
|
# Create the comparison node and attach
|
||||||
|
eqop_node = CFG_Node(self)
|
||||||
|
eqop_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||||
|
right_node.add_child(eqop_node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
eqop_node.add_child(end)
|
||||||
|
return eqop_node
|
||||||
|
|
||||||
|
class LOP(compiler.LOP):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Create nodes for each operand separately
|
||||||
|
left_node = self.arg1.cfa(pred)
|
||||||
|
right_node = self.arg2.cfa(left_node)
|
||||||
|
|
||||||
|
# Create the logical operation node with just the operator
|
||||||
|
lop_node = CFG_Node(self)
|
||||||
|
lop_node.label = f"{str(self.arg1)} {self.operator} {str(self.arg2)}"
|
||||||
|
right_node.add_child(lop_node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
lop_node.add_child(end)
|
||||||
|
return lop_node
|
||||||
|
|
||||||
|
class ASSIGN(compiler.ASSIGN):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Unwraps expressions needed for assignment
|
||||||
|
expr_node = self.expr.cfa(pred)
|
||||||
|
|
||||||
|
# Assignment node
|
||||||
|
assign_node = CFG_Node(self)
|
||||||
|
expr_node.add_child(assign_node)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
assign_node.add_child(end)
|
||||||
|
return assign_node
|
||||||
|
|
||||||
|
class SEQ(compiler.SEQ):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
mid = self.exp1.cfa(pred)
|
||||||
|
if mid is None:
|
||||||
|
return None
|
||||||
|
return self.exp2.cfa(mid, end)
|
||||||
|
|
||||||
|
class IF(compiler.IF):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Unwraps expressions needed for the condition
|
||||||
|
cond_node = self.cond.cfa(pred, None)
|
||||||
|
|
||||||
|
# Attach junction node
|
||||||
|
diamond = CFG_DIAMOND(self.cond)
|
||||||
|
cond_node.add_child(diamond)
|
||||||
|
|
||||||
|
# Define start and end entry and unwraps expressions
|
||||||
|
then_entry = CFG_Node()
|
||||||
|
diamond.add_child(then_entry)
|
||||||
|
else_entry = CFG_Node()
|
||||||
|
diamond.add_child(else_entry)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
join = CFG_Node()
|
||||||
|
if end is not None:
|
||||||
|
join.add_child(end)
|
||||||
|
|
||||||
|
# Connect the extracted expressions with the join
|
||||||
|
then_end = self.exp1.cfa(then_entry, join)
|
||||||
|
else_end = self.exp2.cfa(else_entry, join)
|
||||||
|
return join
|
||||||
|
|
||||||
|
class WHILE(compiler.WHILE):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Dedicated loop-head so every iteration re-evaluates the full condition.
|
||||||
|
cond_entry = CFG_Node()
|
||||||
|
pred.add_child(cond_entry)
|
||||||
|
|
||||||
|
if hasattr(self.cond, 'arg1') and hasattr(self.cond, 'arg2'):
|
||||||
|
# This is a comparison operation (e.g., a > b)
|
||||||
|
|
||||||
|
# Create the condition evaluation nodes
|
||||||
|
left_node = self.cond.arg1.cfa(cond_entry)
|
||||||
|
right_node = self.cond.arg2.cfa(left_node)
|
||||||
|
|
||||||
|
# Create the comparison node and attach
|
||||||
|
comp_node = CFG_Node(self.cond)
|
||||||
|
comp_node.label = f"{str(self.cond.arg1)} {self.cond.operator} {str(self.cond.arg2)}"
|
||||||
|
right_node.add_child(comp_node)
|
||||||
|
else:
|
||||||
|
# This is a simple condition (e.g., constant true/false)
|
||||||
|
cond_node = self.cond.cfa(cond_entry)
|
||||||
|
comp_node = cond_node
|
||||||
|
|
||||||
|
# Attach junction node
|
||||||
|
diamond = CFG_DIAMOND(self.cond)
|
||||||
|
comp_node.add_child(diamond)
|
||||||
|
|
||||||
|
# Unwrap the loop body
|
||||||
|
body_entry = CFG_Node()
|
||||||
|
diamond.add_child(body_entry)
|
||||||
|
|
||||||
|
# The body should connect back to the start of condition evaluation
|
||||||
|
body_end = self.body.cfa(body_entry)
|
||||||
|
if body_end is not None:
|
||||||
|
# Connect loop body back to full condition evaluation.
|
||||||
|
body_end.add_child(cond_entry)
|
||||||
|
|
||||||
|
# Attach joining node
|
||||||
|
after = CFG_Node()
|
||||||
|
diamond.add_child(after)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
after.add_child(end)
|
||||||
|
return after
|
||||||
|
|
||||||
|
class CALL(compiler.CALL):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# Create nodes for all argument values
|
||||||
|
current_arg_node = pred
|
||||||
|
for i, arg in enumerate(self.arg):
|
||||||
|
current_arg_node = arg.cfa(current_arg_node)
|
||||||
|
|
||||||
|
# Create and attach the call node
|
||||||
|
call_node = CFG_CALL(self)
|
||||||
|
call_node.label = f"CALL {self.f_name}"
|
||||||
|
current_arg_node.add_child(call_node)
|
||||||
|
|
||||||
|
# Create and attach the exit node
|
||||||
|
cont = CFG_Node()
|
||||||
|
if end is not None:
|
||||||
|
cont.add_child(end)
|
||||||
|
|
||||||
|
# Find the functions in the function list
|
||||||
|
if self.f_name not in FUNCTIONS:
|
||||||
|
raise RuntimeError(f"Call to undefined function '{self.f_name}'")
|
||||||
|
# Determine the start and exit node of the function
|
||||||
|
f_start, f_end = FUNCTIONS[self.f_name]
|
||||||
|
|
||||||
|
# Create return node from function
|
||||||
|
return_node = CFG_RETURN(self)
|
||||||
|
return_node.label = f"RET {self.f_name}"
|
||||||
|
f_end.add_child(return_node)
|
||||||
|
return_node.add_child(cont)
|
||||||
|
|
||||||
|
# Span the start and exit nodes to the method body
|
||||||
|
call_node.add_child(f_start)
|
||||||
|
call_node.add_child(return_node)
|
||||||
|
|
||||||
|
# Return value flow for recursive calls
|
||||||
|
if CURRENT_FUNCTION is not None and self.f_name == CURRENT_FUNCTION:
|
||||||
|
return_node.add_child(cont)
|
||||||
|
return cont
|
||||||
|
|
||||||
|
class DECL(compiler.DECL):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
# Check if a function is already registered
|
||||||
|
if self.f_name in FUNCTIONS:
|
||||||
|
f_start, f_end = FUNCTIONS[self.f_name]
|
||||||
|
else:
|
||||||
|
# Span the method body into a start and end node
|
||||||
|
f_start = CFG_START(self)
|
||||||
|
f_start.label = f"START {self.f_name}({', '.join(self.params)})"
|
||||||
|
f_end = CFG_END(self)
|
||||||
|
f_end.label = f"END {self.f_name}({', '.join(self.params)})"
|
||||||
|
FUNCTIONS[self.f_name] = (f_start, f_end)
|
||||||
|
|
||||||
|
# Set the current function context for recursion detection
|
||||||
|
global CURRENT_FUNCTION
|
||||||
|
previous_function = CURRENT_FUNCTION
|
||||||
|
CURRENT_FUNCTION = self.f_name
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Unwrap the method body
|
||||||
|
body_end = self.body.cfa(f_start, f_end)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if body_end is not None:
|
||||||
|
body_end.add_child(f_end)
|
||||||
|
finally:
|
||||||
|
# Restore the previous function context
|
||||||
|
CURRENT_FUNCTION = previous_function
|
||||||
|
|
||||||
|
return pred
|
||||||
|
|
||||||
|
class LET(compiler.LET):
|
||||||
|
def cfa(self, pred, end = None):
|
||||||
|
# First pass: Register all function declarations
|
||||||
|
decls = self.decl if isinstance(self.decl, list) else [self.decl]
|
||||||
|
for d in decls:
|
||||||
|
if isinstance(d, compiler.DECL):
|
||||||
|
# Register function without building CFG yet
|
||||||
|
f_start = CFG_START(d)
|
||||||
|
f_start.label = f"START {d.f_name}({', '.join(d.params)})"
|
||||||
|
f_end = CFG_END(d)
|
||||||
|
f_end.label = f"END {d.f_name}({', '.join(d.params)})"
|
||||||
|
FUNCTIONS[d.f_name] = (f_start, f_end)
|
||||||
|
|
||||||
|
# Create a global entry node for the function
|
||||||
|
global_entry = CFG_Node()
|
||||||
|
global_entry.label = "None"
|
||||||
|
pred.add_child(global_entry)
|
||||||
|
current = global_entry
|
||||||
|
|
||||||
|
# Generate function declarations
|
||||||
|
for d in decls:
|
||||||
|
current = d.cfa(current, None)
|
||||||
|
if current is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Unwrap the body
|
||||||
|
body_result = self.body.cfa(current, end)
|
||||||
|
|
||||||
|
# Create global exit node
|
||||||
|
global_exit = CFG_Node()
|
||||||
|
global_exit.label = "None"
|
||||||
|
if body_result is not None:
|
||||||
|
body_result.add_child(global_exit)
|
||||||
|
|
||||||
|
# Attach the end node if it is provided
|
||||||
|
if end is not None:
|
||||||
|
global_exit.add_child(end)
|
||||||
|
return global_exit
|
||||||
|
|
||||||
|
class RETURN(syntax.EXPRESSION):
|
||||||
|
def cfa(self, pred, end):
|
||||||
|
n = CFG_RETURN(self)
|
||||||
|
pred.add_child(n)
|
||||||
|
n.add_child(end)
|
||||||
|
return None
|
||||||
23
Project-02-03-04-05/cfgdots/argsParamsExample.dot
Normal file
23
Project-02-03-04-05/cfgdots/argsParamsExample.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1 -> n7;
|
||||||
|
n7 [label="1", shape=box];
|
||||||
|
n7 -> n8;
|
||||||
|
n8 [label="2", shape=box];
|
||||||
|
n8 -> n9;
|
||||||
|
n9 [label="3", shape=box];
|
||||||
|
n9 -> n10;
|
||||||
|
n10 [label="CALL a", shape=box, style=filled, color=orange];
|
||||||
|
n10 -> n3;
|
||||||
|
n10 -> n12;
|
||||||
|
n3 [label="START a(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n3 -> n6;
|
||||||
|
n6 [label="x", shape=box];
|
||||||
|
n6 -> n4;
|
||||||
|
n4 [label="END a(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n4 -> n12;
|
||||||
|
n12 [label="RET a", shape=box, style=filled, color=orange];
|
||||||
|
n12 -> n2;
|
||||||
|
n2 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
127
Project-02-03-04-05/cfgdots/complex.dot
Normal file
127
Project-02-03-04-05/cfgdots/complex.dot
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n14 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n14 -> n65;
|
||||||
|
n65 [label="10", shape=box];
|
||||||
|
n65 -> n66;
|
||||||
|
n66 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n66 -> n16;
|
||||||
|
n66 -> n68;
|
||||||
|
n16 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n16 -> n21;
|
||||||
|
n21 [label="b", shape=box];
|
||||||
|
n21 -> n22;
|
||||||
|
n22 [label="0", shape=box];
|
||||||
|
n22 -> n23;
|
||||||
|
n23 [label="b == 0", shape=box];
|
||||||
|
n23 -> n24;
|
||||||
|
n24 [label="<?>", shape=diamond];
|
||||||
|
n24 -> n28 [label="T"];
|
||||||
|
n24 -> n29 [label="F"];
|
||||||
|
n28 [label="0", shape=box];
|
||||||
|
n28 -> n17;
|
||||||
|
n17 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n17 -> n34;
|
||||||
|
n17 -> n45;
|
||||||
|
n17 -> n49;
|
||||||
|
n17 -> n68;
|
||||||
|
n34 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n34 -> n17;
|
||||||
|
n45 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n45 -> n58;
|
||||||
|
n58 [label="a", shape=box];
|
||||||
|
n58 -> n59;
|
||||||
|
n59 [label="b", shape=box];
|
||||||
|
n59 -> n60;
|
||||||
|
n60 [label="a * b", shape=box];
|
||||||
|
n60 -> n61;
|
||||||
|
n61 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n61 -> n50;
|
||||||
|
n61 -> n63;
|
||||||
|
n50 [label="START g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n50 -> n53;
|
||||||
|
n53 [label="a", shape=box];
|
||||||
|
n53 -> n54;
|
||||||
|
n54 [label="b", shape=box];
|
||||||
|
n54 -> n55;
|
||||||
|
n55 [label="a * b", shape=box];
|
||||||
|
n55 -> n56;
|
||||||
|
n56 [label="c", shape=box];
|
||||||
|
n56 -> n57;
|
||||||
|
n57 [label="(a * b) * c", shape=box];
|
||||||
|
n57 -> n51;
|
||||||
|
n51 [label="END g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n51 -> n63;
|
||||||
|
n63 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n63 -> n19;
|
||||||
|
n19 [label="END f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n19 -> n91;
|
||||||
|
n91 [label="RET f2", shape=box, style=filled, color=orange];
|
||||||
|
n91 -> n15;
|
||||||
|
n15 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n49 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n49 -> n58;
|
||||||
|
n68 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n68 -> n70;
|
||||||
|
n70 [label="10", shape=box];
|
||||||
|
n70 -> n83;
|
||||||
|
n83 [label="20", shape=box];
|
||||||
|
n83 -> n84;
|
||||||
|
n84 [label="30", shape=box];
|
||||||
|
n84 -> n85;
|
||||||
|
n85 [label="CALL max", shape=box, style=filled, color=orange];
|
||||||
|
n85 -> n71;
|
||||||
|
n85 -> n87;
|
||||||
|
n71 [label="START max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n71 -> n74;
|
||||||
|
n74 [label="a", shape=box];
|
||||||
|
n74 -> n75;
|
||||||
|
n75 [label="b", shape=box];
|
||||||
|
n75 -> n76;
|
||||||
|
n76 [label="a > b", shape=box];
|
||||||
|
n76 -> n77;
|
||||||
|
n77 [label="<?>", shape=diamond];
|
||||||
|
n77 -> n81 [label="T"];
|
||||||
|
n77 -> n82 [label="F"];
|
||||||
|
n81 [label="a", shape=box];
|
||||||
|
n81 -> n72;
|
||||||
|
n72 [label="END max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n72 -> n87;
|
||||||
|
n87 [label="RET max", shape=box, style=filled, color=orange];
|
||||||
|
n87 -> n89;
|
||||||
|
n89 [label="CALL f2", shape=box, style=filled, color=orange];
|
||||||
|
n89 -> n18;
|
||||||
|
n89 -> n91;
|
||||||
|
n18 [label="START f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n18 -> n35;
|
||||||
|
n35 [label="a", shape=box];
|
||||||
|
n35 -> n36;
|
||||||
|
n36 [label="b", shape=box];
|
||||||
|
n36 -> n37;
|
||||||
|
n37 [label="a > b", shape=box];
|
||||||
|
n37 -> n38;
|
||||||
|
n38 [label="<?>", shape=diamond];
|
||||||
|
n38 -> n42 [label="T"];
|
||||||
|
n38 -> n46 [label="F"];
|
||||||
|
n42 [label="a", shape=box];
|
||||||
|
n42 -> n43;
|
||||||
|
n43 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n43 -> n16;
|
||||||
|
n43 -> n45;
|
||||||
|
n46 [label="b", shape=box];
|
||||||
|
n46 -> n47;
|
||||||
|
n47 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n47 -> n16;
|
||||||
|
n47 -> n49;
|
||||||
|
n82 [label="b", shape=box];
|
||||||
|
n82 -> n72;
|
||||||
|
n29 [label="b", shape=box];
|
||||||
|
n29 -> n30;
|
||||||
|
n30 [label="1", shape=box];
|
||||||
|
n30 -> n31;
|
||||||
|
n31 [label="b - 1", shape=box];
|
||||||
|
n31 -> n32;
|
||||||
|
n32 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n32 -> n16;
|
||||||
|
n32 -> n34;
|
||||||
|
}
|
||||||
27
Project-02-03-04-05/cfgdots/condition.dot
Normal file
27
Project-02-03-04-05/cfgdots/condition.dot
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n92 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n92 -> n94;
|
||||||
|
n94 [label="2", shape=box];
|
||||||
|
n94 -> n95;
|
||||||
|
n95 [label="x", shape=box];
|
||||||
|
n95 -> n96;
|
||||||
|
n96 [label="2 < x", shape=box];
|
||||||
|
n96 -> n97;
|
||||||
|
n97 [label="x", shape=box];
|
||||||
|
n97 -> n98;
|
||||||
|
n98 [label="9", shape=box];
|
||||||
|
n98 -> n99;
|
||||||
|
n99 [label="x > 9", shape=box];
|
||||||
|
n99 -> n100;
|
||||||
|
n100 [label="(2 < x) && (x > 9)", shape=box];
|
||||||
|
n100 -> n101;
|
||||||
|
n101 [label="<?>", shape=diamond];
|
||||||
|
n101 -> n105 [label="T"];
|
||||||
|
n101 -> n106 [label="F"];
|
||||||
|
n105 [label="1", shape=box];
|
||||||
|
n105 -> n93;
|
||||||
|
n93 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n106 [label="0", shape=box];
|
||||||
|
n106 -> n93;
|
||||||
|
}
|
||||||
45
Project-02-03-04-05/cfgdots/defSemiExample.dot
Normal file
45
Project-02-03-04-05/cfgdots/defSemiExample.dot
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n107 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n107 -> n119;
|
||||||
|
n119 [label="1", shape=box];
|
||||||
|
n119 -> n120;
|
||||||
|
n120 [label="CALL a", shape=box, style=filled, color=orange];
|
||||||
|
n120 -> n109;
|
||||||
|
n120 -> n122;
|
||||||
|
n109 [label="START a(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n109 -> n116;
|
||||||
|
n116 [label="x", shape=box];
|
||||||
|
n116 -> n110;
|
||||||
|
n110 [label="END a(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n110 -> n122;
|
||||||
|
n122 [label="RET a", shape=box, style=filled, color=orange];
|
||||||
|
n122 -> n124;
|
||||||
|
n124 [label="2", shape=box];
|
||||||
|
n124 -> n125;
|
||||||
|
n125 [label="CALL b", shape=box, style=filled, color=orange];
|
||||||
|
n125 -> n111;
|
||||||
|
n125 -> n127;
|
||||||
|
n111 [label="START b(y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n111 -> n117;
|
||||||
|
n117 [label="y", shape=box];
|
||||||
|
n117 -> n112;
|
||||||
|
n112 [label="END b(y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n112 -> n127;
|
||||||
|
n127 [label="RET b", shape=box, style=filled, color=orange];
|
||||||
|
n127 -> n128;
|
||||||
|
n128 [label="3", shape=box];
|
||||||
|
n128 -> n129;
|
||||||
|
n129 [label="CALL c", shape=box, style=filled, color=orange];
|
||||||
|
n129 -> n113;
|
||||||
|
n129 -> n131;
|
||||||
|
n113 [label="START c(z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n113 -> n118;
|
||||||
|
n118 [label="z", shape=box];
|
||||||
|
n118 -> n114;
|
||||||
|
n114 [label="END c(z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n114 -> n131;
|
||||||
|
n131 [label="RET c", shape=box, style=filled, color=orange];
|
||||||
|
n131 -> n108;
|
||||||
|
n108 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
69
Project-02-03-04-05/cfgdots/example.dot
Normal file
69
Project-02-03-04-05/cfgdots/example.dot
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n132 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n132 -> n167;
|
||||||
|
n167 [label="2", shape=box];
|
||||||
|
n167 -> n168;
|
||||||
|
n168 [label="3", shape=box];
|
||||||
|
n168 -> n169;
|
||||||
|
n169 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n169 -> n134;
|
||||||
|
n169 -> n171;
|
||||||
|
n134 [label="START f(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n134 -> n137;
|
||||||
|
n137 [label="2", shape=box];
|
||||||
|
n137 -> n138;
|
||||||
|
n138 [label="y = 2", shape=box];
|
||||||
|
n138 -> n139;
|
||||||
|
n139 [label="3", shape=box];
|
||||||
|
n139 -> n140;
|
||||||
|
n140 [label="z = 3", shape=box];
|
||||||
|
n140 -> n160;
|
||||||
|
n160 [label="x", shape=box];
|
||||||
|
n160 -> n161;
|
||||||
|
n161 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n161 -> n141;
|
||||||
|
n161 -> n163;
|
||||||
|
n141 [label="START g(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n141 -> n144;
|
||||||
|
n144 [label="7", shape=box];
|
||||||
|
n144 -> n145;
|
||||||
|
n145 [label="x = 7", shape=box];
|
||||||
|
n145 -> n146;
|
||||||
|
n146 [label="y", shape=box];
|
||||||
|
n146 -> n147;
|
||||||
|
n147 [label="0", shape=box];
|
||||||
|
n147 -> n148;
|
||||||
|
n148 [label="y > 0", shape=box];
|
||||||
|
n148 -> n149;
|
||||||
|
n149 [label="<?>", shape=diamond];
|
||||||
|
n149 -> n153 [label="T"];
|
||||||
|
n149 -> n157 [label="F"];
|
||||||
|
n153 [label="y", shape=box];
|
||||||
|
n153 -> n154;
|
||||||
|
n154 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n154 -> n141;
|
||||||
|
n154 -> n156;
|
||||||
|
n156 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n156 -> n159;
|
||||||
|
n159 [label="x", shape=box];
|
||||||
|
n159 -> n142;
|
||||||
|
n142 [label="END g(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n142 -> n156;
|
||||||
|
n142 -> n163;
|
||||||
|
n163 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n163 -> n164;
|
||||||
|
n164 [label="x", shape=box];
|
||||||
|
n164 -> n165;
|
||||||
|
n165 [label="g(x) + x", shape=box];
|
||||||
|
n165 -> n135;
|
||||||
|
n135 [label="END f(x, y, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n135 -> n171;
|
||||||
|
n171 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n171 -> n133;
|
||||||
|
n133 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n157 [label="8", shape=box];
|
||||||
|
n157 -> n158;
|
||||||
|
n158 [label="x = 8", shape=box];
|
||||||
|
n158 -> n159;
|
||||||
|
}
|
||||||
268
Project-02-03-04-05/cfgdots/factorial.dot
Normal file
268
Project-02-03-04-05/cfgdots/factorial.dot
Normal file
@@ -0,0 +1,268 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n173 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n173 -> n338;
|
||||||
|
n338 [label="3", shape=box];
|
||||||
|
n338 -> n339;
|
||||||
|
n339 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n339 -> n191;
|
||||||
|
n339 -> n341;
|
||||||
|
n191 [label="START fac(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n191 -> n194;
|
||||||
|
n191 -> n210;
|
||||||
|
n191 -> n226;
|
||||||
|
n191 -> n242;
|
||||||
|
n191 -> n258;
|
||||||
|
n191 -> n274;
|
||||||
|
n191 -> n290;
|
||||||
|
n191 -> n306;
|
||||||
|
n191 -> n322;
|
||||||
|
n194 [label="x", shape=box];
|
||||||
|
n194 -> n195;
|
||||||
|
n195 [label="1", shape=box];
|
||||||
|
n195 -> n196;
|
||||||
|
n196 [label="x == 1", shape=box];
|
||||||
|
n196 -> n197;
|
||||||
|
n197 [label="<?>", shape=diamond];
|
||||||
|
n197 -> n201 [label="T"];
|
||||||
|
n197 -> n202 [label="F"];
|
||||||
|
n201 [label="1", shape=box];
|
||||||
|
n201 -> n192;
|
||||||
|
n192 [label="END fac(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n192 -> n207;
|
||||||
|
n192 -> n223;
|
||||||
|
n192 -> n239;
|
||||||
|
n192 -> n255;
|
||||||
|
n192 -> n271;
|
||||||
|
n192 -> n287;
|
||||||
|
n192 -> n303;
|
||||||
|
n192 -> n319;
|
||||||
|
n192 -> n335;
|
||||||
|
n192 -> n341;
|
||||||
|
n207 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n207 -> n208;
|
||||||
|
n208 [label="x", shape=box];
|
||||||
|
n208 -> n209;
|
||||||
|
n209 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n209 -> n192;
|
||||||
|
n223 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n223 -> n224;
|
||||||
|
n224 [label="x", shape=box];
|
||||||
|
n224 -> n225;
|
||||||
|
n225 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n225 -> n192;
|
||||||
|
n239 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n239 -> n240;
|
||||||
|
n240 [label="x", shape=box];
|
||||||
|
n240 -> n241;
|
||||||
|
n241 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n241 -> n192;
|
||||||
|
n255 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n255 -> n256;
|
||||||
|
n256 [label="x", shape=box];
|
||||||
|
n256 -> n257;
|
||||||
|
n257 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n257 -> n192;
|
||||||
|
n271 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n271 -> n272;
|
||||||
|
n272 [label="x", shape=box];
|
||||||
|
n272 -> n273;
|
||||||
|
n273 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n273 -> n192;
|
||||||
|
n287 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n287 -> n288;
|
||||||
|
n288 [label="x", shape=box];
|
||||||
|
n288 -> n289;
|
||||||
|
n289 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n289 -> n192;
|
||||||
|
n303 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n303 -> n304;
|
||||||
|
n304 [label="x", shape=box];
|
||||||
|
n304 -> n305;
|
||||||
|
n305 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n305 -> n192;
|
||||||
|
n319 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n319 -> n320;
|
||||||
|
n320 [label="x", shape=box];
|
||||||
|
n320 -> n321;
|
||||||
|
n321 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n321 -> n192;
|
||||||
|
n335 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n335 -> n336;
|
||||||
|
n336 [label="x", shape=box];
|
||||||
|
n336 -> n337;
|
||||||
|
n337 [label="fac((x - 1)) * x", shape=box];
|
||||||
|
n337 -> n192;
|
||||||
|
n341 [label="RET fac", shape=box, style=filled, color=orange];
|
||||||
|
n341 -> n174;
|
||||||
|
n174 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n202 [label="x", shape=box];
|
||||||
|
n202 -> n203;
|
||||||
|
n203 [label="1", shape=box];
|
||||||
|
n203 -> n204;
|
||||||
|
n204 [label="x - 1", shape=box];
|
||||||
|
n204 -> n205;
|
||||||
|
n205 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n205 -> n191;
|
||||||
|
n205 -> n207;
|
||||||
|
n210 [label="x", shape=box];
|
||||||
|
n210 -> n211;
|
||||||
|
n211 [label="1", shape=box];
|
||||||
|
n211 -> n212;
|
||||||
|
n212 [label="x == 1", shape=box];
|
||||||
|
n212 -> n213;
|
||||||
|
n213 [label="<?>", shape=diamond];
|
||||||
|
n213 -> n217 [label="T"];
|
||||||
|
n213 -> n218 [label="F"];
|
||||||
|
n217 [label="1", shape=box];
|
||||||
|
n217 -> n192;
|
||||||
|
n218 [label="x", shape=box];
|
||||||
|
n218 -> n219;
|
||||||
|
n219 [label="1", shape=box];
|
||||||
|
n219 -> n220;
|
||||||
|
n220 [label="x - 1", shape=box];
|
||||||
|
n220 -> n221;
|
||||||
|
n221 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n221 -> n191;
|
||||||
|
n221 -> n223;
|
||||||
|
n226 [label="x", shape=box];
|
||||||
|
n226 -> n227;
|
||||||
|
n227 [label="1", shape=box];
|
||||||
|
n227 -> n228;
|
||||||
|
n228 [label="x == 1", shape=box];
|
||||||
|
n228 -> n229;
|
||||||
|
n229 [label="<?>", shape=diamond];
|
||||||
|
n229 -> n233 [label="T"];
|
||||||
|
n229 -> n234 [label="F"];
|
||||||
|
n233 [label="1", shape=box];
|
||||||
|
n233 -> n192;
|
||||||
|
n234 [label="x", shape=box];
|
||||||
|
n234 -> n235;
|
||||||
|
n235 [label="1", shape=box];
|
||||||
|
n235 -> n236;
|
||||||
|
n236 [label="x - 1", shape=box];
|
||||||
|
n236 -> n237;
|
||||||
|
n237 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n237 -> n191;
|
||||||
|
n237 -> n239;
|
||||||
|
n242 [label="x", shape=box];
|
||||||
|
n242 -> n243;
|
||||||
|
n243 [label="1", shape=box];
|
||||||
|
n243 -> n244;
|
||||||
|
n244 [label="x == 1", shape=box];
|
||||||
|
n244 -> n245;
|
||||||
|
n245 [label="<?>", shape=diamond];
|
||||||
|
n245 -> n249 [label="T"];
|
||||||
|
n245 -> n250 [label="F"];
|
||||||
|
n249 [label="1", shape=box];
|
||||||
|
n249 -> n192;
|
||||||
|
n250 [label="x", shape=box];
|
||||||
|
n250 -> n251;
|
||||||
|
n251 [label="1", shape=box];
|
||||||
|
n251 -> n252;
|
||||||
|
n252 [label="x - 1", shape=box];
|
||||||
|
n252 -> n253;
|
||||||
|
n253 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n253 -> n191;
|
||||||
|
n253 -> n255;
|
||||||
|
n258 [label="x", shape=box];
|
||||||
|
n258 -> n259;
|
||||||
|
n259 [label="1", shape=box];
|
||||||
|
n259 -> n260;
|
||||||
|
n260 [label="x == 1", shape=box];
|
||||||
|
n260 -> n261;
|
||||||
|
n261 [label="<?>", shape=diamond];
|
||||||
|
n261 -> n265 [label="T"];
|
||||||
|
n261 -> n266 [label="F"];
|
||||||
|
n265 [label="1", shape=box];
|
||||||
|
n265 -> n192;
|
||||||
|
n266 [label="x", shape=box];
|
||||||
|
n266 -> n267;
|
||||||
|
n267 [label="1", shape=box];
|
||||||
|
n267 -> n268;
|
||||||
|
n268 [label="x - 1", shape=box];
|
||||||
|
n268 -> n269;
|
||||||
|
n269 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n269 -> n191;
|
||||||
|
n269 -> n271;
|
||||||
|
n274 [label="x", shape=box];
|
||||||
|
n274 -> n275;
|
||||||
|
n275 [label="1", shape=box];
|
||||||
|
n275 -> n276;
|
||||||
|
n276 [label="x == 1", shape=box];
|
||||||
|
n276 -> n277;
|
||||||
|
n277 [label="<?>", shape=diamond];
|
||||||
|
n277 -> n281 [label="T"];
|
||||||
|
n277 -> n282 [label="F"];
|
||||||
|
n281 [label="1", shape=box];
|
||||||
|
n281 -> n192;
|
||||||
|
n282 [label="x", shape=box];
|
||||||
|
n282 -> n283;
|
||||||
|
n283 [label="1", shape=box];
|
||||||
|
n283 -> n284;
|
||||||
|
n284 [label="x - 1", shape=box];
|
||||||
|
n284 -> n285;
|
||||||
|
n285 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n285 -> n191;
|
||||||
|
n285 -> n287;
|
||||||
|
n290 [label="x", shape=box];
|
||||||
|
n290 -> n291;
|
||||||
|
n291 [label="1", shape=box];
|
||||||
|
n291 -> n292;
|
||||||
|
n292 [label="x == 1", shape=box];
|
||||||
|
n292 -> n293;
|
||||||
|
n293 [label="<?>", shape=diamond];
|
||||||
|
n293 -> n297 [label="T"];
|
||||||
|
n293 -> n298 [label="F"];
|
||||||
|
n297 [label="1", shape=box];
|
||||||
|
n297 -> n192;
|
||||||
|
n298 [label="x", shape=box];
|
||||||
|
n298 -> n299;
|
||||||
|
n299 [label="1", shape=box];
|
||||||
|
n299 -> n300;
|
||||||
|
n300 [label="x - 1", shape=box];
|
||||||
|
n300 -> n301;
|
||||||
|
n301 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n301 -> n191;
|
||||||
|
n301 -> n303;
|
||||||
|
n306 [label="x", shape=box];
|
||||||
|
n306 -> n307;
|
||||||
|
n307 [label="1", shape=box];
|
||||||
|
n307 -> n308;
|
||||||
|
n308 [label="x == 1", shape=box];
|
||||||
|
n308 -> n309;
|
||||||
|
n309 [label="<?>", shape=diamond];
|
||||||
|
n309 -> n313 [label="T"];
|
||||||
|
n309 -> n314 [label="F"];
|
||||||
|
n313 [label="1", shape=box];
|
||||||
|
n313 -> n192;
|
||||||
|
n314 [label="x", shape=box];
|
||||||
|
n314 -> n315;
|
||||||
|
n315 [label="1", shape=box];
|
||||||
|
n315 -> n316;
|
||||||
|
n316 [label="x - 1", shape=box];
|
||||||
|
n316 -> n317;
|
||||||
|
n317 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n317 -> n191;
|
||||||
|
n317 -> n319;
|
||||||
|
n322 [label="x", shape=box];
|
||||||
|
n322 -> n323;
|
||||||
|
n323 [label="1", shape=box];
|
||||||
|
n323 -> n324;
|
||||||
|
n324 [label="x == 1", shape=box];
|
||||||
|
n324 -> n325;
|
||||||
|
n325 [label="<?>", shape=diamond];
|
||||||
|
n325 -> n329 [label="T"];
|
||||||
|
n325 -> n330 [label="F"];
|
||||||
|
n329 [label="1", shape=box];
|
||||||
|
n329 -> n192;
|
||||||
|
n330 [label="x", shape=box];
|
||||||
|
n330 -> n331;
|
||||||
|
n331 [label="1", shape=box];
|
||||||
|
n331 -> n332;
|
||||||
|
n332 [label="x - 1", shape=box];
|
||||||
|
n332 -> n333;
|
||||||
|
n333 [label="CALL fac", shape=box, style=filled, color=orange];
|
||||||
|
n333 -> n191;
|
||||||
|
n333 -> n335;
|
||||||
|
}
|
||||||
8
Project-02-03-04-05/cfgdots/faulty_if.dot
Normal file
8
Project-02-03-04-05/cfgdots/faulty_if.dot
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n356 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n356 -> n358;
|
||||||
|
n358 [label="0", shape=box];
|
||||||
|
n358 -> n357;
|
||||||
|
n357 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
52
Project-02-03-04-05/cfgdots/func.dot
Normal file
52
Project-02-03-04-05/cfgdots/func.dot
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n359 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n359 -> n382;
|
||||||
|
n382 [label="10", shape=box];
|
||||||
|
n382 -> n383;
|
||||||
|
n383 [label="8", shape=box];
|
||||||
|
n383 -> n384;
|
||||||
|
n384 [label="CALL func", shape=box, style=filled, color=orange];
|
||||||
|
n384 -> n361;
|
||||||
|
n384 -> n386;
|
||||||
|
n361 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n361 -> n364;
|
||||||
|
n364 [label="a", shape=box];
|
||||||
|
n364 -> n365;
|
||||||
|
n365 [label="0", shape=box];
|
||||||
|
n365 -> n366;
|
||||||
|
n366 [label="a > 0", shape=box];
|
||||||
|
n366 -> n367;
|
||||||
|
n367 [label="b", shape=box];
|
||||||
|
n367 -> n368;
|
||||||
|
n368 [label="a", shape=box];
|
||||||
|
n368 -> n369;
|
||||||
|
n369 [label="b != a", shape=box];
|
||||||
|
n369 -> n370;
|
||||||
|
n370 [label="(a > 0) && (b != a)", shape=box];
|
||||||
|
n370 -> n371;
|
||||||
|
n371 [label="<?>", shape=diamond];
|
||||||
|
n371 -> n362 [label="T"];
|
||||||
|
n371 -> n373 [label="F"];
|
||||||
|
n362 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n362 -> n386;
|
||||||
|
n386 [label="RET func", shape=box, style=filled, color=orange];
|
||||||
|
n386 -> n360;
|
||||||
|
n360 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n373 [label="b", shape=box];
|
||||||
|
n373 -> n374;
|
||||||
|
n374 [label="1", shape=box];
|
||||||
|
n374 -> n375;
|
||||||
|
n375 [label="b + 1", shape=box];
|
||||||
|
n375 -> n376;
|
||||||
|
n376 [label="b = (b + 1)", shape=box];
|
||||||
|
n376 -> n377;
|
||||||
|
n377 [label="a", shape=box];
|
||||||
|
n377 -> n378;
|
||||||
|
n378 [label="1", shape=box];
|
||||||
|
n378 -> n379;
|
||||||
|
n379 [label="a - 1", shape=box];
|
||||||
|
n379 -> n380;
|
||||||
|
n380 [label="a = (a - 1)", shape=box];
|
||||||
|
n380 -> n366;
|
||||||
|
}
|
||||||
19
Project-02-03-04-05/cfgdots/geq.dot
Normal file
19
Project-02-03-04-05/cfgdots/geq.dot
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n388 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n388 -> n390;
|
||||||
|
n390 [label="1", shape=box];
|
||||||
|
n390 -> n391;
|
||||||
|
n391 [label="0", shape=box];
|
||||||
|
n391 -> n392;
|
||||||
|
n392 [label="1 >= 0", shape=box];
|
||||||
|
n392 -> n393;
|
||||||
|
n393 [label="<?>", shape=diamond];
|
||||||
|
n393 -> n397 [label="T"];
|
||||||
|
n393 -> n398 [label="F"];
|
||||||
|
n397 [label="1", shape=box];
|
||||||
|
n397 -> n389;
|
||||||
|
n389 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n398 [label="0", shape=box];
|
||||||
|
n398 -> n389;
|
||||||
|
}
|
||||||
67
Project-02-03-04-05/cfgdots/ggT_euclid_rec.dot
Normal file
67
Project-02-03-04-05/cfgdots/ggT_euclid_rec.dot
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n405 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n405 -> n439;
|
||||||
|
n439 [label="2", shape=box];
|
||||||
|
n439 -> n440;
|
||||||
|
n440 [label="8", shape=box];
|
||||||
|
n440 -> n441;
|
||||||
|
n441 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||||
|
n441 -> n407;
|
||||||
|
n441 -> n443;
|
||||||
|
n407 [label="START ggT(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n407 -> n410;
|
||||||
|
n410 [label="a", shape=box];
|
||||||
|
n410 -> n411;
|
||||||
|
n411 [label="b", shape=box];
|
||||||
|
n411 -> n412;
|
||||||
|
n412 [label="a == b", shape=box];
|
||||||
|
n412 -> n413;
|
||||||
|
n413 [label="<?>", shape=diamond];
|
||||||
|
n413 -> n417 [label="T"];
|
||||||
|
n413 -> n418 [label="F"];
|
||||||
|
n417 [label="a", shape=box];
|
||||||
|
n417 -> n408;
|
||||||
|
n408 [label="END ggT(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n408 -> n431;
|
||||||
|
n408 -> n438;
|
||||||
|
n408 -> n443;
|
||||||
|
n431 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||||
|
n431 -> n408;
|
||||||
|
n438 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||||
|
n438 -> n408;
|
||||||
|
n443 [label="RET ggT", shape=box, style=filled, color=orange];
|
||||||
|
n443 -> n406;
|
||||||
|
n406 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n418 [label="a", shape=box];
|
||||||
|
n418 -> n419;
|
||||||
|
n419 [label="b", shape=box];
|
||||||
|
n419 -> n420;
|
||||||
|
n420 [label="a > b", shape=box];
|
||||||
|
n420 -> n421;
|
||||||
|
n421 [label="<?>", shape=diamond];
|
||||||
|
n421 -> n425 [label="T"];
|
||||||
|
n421 -> n432 [label="F"];
|
||||||
|
n425 [label="a", shape=box];
|
||||||
|
n425 -> n426;
|
||||||
|
n426 [label="b", shape=box];
|
||||||
|
n426 -> n427;
|
||||||
|
n427 [label="a - b", shape=box];
|
||||||
|
n427 -> n428;
|
||||||
|
n428 [label="b", shape=box];
|
||||||
|
n428 -> n429;
|
||||||
|
n429 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||||
|
n429 -> n407;
|
||||||
|
n429 -> n431;
|
||||||
|
n432 [label="b", shape=box];
|
||||||
|
n432 -> n433;
|
||||||
|
n433 [label="a", shape=box];
|
||||||
|
n433 -> n434;
|
||||||
|
n434 [label="b - a", shape=box];
|
||||||
|
n434 -> n435;
|
||||||
|
n435 [label="a", shape=box];
|
||||||
|
n435 -> n436;
|
||||||
|
n436 [label="CALL ggT", shape=box, style=filled, color=orange];
|
||||||
|
n436 -> n407;
|
||||||
|
n436 -> n438;
|
||||||
|
}
|
||||||
111
Project-02-03-04-05/cfgdots/homework.dot
Normal file
111
Project-02-03-04-05/cfgdots/homework.dot
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n445 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n445 -> n499;
|
||||||
|
n499 [label="1", shape=box];
|
||||||
|
n499 -> n500;
|
||||||
|
n500 [label="2", shape=box];
|
||||||
|
n500 -> n501;
|
||||||
|
n501 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n501 -> n447;
|
||||||
|
n501 -> n503;
|
||||||
|
n447 [label="START f(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n447 -> n452;
|
||||||
|
n452 [label="x", shape=box];
|
||||||
|
n452 -> n453;
|
||||||
|
n453 [label="0", shape=box];
|
||||||
|
n453 -> n454;
|
||||||
|
n454 [label="x == 0", shape=box];
|
||||||
|
n454 -> n455;
|
||||||
|
n455 [label="<?>", shape=diamond];
|
||||||
|
n455 -> n467 [label="T"];
|
||||||
|
n455 -> n475 [label="F"];
|
||||||
|
n467 [label="2", shape=box];
|
||||||
|
n467 -> n468;
|
||||||
|
n468 [label="y", shape=box];
|
||||||
|
n468 -> n469;
|
||||||
|
n469 [label="2 * y", shape=box];
|
||||||
|
n469 -> n470;
|
||||||
|
n470 [label="x", shape=box];
|
||||||
|
n470 -> n471;
|
||||||
|
n471 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n471 -> n459;
|
||||||
|
n471 -> n473;
|
||||||
|
n459 [label="START g(x, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n459 -> n462;
|
||||||
|
n459 -> n478;
|
||||||
|
n462 [label="x", shape=box];
|
||||||
|
n462 -> n463;
|
||||||
|
n463 [label="y", shape=box];
|
||||||
|
n463 -> n464;
|
||||||
|
n464 [label="x * y", shape=box];
|
||||||
|
n464 -> n465;
|
||||||
|
n465 [label="z", shape=box];
|
||||||
|
n465 -> n466;
|
||||||
|
n466 [label="(x * y) + z", shape=box];
|
||||||
|
n466 -> n460;
|
||||||
|
n460 [label="END g(x, z)", shape=ellipse, style=filled, color=green];
|
||||||
|
n460 -> n473;
|
||||||
|
n460 -> n509;
|
||||||
|
n473 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n473 -> n448;
|
||||||
|
n448 [label="END f(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n448 -> n488;
|
||||||
|
n448 -> n503;
|
||||||
|
n488 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n488 -> n489;
|
||||||
|
n489 [label="a * f(a,i)", shape=box];
|
||||||
|
n489 -> n490;
|
||||||
|
n490 [label="a = (a * f(a,i))", shape=box];
|
||||||
|
n490 -> n491;
|
||||||
|
n491 [label="i", shape=box];
|
||||||
|
n491 -> n492;
|
||||||
|
n492 [label="1", shape=box];
|
||||||
|
n492 -> n493;
|
||||||
|
n493 [label="i - 1", shape=box];
|
||||||
|
n493 -> n494;
|
||||||
|
n494 [label="i = (i - 1)", shape=box];
|
||||||
|
n494 -> n478;
|
||||||
|
n478 [label="i", shape=box];
|
||||||
|
n478 -> n479;
|
||||||
|
n479 [label="0", shape=box];
|
||||||
|
n479 -> n480;
|
||||||
|
n480 [label="i > 0", shape=box];
|
||||||
|
n480 -> n481;
|
||||||
|
n481 [label="<?>", shape=diamond];
|
||||||
|
n481 -> n483 [label="T"];
|
||||||
|
n481 -> n496 [label="F"];
|
||||||
|
n483 [label="a", shape=box];
|
||||||
|
n483 -> n484;
|
||||||
|
n484 [label="a", shape=box];
|
||||||
|
n484 -> n485;
|
||||||
|
n485 [label="i", shape=box];
|
||||||
|
n485 -> n486;
|
||||||
|
n486 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n486 -> n447;
|
||||||
|
n486 -> n488;
|
||||||
|
n496 [label="a", shape=box];
|
||||||
|
n496 -> n497;
|
||||||
|
n497 [label="42", shape=box];
|
||||||
|
n497 -> n498;
|
||||||
|
n498 [label="a + 42", shape=box];
|
||||||
|
n498 -> n460;
|
||||||
|
n503 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n503 -> n505;
|
||||||
|
n505 [label="3", shape=box];
|
||||||
|
n505 -> n506;
|
||||||
|
n506 [label="3", shape=box];
|
||||||
|
n506 -> n507;
|
||||||
|
n507 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n507 -> n459;
|
||||||
|
n507 -> n509;
|
||||||
|
n509 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n509 -> n446;
|
||||||
|
n446 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n475 [label="x", shape=box];
|
||||||
|
n475 -> n476;
|
||||||
|
n476 [label="1", shape=box];
|
||||||
|
n476 -> n477;
|
||||||
|
n477 [label="x + 1", shape=box];
|
||||||
|
n477 -> n448;
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n512 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n512 -> n518;
|
||||||
|
n518 [label="5", shape=box];
|
||||||
|
n518 -> n519;
|
||||||
|
n519 [label="CALL m", shape=box, style=filled, color=orange];
|
||||||
|
n519 -> n514;
|
||||||
|
n519 -> n521;
|
||||||
|
n514 [label="START m(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n514 -> n517;
|
||||||
|
n517 [label="a", shape=box];
|
||||||
|
n517 -> n515;
|
||||||
|
n515 [label="END m(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n515 -> n521;
|
||||||
|
n521 [label="RET m", shape=box, style=filled, color=orange];
|
||||||
|
n521 -> n529;
|
||||||
|
n529 [label="5", shape=box];
|
||||||
|
n529 -> n530;
|
||||||
|
n530 [label="CALL m", shape=box, style=filled, color=orange];
|
||||||
|
n530 -> n523;
|
||||||
|
n530 -> n532;
|
||||||
|
n523 [label="START m(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n523 -> n526;
|
||||||
|
n526 [label="b", shape=box];
|
||||||
|
n526 -> n527;
|
||||||
|
n527 [label="1", shape=box];
|
||||||
|
n527 -> n528;
|
||||||
|
n528 [label="b + 1", shape=box];
|
||||||
|
n528 -> n524;
|
||||||
|
n524 [label="END m(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n524 -> n532;
|
||||||
|
n532 [label="RET m", shape=box, style=filled, color=orange];
|
||||||
|
n532 -> n513;
|
||||||
|
n513 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
46
Project-02-03-04-05/cfgdots/multiple-let.dot
Normal file
46
Project-02-03-04-05/cfgdots/multiple-let.dot
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n534 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n534 -> n540;
|
||||||
|
n540 [label="5", shape=box];
|
||||||
|
n540 -> n541;
|
||||||
|
n541 [label="CALL n", shape=box, style=filled, color=orange];
|
||||||
|
n541 -> n536;
|
||||||
|
n541 -> n543;
|
||||||
|
n536 [label="START n(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n536 -> n539;
|
||||||
|
n539 [label="a", shape=box];
|
||||||
|
n539 -> n537;
|
||||||
|
n537 [label="END n(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n537 -> n543;
|
||||||
|
n537 -> n554;
|
||||||
|
n543 [label="RET n", shape=box, style=filled, color=orange];
|
||||||
|
n543 -> n551;
|
||||||
|
n551 [label="5", shape=box];
|
||||||
|
n551 -> n552;
|
||||||
|
n552 [label="CALL n", shape=box, style=filled, color=orange];
|
||||||
|
n552 -> n536;
|
||||||
|
n552 -> n554;
|
||||||
|
n554 [label="RET n", shape=box, style=filled, color=orange];
|
||||||
|
n554 -> n555;
|
||||||
|
n555 [label="5", shape=box];
|
||||||
|
n555 -> n556;
|
||||||
|
n556 [label="CALL m", shape=box, style=filled, color=orange];
|
||||||
|
n556 -> n545;
|
||||||
|
n556 -> n558;
|
||||||
|
n545 [label="START m(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n545 -> n548;
|
||||||
|
n548 [label="a", shape=box];
|
||||||
|
n548 -> n549;
|
||||||
|
n549 [label="1", shape=box];
|
||||||
|
n549 -> n550;
|
||||||
|
n550 [label="a + 1", shape=box];
|
||||||
|
n550 -> n546;
|
||||||
|
n546 [label="END m(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n546 -> n558;
|
||||||
|
n558 [label="RET m", shape=box, style=filled, color=orange];
|
||||||
|
n558 -> n559;
|
||||||
|
n559 [label="n(5) + m(5)", shape=box];
|
||||||
|
n559 -> n535;
|
||||||
|
n535 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/or.dot
Normal file
23
Project-02-03-04-05/cfgdots/or.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n561 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n561 -> n563;
|
||||||
|
n563 [label="True", shape=box];
|
||||||
|
n563 -> n564;
|
||||||
|
n564 [label="True", shape=box];
|
||||||
|
n564 -> n565;
|
||||||
|
n565 [label="True", shape=box];
|
||||||
|
n565 -> n566;
|
||||||
|
n566 [label="True == True", shape=box];
|
||||||
|
n566 -> n567;
|
||||||
|
n567 [label="True || (True == True)", shape=box];
|
||||||
|
n567 -> n568;
|
||||||
|
n568 [label="<?>", shape=diamond];
|
||||||
|
n568 -> n572 [label="T"];
|
||||||
|
n568 -> n573 [label="F"];
|
||||||
|
n572 [label="1", shape=box];
|
||||||
|
n572 -> n562;
|
||||||
|
n562 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n573 [label="0", shape=box];
|
||||||
|
n573 -> n562;
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/p1.dot
Normal file
23
Project-02-03-04-05/cfgdots/p1.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n574 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n574 -> n582;
|
||||||
|
n582 [label="5", shape=box];
|
||||||
|
n582 -> n583;
|
||||||
|
n583 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n583 -> n576;
|
||||||
|
n583 -> n585;
|
||||||
|
n576 [label="START g(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n576 -> n579;
|
||||||
|
n579 [label="a", shape=box];
|
||||||
|
n579 -> n580;
|
||||||
|
n580 [label="a", shape=box];
|
||||||
|
n580 -> n581;
|
||||||
|
n581 [label="a * a", shape=box];
|
||||||
|
n581 -> n577;
|
||||||
|
n577 [label="END g(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n577 -> n585;
|
||||||
|
n585 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n585 -> n575;
|
||||||
|
n575 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
40
Project-02-03-04-05/cfgdots/p2.dot
Normal file
40
Project-02-03-04-05/cfgdots/p2.dot
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n587 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n587 -> n606;
|
||||||
|
n606 [label="10", shape=box];
|
||||||
|
n606 -> n607;
|
||||||
|
n607 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n607 -> n589;
|
||||||
|
n607 -> n609;
|
||||||
|
n589 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n589 -> n592;
|
||||||
|
n592 [label="b", shape=box];
|
||||||
|
n592 -> n593;
|
||||||
|
n593 [label="0", shape=box];
|
||||||
|
n593 -> n594;
|
||||||
|
n594 [label="b == 0", shape=box];
|
||||||
|
n594 -> n595;
|
||||||
|
n595 [label="<?>", shape=diamond];
|
||||||
|
n595 -> n599 [label="T"];
|
||||||
|
n595 -> n600 [label="F"];
|
||||||
|
n599 [label="0", shape=box];
|
||||||
|
n599 -> n590;
|
||||||
|
n590 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n590 -> n605;
|
||||||
|
n590 -> n609;
|
||||||
|
n605 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n605 -> n590;
|
||||||
|
n609 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n609 -> n588;
|
||||||
|
n588 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n600 [label="b", shape=box];
|
||||||
|
n600 -> n601;
|
||||||
|
n601 [label="1", shape=box];
|
||||||
|
n601 -> n602;
|
||||||
|
n602 [label="b - 1", shape=box];
|
||||||
|
n602 -> n603;
|
||||||
|
n603 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n603 -> n589;
|
||||||
|
n603 -> n605;
|
||||||
|
}
|
||||||
127
Project-02-03-04-05/cfgdots/p3.dot
Normal file
127
Project-02-03-04-05/cfgdots/p3.dot
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n611 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n611 -> n662;
|
||||||
|
n662 [label="10", shape=box];
|
||||||
|
n662 -> n663;
|
||||||
|
n663 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n663 -> n613;
|
||||||
|
n663 -> n665;
|
||||||
|
n613 [label="START f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n613 -> n618;
|
||||||
|
n618 [label="b", shape=box];
|
||||||
|
n618 -> n619;
|
||||||
|
n619 [label="0", shape=box];
|
||||||
|
n619 -> n620;
|
||||||
|
n620 [label="b == 0", shape=box];
|
||||||
|
n620 -> n621;
|
||||||
|
n621 [label="<?>", shape=diamond];
|
||||||
|
n621 -> n625 [label="T"];
|
||||||
|
n621 -> n626 [label="F"];
|
||||||
|
n625 [label="0", shape=box];
|
||||||
|
n625 -> n614;
|
||||||
|
n614 [label="END f1(b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n614 -> n631;
|
||||||
|
n614 -> n642;
|
||||||
|
n614 -> n646;
|
||||||
|
n614 -> n665;
|
||||||
|
n631 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n631 -> n614;
|
||||||
|
n642 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n642 -> n655;
|
||||||
|
n655 [label="a", shape=box];
|
||||||
|
n655 -> n656;
|
||||||
|
n656 [label="b", shape=box];
|
||||||
|
n656 -> n657;
|
||||||
|
n657 [label="a * b", shape=box];
|
||||||
|
n657 -> n658;
|
||||||
|
n658 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n658 -> n647;
|
||||||
|
n658 -> n660;
|
||||||
|
n647 [label="START g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n647 -> n650;
|
||||||
|
n650 [label="a", shape=box];
|
||||||
|
n650 -> n651;
|
||||||
|
n651 [label="b", shape=box];
|
||||||
|
n651 -> n652;
|
||||||
|
n652 [label="a * b", shape=box];
|
||||||
|
n652 -> n653;
|
||||||
|
n653 [label="c", shape=box];
|
||||||
|
n653 -> n654;
|
||||||
|
n654 [label="(a * b) * c", shape=box];
|
||||||
|
n654 -> n648;
|
||||||
|
n648 [label="END g(c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n648 -> n660;
|
||||||
|
n660 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n660 -> n616;
|
||||||
|
n616 [label="END f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n616 -> n688;
|
||||||
|
n688 [label="RET f2", shape=box, style=filled, color=orange];
|
||||||
|
n688 -> n612;
|
||||||
|
n612 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n646 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n646 -> n655;
|
||||||
|
n665 [label="RET f1", shape=box, style=filled, color=orange];
|
||||||
|
n665 -> n667;
|
||||||
|
n667 [label="10", shape=box];
|
||||||
|
n667 -> n680;
|
||||||
|
n680 [label="20", shape=box];
|
||||||
|
n680 -> n681;
|
||||||
|
n681 [label="30", shape=box];
|
||||||
|
n681 -> n682;
|
||||||
|
n682 [label="CALL max", shape=box, style=filled, color=orange];
|
||||||
|
n682 -> n668;
|
||||||
|
n682 -> n684;
|
||||||
|
n668 [label="START max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n668 -> n671;
|
||||||
|
n671 [label="a", shape=box];
|
||||||
|
n671 -> n672;
|
||||||
|
n672 [label="b", shape=box];
|
||||||
|
n672 -> n673;
|
||||||
|
n673 [label="a > b", shape=box];
|
||||||
|
n673 -> n674;
|
||||||
|
n674 [label="<?>", shape=diamond];
|
||||||
|
n674 -> n678 [label="T"];
|
||||||
|
n674 -> n679 [label="F"];
|
||||||
|
n678 [label="a", shape=box];
|
||||||
|
n678 -> n669;
|
||||||
|
n669 [label="END max(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n669 -> n684;
|
||||||
|
n684 [label="RET max", shape=box, style=filled, color=orange];
|
||||||
|
n684 -> n686;
|
||||||
|
n686 [label="CALL f2", shape=box, style=filled, color=orange];
|
||||||
|
n686 -> n615;
|
||||||
|
n686 -> n688;
|
||||||
|
n615 [label="START f2(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n615 -> n632;
|
||||||
|
n632 [label="a", shape=box];
|
||||||
|
n632 -> n633;
|
||||||
|
n633 [label="b", shape=box];
|
||||||
|
n633 -> n634;
|
||||||
|
n634 [label="a > b", shape=box];
|
||||||
|
n634 -> n635;
|
||||||
|
n635 [label="<?>", shape=diamond];
|
||||||
|
n635 -> n639 [label="T"];
|
||||||
|
n635 -> n643 [label="F"];
|
||||||
|
n639 [label="a", shape=box];
|
||||||
|
n639 -> n640;
|
||||||
|
n640 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n640 -> n613;
|
||||||
|
n640 -> n642;
|
||||||
|
n643 [label="b", shape=box];
|
||||||
|
n643 -> n644;
|
||||||
|
n644 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n644 -> n613;
|
||||||
|
n644 -> n646;
|
||||||
|
n679 [label="b", shape=box];
|
||||||
|
n679 -> n669;
|
||||||
|
n626 [label="b", shape=box];
|
||||||
|
n626 -> n627;
|
||||||
|
n627 [label="1", shape=box];
|
||||||
|
n627 -> n628;
|
||||||
|
n628 [label="b - 1", shape=box];
|
||||||
|
n628 -> n629;
|
||||||
|
n629 [label="CALL f1", shape=box, style=filled, color=orange];
|
||||||
|
n629 -> n613;
|
||||||
|
n629 -> n631;
|
||||||
|
}
|
||||||
27
Project-02-03-04-05/cfgdots/p4.dot
Normal file
27
Project-02-03-04-05/cfgdots/p4.dot
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n689 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n689 -> n698;
|
||||||
|
n698 [label="10", shape=box];
|
||||||
|
n698 -> n699;
|
||||||
|
n699 [label="8", shape=box];
|
||||||
|
n699 -> n700;
|
||||||
|
n700 [label="CALL func", shape=box, style=filled, color=orange];
|
||||||
|
n700 -> n691;
|
||||||
|
n700 -> n702;
|
||||||
|
n691 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n691 -> n694;
|
||||||
|
n694 [label="b", shape=box];
|
||||||
|
n694 -> n695;
|
||||||
|
n695 [label="1", shape=box];
|
||||||
|
n695 -> n696;
|
||||||
|
n696 [label="b + 1", shape=box];
|
||||||
|
n696 -> n697;
|
||||||
|
n697 [label="a = (b + 1)", shape=box];
|
||||||
|
n697 -> n692;
|
||||||
|
n692 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n692 -> n702;
|
||||||
|
n702 [label="RET func", shape=box, style=filled, color=orange];
|
||||||
|
n702 -> n690;
|
||||||
|
n690 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
31
Project-02-03-04-05/cfgdots/p5.dot
Normal file
31
Project-02-03-04-05/cfgdots/p5.dot
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n704 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n704 -> n706;
|
||||||
|
n706 [label="10", shape=box];
|
||||||
|
n706 -> n707;
|
||||||
|
n707 [label="8", shape=box];
|
||||||
|
n707 -> n708;
|
||||||
|
n708 [label="CALL func", shape=box, style=filled, color=orange];
|
||||||
|
n708 -> n691;
|
||||||
|
n708 -> n710;
|
||||||
|
n691 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n691 -> n694;
|
||||||
|
n694 [label="b", shape=box];
|
||||||
|
n694 -> n695;
|
||||||
|
n695 [label="1", shape=box];
|
||||||
|
n695 -> n696;
|
||||||
|
n696 [label="b + 1", shape=box];
|
||||||
|
n696 -> n697;
|
||||||
|
n697 [label="a = (b + 1)", shape=box];
|
||||||
|
n697 -> n692;
|
||||||
|
n692 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n692 -> n702;
|
||||||
|
n692 -> n710;
|
||||||
|
n702 [label="RET func", shape=box, style=filled, color=orange];
|
||||||
|
n702 -> n690;
|
||||||
|
n690 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n710 [label="RET func", shape=box, style=filled, color=orange];
|
||||||
|
n710 -> n705;
|
||||||
|
n705 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
105
Project-02-03-04-05/cfgdots/p6.dot
Normal file
105
Project-02-03-04-05/cfgdots/p6.dot
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n711 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n711 -> n763;
|
||||||
|
n763 [label="2", shape=box];
|
||||||
|
n763 -> n764;
|
||||||
|
n764 [label="3", shape=box];
|
||||||
|
n764 -> n765;
|
||||||
|
n765 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n765 -> n713;
|
||||||
|
n765 -> n767;
|
||||||
|
n713 [label="START f(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n713 -> n718;
|
||||||
|
n718 [label="a", shape=box];
|
||||||
|
n718 -> n719;
|
||||||
|
n719 [label="0", shape=box];
|
||||||
|
n719 -> n720;
|
||||||
|
n720 [label="a == 0", shape=box];
|
||||||
|
n720 -> n721;
|
||||||
|
n721 [label="<?>", shape=diamond];
|
||||||
|
n721 -> n725 [label="T"];
|
||||||
|
n721 -> n736 [label="F"];
|
||||||
|
n725 [label="2", shape=box];
|
||||||
|
n725 -> n726;
|
||||||
|
n726 [label="b", shape=box];
|
||||||
|
n726 -> n727;
|
||||||
|
n727 [label="2 + b", shape=box];
|
||||||
|
n727 -> n714;
|
||||||
|
n714 [label="END f(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n714 -> n761;
|
||||||
|
n714 -> n767;
|
||||||
|
n761 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n761 -> n762;
|
||||||
|
n762 [label="c * f((c - 1),d)", shape=box];
|
||||||
|
n762 -> n729;
|
||||||
|
n729 [label="END g(a, c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n729 -> n741;
|
||||||
|
n729 -> n773;
|
||||||
|
n741 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n741 -> n742;
|
||||||
|
n742 [label="2 + g(a,b)", shape=box];
|
||||||
|
n742 -> n714;
|
||||||
|
n773 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n773 -> n712;
|
||||||
|
n712 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n767 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n767 -> n769;
|
||||||
|
n769 [label="3", shape=box];
|
||||||
|
n769 -> n770;
|
||||||
|
n770 [label="2", shape=box];
|
||||||
|
n770 -> n771;
|
||||||
|
n771 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n771 -> n728;
|
||||||
|
n771 -> n773;
|
||||||
|
n728 [label="START g(a, c)", shape=ellipse, style=filled, color=green];
|
||||||
|
n728 -> n731;
|
||||||
|
n728 -> n744;
|
||||||
|
n731 [label="a", shape=box];
|
||||||
|
n731 -> n732;
|
||||||
|
n732 [label="c", shape=box];
|
||||||
|
n732 -> n733;
|
||||||
|
n733 [label="a + c", shape=box];
|
||||||
|
n733 -> n734;
|
||||||
|
n734 [label="b", shape=box];
|
||||||
|
n734 -> n735;
|
||||||
|
n735 [label="(a + c) + b", shape=box];
|
||||||
|
n735 -> n729;
|
||||||
|
n744 [label="c", shape=box];
|
||||||
|
n744 -> n745;
|
||||||
|
n745 [label="0", shape=box];
|
||||||
|
n745 -> n746;
|
||||||
|
n746 [label="c == 0", shape=box];
|
||||||
|
n746 -> n747;
|
||||||
|
n747 [label="<?>", shape=diamond];
|
||||||
|
n747 -> n751 [label="T"];
|
||||||
|
n747 -> n754 [label="F"];
|
||||||
|
n751 [label="1", shape=box];
|
||||||
|
n751 -> n752;
|
||||||
|
n752 [label="d", shape=box];
|
||||||
|
n752 -> n753;
|
||||||
|
n753 [label="1 + d", shape=box];
|
||||||
|
n753 -> n729;
|
||||||
|
n754 [label="c", shape=box];
|
||||||
|
n754 -> n755;
|
||||||
|
n755 [label="c", shape=box];
|
||||||
|
n755 -> n756;
|
||||||
|
n756 [label="1", shape=box];
|
||||||
|
n756 -> n757;
|
||||||
|
n757 [label="c - 1", shape=box];
|
||||||
|
n757 -> n758;
|
||||||
|
n758 [label="d", shape=box];
|
||||||
|
n758 -> n759;
|
||||||
|
n759 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n759 -> n713;
|
||||||
|
n759 -> n761;
|
||||||
|
n736 [label="2", shape=box];
|
||||||
|
n736 -> n737;
|
||||||
|
n737 [label="a", shape=box];
|
||||||
|
n737 -> n738;
|
||||||
|
n738 [label="b", shape=box];
|
||||||
|
n738 -> n739;
|
||||||
|
n739 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n739 -> n728;
|
||||||
|
n739 -> n741;
|
||||||
|
}
|
||||||
42
Project-02-03-04-05/cfgdots/side_effect.dot
Normal file
42
Project-02-03-04-05/cfgdots/side_effect.dot
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n774 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n774 -> n793;
|
||||||
|
n793 [label="1", shape=box];
|
||||||
|
n793 -> n794;
|
||||||
|
n794 [label="2", shape=box];
|
||||||
|
n794 -> n795;
|
||||||
|
n795 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n795 -> n776;
|
||||||
|
n795 -> n797;
|
||||||
|
n776 [label="START f(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n776 -> n786;
|
||||||
|
n786 [label="5", shape=box];
|
||||||
|
n786 -> n787;
|
||||||
|
n787 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n787 -> n779;
|
||||||
|
n787 -> n789;
|
||||||
|
n779 [label="START g(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n779 -> n782;
|
||||||
|
n782 [label="x", shape=box];
|
||||||
|
n782 -> n783;
|
||||||
|
n783 [label="7", shape=box];
|
||||||
|
n783 -> n784;
|
||||||
|
n784 [label="x + 7", shape=box];
|
||||||
|
n784 -> n785;
|
||||||
|
n785 [label="y = (x + 7)", shape=box];
|
||||||
|
n785 -> n780;
|
||||||
|
n780 [label="END g(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n780 -> n789;
|
||||||
|
n789 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n789 -> n790;
|
||||||
|
n790 [label="x = g(5)", shape=box];
|
||||||
|
n790 -> n792;
|
||||||
|
n792 [label="y", shape=box];
|
||||||
|
n792 -> n777;
|
||||||
|
n777 [label="END f(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n777 -> n797;
|
||||||
|
n797 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n797 -> n775;
|
||||||
|
n775 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
61
Project-02-03-04-05/cfgdots/simpleSequence.dot
Normal file
61
Project-02-03-04-05/cfgdots/simpleSequence.dot
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n799 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n799 -> n830;
|
||||||
|
n830 [label="3", shape=box];
|
||||||
|
n830 -> n831;
|
||||||
|
n831 [label="CALL f", shape=box, style=filled, color=orange];
|
||||||
|
n831 -> n801;
|
||||||
|
n831 -> n833;
|
||||||
|
n801 [label="START f(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n801 -> n804;
|
||||||
|
n804 [label="2", shape=box];
|
||||||
|
n804 -> n805;
|
||||||
|
n805 [label="x", shape=box];
|
||||||
|
n805 -> n806;
|
||||||
|
n806 [label="2 * x", shape=box];
|
||||||
|
n806 -> n807;
|
||||||
|
n807 [label="x = (2 * x)", shape=box];
|
||||||
|
n807 -> n808;
|
||||||
|
n808 [label="x", shape=box];
|
||||||
|
n808 -> n809;
|
||||||
|
n809 [label="0", shape=box];
|
||||||
|
n809 -> n810;
|
||||||
|
n810 [label="x > 0", shape=box];
|
||||||
|
n810 -> n811;
|
||||||
|
n811 [label="<?>", shape=diamond];
|
||||||
|
n811 -> n815 [label="T"];
|
||||||
|
n811 -> n819 [label="F"];
|
||||||
|
n815 [label="x", shape=box];
|
||||||
|
n815 -> n816;
|
||||||
|
n816 [label="1", shape=box];
|
||||||
|
n816 -> n817;
|
||||||
|
n817 [label="x - 1", shape=box];
|
||||||
|
n817 -> n818;
|
||||||
|
n818 [label="x = (x - 1)", shape=box];
|
||||||
|
n818 -> n820;
|
||||||
|
n820 [label="x", shape=box];
|
||||||
|
n820 -> n821;
|
||||||
|
n821 [label="0", shape=box];
|
||||||
|
n821 -> n822;
|
||||||
|
n822 [label="x > 0", shape=box];
|
||||||
|
n822 -> n823;
|
||||||
|
n823 [label="<?>", shape=diamond];
|
||||||
|
n823 -> n802 [label="T"];
|
||||||
|
n823 -> n825 [label="F"];
|
||||||
|
n802 [label="END f(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n802 -> n833;
|
||||||
|
n833 [label="RET f", shape=box, style=filled, color=orange];
|
||||||
|
n833 -> n800;
|
||||||
|
n800 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n825 [label="x", shape=box];
|
||||||
|
n825 -> n826;
|
||||||
|
n826 [label="1", shape=box];
|
||||||
|
n826 -> n827;
|
||||||
|
n827 [label="x - 1", shape=box];
|
||||||
|
n827 -> n828;
|
||||||
|
n828 [label="x = (x - 1)", shape=box];
|
||||||
|
n828 -> n820;
|
||||||
|
n819 [label="x", shape=box];
|
||||||
|
n819 -> n820;
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/simple_dfa.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_dfa.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n835 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n835 -> n843;
|
||||||
|
n843 [label="2", shape=box];
|
||||||
|
n843 -> n844;
|
||||||
|
n844 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n844 -> n837;
|
||||||
|
n844 -> n846;
|
||||||
|
n837 [label="START g(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n837 -> n840;
|
||||||
|
n840 [label="3", shape=box];
|
||||||
|
n840 -> n841;
|
||||||
|
n841 [label="y = 3", shape=box];
|
||||||
|
n841 -> n842;
|
||||||
|
n842 [label="x", shape=box];
|
||||||
|
n842 -> n838;
|
||||||
|
n838 [label="END g(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n838 -> n846;
|
||||||
|
n846 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n846 -> n836;
|
||||||
|
n836 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
15
Project-02-03-04-05/cfgdots/simple_if.dot
Normal file
15
Project-02-03-04-05/cfgdots/simple_if.dot
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n848 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n848 -> n850;
|
||||||
|
n850 [label="True", shape=box];
|
||||||
|
n850 -> n851;
|
||||||
|
n851 [label="<?>", shape=diamond];
|
||||||
|
n851 -> n855 [label="T"];
|
||||||
|
n851 -> n856 [label="F"];
|
||||||
|
n855 [label="1", shape=box];
|
||||||
|
n855 -> n849;
|
||||||
|
n849 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n856 [label="0", shape=box];
|
||||||
|
n856 -> n849;
|
||||||
|
}
|
||||||
19
Project-02-03-04-05/cfgdots/simple_if_2.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_2.dot
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n857 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n857 -> n859;
|
||||||
|
n859 [label="True", shape=box];
|
||||||
|
n859 -> n860;
|
||||||
|
n860 [label="False", shape=box];
|
||||||
|
n860 -> n861;
|
||||||
|
n861 [label="True && False", shape=box];
|
||||||
|
n861 -> n862;
|
||||||
|
n862 [label="<?>", shape=diamond];
|
||||||
|
n862 -> n866 [label="T"];
|
||||||
|
n862 -> n867 [label="F"];
|
||||||
|
n866 [label="1", shape=box];
|
||||||
|
n866 -> n858;
|
||||||
|
n858 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n867 [label="0", shape=box];
|
||||||
|
n867 -> n858;
|
||||||
|
}
|
||||||
19
Project-02-03-04-05/cfgdots/simple_if_3.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_3.dot
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n868 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n868 -> n870;
|
||||||
|
n870 [label="True", shape=box];
|
||||||
|
n870 -> n871;
|
||||||
|
n871 [label="False", shape=box];
|
||||||
|
n871 -> n872;
|
||||||
|
n872 [label="True || False", shape=box];
|
||||||
|
n872 -> n873;
|
||||||
|
n873 [label="<?>", shape=diamond];
|
||||||
|
n873 -> n877 [label="T"];
|
||||||
|
n873 -> n878 [label="F"];
|
||||||
|
n877 [label="1", shape=box];
|
||||||
|
n877 -> n869;
|
||||||
|
n869 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n878 [label="0", shape=box];
|
||||||
|
n878 -> n869;
|
||||||
|
}
|
||||||
19
Project-02-03-04-05/cfgdots/simple_if_4.dot
Normal file
19
Project-02-03-04-05/cfgdots/simple_if_4.dot
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n879 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n879 -> n881;
|
||||||
|
n881 [label="1", shape=box];
|
||||||
|
n881 -> n882;
|
||||||
|
n882 [label="2", shape=box];
|
||||||
|
n882 -> n883;
|
||||||
|
n883 [label="1 > 2", shape=box];
|
||||||
|
n883 -> n884;
|
||||||
|
n884 [label="<?>", shape=diamond];
|
||||||
|
n884 -> n888 [label="T"];
|
||||||
|
n884 -> n889 [label="F"];
|
||||||
|
n888 [label="1", shape=box];
|
||||||
|
n888 -> n880;
|
||||||
|
n880 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n889 [label="0", shape=box];
|
||||||
|
n889 -> n880;
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/simple_if_5.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_if_5.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n890 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n890 -> n892;
|
||||||
|
n892 [label="2", shape=box];
|
||||||
|
n892 -> n893;
|
||||||
|
n893 [label="3", shape=box];
|
||||||
|
n893 -> n894;
|
||||||
|
n894 [label="5", shape=box];
|
||||||
|
n894 -> n895;
|
||||||
|
n895 [label="3 + 5", shape=box];
|
||||||
|
n895 -> n896;
|
||||||
|
n896 [label="2 > (3 + 5)", shape=box];
|
||||||
|
n896 -> n897;
|
||||||
|
n897 [label="<?>", shape=diamond];
|
||||||
|
n897 -> n901 [label="T"];
|
||||||
|
n897 -> n902 [label="F"];
|
||||||
|
n901 [label="1", shape=box];
|
||||||
|
n901 -> n891;
|
||||||
|
n891 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n902 [label="0", shape=box];
|
||||||
|
n902 -> n891;
|
||||||
|
}
|
||||||
27
Project-02-03-04-05/cfgdots/simple_if_6.dot
Normal file
27
Project-02-03-04-05/cfgdots/simple_if_6.dot
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n903 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n903 -> n905;
|
||||||
|
n905 [label="1", shape=box];
|
||||||
|
n905 -> n906;
|
||||||
|
n906 [label="2", shape=box];
|
||||||
|
n906 -> n907;
|
||||||
|
n907 [label="1 > 2", shape=box];
|
||||||
|
n907 -> n908;
|
||||||
|
n908 [label="3", shape=box];
|
||||||
|
n908 -> n909;
|
||||||
|
n909 [label="5", shape=box];
|
||||||
|
n909 -> n910;
|
||||||
|
n910 [label="3 < 5", shape=box];
|
||||||
|
n910 -> n911;
|
||||||
|
n911 [label="(1 > 2) || (3 < 5)", shape=box];
|
||||||
|
n911 -> n912;
|
||||||
|
n912 [label="<?>", shape=diamond];
|
||||||
|
n912 -> n916 [label="T"];
|
||||||
|
n912 -> n917 [label="F"];
|
||||||
|
n916 [label="1", shape=box];
|
||||||
|
n916 -> n904;
|
||||||
|
n904 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n917 [label="0", shape=box];
|
||||||
|
n917 -> n904;
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/simple_if_7.dot
Normal file
23
Project-02-03-04-05/cfgdots/simple_if_7.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n918 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n918 -> n920;
|
||||||
|
n920 [label="2", shape=box];
|
||||||
|
n920 -> n921;
|
||||||
|
n921 [label="0", shape=box];
|
||||||
|
n921 -> n922;
|
||||||
|
n922 [label="2 == 0", shape=box];
|
||||||
|
n922 -> n923;
|
||||||
|
n923 [label="False", shape=box];
|
||||||
|
n923 -> n924;
|
||||||
|
n924 [label="(2 == 0) == False", shape=box];
|
||||||
|
n924 -> n925;
|
||||||
|
n925 [label="<?>", shape=diamond];
|
||||||
|
n925 -> n929 [label="T"];
|
||||||
|
n925 -> n930 [label="F"];
|
||||||
|
n929 [label="1", shape=box];
|
||||||
|
n929 -> n919;
|
||||||
|
n919 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n930 [label="0", shape=box];
|
||||||
|
n930 -> n919;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
digraph CFG {
|
||||||
|
// Analysis: Reached Uses
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1 -> n9;
|
||||||
|
n9 [label="2", shape=box];
|
||||||
|
n9 -> n10;
|
||||||
|
n10 [label="CALL g", shape=box, style=filled, color=orange];
|
||||||
|
n10 -> n3;
|
||||||
|
n10 -> n12;
|
||||||
|
n3 [label="START g(x, y)\nRU: [8]", shape=ellipse, style=filled, color=green];
|
||||||
|
n3 -> n6;
|
||||||
|
n6 [label="3", shape=box];
|
||||||
|
n6 -> n7;
|
||||||
|
n7 [label="y = 3\nRU: []", shape=box];
|
||||||
|
n7 -> n8;
|
||||||
|
n8 [label="x", shape=box];
|
||||||
|
n8 -> n4;
|
||||||
|
n4 [label="END g(x, y)", shape=ellipse, style=filled, color=green];
|
||||||
|
n4 -> n12;
|
||||||
|
n12 [label="RET g", shape=box, style=filled, color=orange];
|
||||||
|
n12 -> n2;
|
||||||
|
n2 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
23
Project-02-03-04-05/cfgdots/square.dot
Normal file
23
Project-02-03-04-05/cfgdots/square.dot
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n931 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n931 -> n939;
|
||||||
|
n939 [label="10", shape=box];
|
||||||
|
n939 -> n940;
|
||||||
|
n940 [label="CALL square", shape=box, style=filled, color=orange];
|
||||||
|
n940 -> n933;
|
||||||
|
n940 -> n942;
|
||||||
|
n933 [label="START square(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n933 -> n936;
|
||||||
|
n936 [label="x", shape=box];
|
||||||
|
n936 -> n937;
|
||||||
|
n937 [label="x", shape=box];
|
||||||
|
n937 -> n938;
|
||||||
|
n938 [label="x * x", shape=box];
|
||||||
|
n938 -> n934;
|
||||||
|
n934 [label="END square(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n934 -> n942;
|
||||||
|
n942 [label="RET square", shape=box, style=filled, color=orange];
|
||||||
|
n942 -> n932;
|
||||||
|
n932 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
}
|
||||||
94
Project-02-03-04-05/cfgdots/validProgram.dot
Normal file
94
Project-02-03-04-05/cfgdots/validProgram.dot
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n944 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n944 -> n984;
|
||||||
|
n984 [label="2", shape=box];
|
||||||
|
n984 -> n985;
|
||||||
|
n985 [label="3", shape=box];
|
||||||
|
n985 -> n986;
|
||||||
|
n986 [label="CALL mult", shape=box, style=filled, color=orange];
|
||||||
|
n986 -> n946;
|
||||||
|
n986 -> n988;
|
||||||
|
n946 [label="START mult(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n946 -> n951;
|
||||||
|
n951 [label="a", shape=box];
|
||||||
|
n951 -> n952;
|
||||||
|
n952 [label="b", shape=box];
|
||||||
|
n952 -> n953;
|
||||||
|
n953 [label="a * b", shape=box];
|
||||||
|
n953 -> n947;
|
||||||
|
n947 [label="END mult(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n947 -> n978;
|
||||||
|
n947 -> n988;
|
||||||
|
n978 [label="RET mult", shape=box, style=filled, color=orange];
|
||||||
|
n978 -> n955;
|
||||||
|
n955 [label="END inc(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n955 -> n973;
|
||||||
|
n955 -> n982;
|
||||||
|
n973 [label="RET inc", shape=box, style=filled, color=orange];
|
||||||
|
n973 -> n955;
|
||||||
|
n982 [label="RET inc", shape=box, style=filled, color=orange];
|
||||||
|
n982 -> n949;
|
||||||
|
n949 [label="END add(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n949 -> n993;
|
||||||
|
n949 -> n996;
|
||||||
|
n993 [label="RET add", shape=box, style=filled, color=orange];
|
||||||
|
n993 -> n994;
|
||||||
|
n994 [label="CALL add", shape=box, style=filled, color=orange];
|
||||||
|
n994 -> n948;
|
||||||
|
n994 -> n996;
|
||||||
|
n948 [label="START add(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n948 -> n979;
|
||||||
|
n979 [label="a", shape=box];
|
||||||
|
n979 -> n980;
|
||||||
|
n980 [label="CALL inc", shape=box, style=filled, color=orange];
|
||||||
|
n980 -> n954;
|
||||||
|
n980 -> n982;
|
||||||
|
n954 [label="START inc(a)", shape=ellipse, style=filled, color=green];
|
||||||
|
n954 -> n957;
|
||||||
|
n957 [label="b", shape=box];
|
||||||
|
n957 -> n958;
|
||||||
|
n958 [label="0", shape=box];
|
||||||
|
n958 -> n959;
|
||||||
|
n959 [label="b != 0", shape=box];
|
||||||
|
n959 -> n960;
|
||||||
|
n960 [label="<?>", shape=diamond];
|
||||||
|
n960 -> n964 [label="T"];
|
||||||
|
n960 -> n974 [label="F"];
|
||||||
|
n964 [label="b", shape=box];
|
||||||
|
n964 -> n965;
|
||||||
|
n965 [label="1", shape=box];
|
||||||
|
n965 -> n966;
|
||||||
|
n966 [label="b - 1", shape=box];
|
||||||
|
n966 -> n967;
|
||||||
|
n967 [label="b = (b - 1)", shape=box];
|
||||||
|
n967 -> n968;
|
||||||
|
n968 [label="a", shape=box];
|
||||||
|
n968 -> n969;
|
||||||
|
n969 [label="1", shape=box];
|
||||||
|
n969 -> n970;
|
||||||
|
n970 [label="a + 1", shape=box];
|
||||||
|
n970 -> n971;
|
||||||
|
n971 [label="CALL inc", shape=box, style=filled, color=orange];
|
||||||
|
n971 -> n954;
|
||||||
|
n971 -> n973;
|
||||||
|
n974 [label="a", shape=box];
|
||||||
|
n974 -> n975;
|
||||||
|
n975 [label="1", shape=box];
|
||||||
|
n975 -> n976;
|
||||||
|
n976 [label="CALL mult", shape=box, style=filled, color=orange];
|
||||||
|
n976 -> n946;
|
||||||
|
n976 -> n978;
|
||||||
|
n996 [label="RET add", shape=box, style=filled, color=orange];
|
||||||
|
n996 -> n945;
|
||||||
|
n945 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n988 [label="RET mult", shape=box, style=filled, color=orange];
|
||||||
|
n988 -> n989;
|
||||||
|
n989 [label="4", shape=box];
|
||||||
|
n989 -> n990;
|
||||||
|
n990 [label="5", shape=box];
|
||||||
|
n990 -> n991;
|
||||||
|
n991 [label="CALL add", shape=box, style=filled, color=orange];
|
||||||
|
n991 -> n948;
|
||||||
|
n991 -> n993;
|
||||||
|
}
|
||||||
52
Project-02-03-04-05/cfgdots/while.dot
Normal file
52
Project-02-03-04-05/cfgdots/while.dot
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n998 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n998 -> n1021;
|
||||||
|
n1021 [label="10", shape=box];
|
||||||
|
n1021 -> n1022;
|
||||||
|
n1022 [label="8", shape=box];
|
||||||
|
n1022 -> n1023;
|
||||||
|
n1023 [label="CALL func", shape=box, style=filled, color=orange];
|
||||||
|
n1023 -> n1000;
|
||||||
|
n1023 -> n1025;
|
||||||
|
n1000 [label="START func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1000 -> n1003;
|
||||||
|
n1003 [label="a", shape=box];
|
||||||
|
n1003 -> n1004;
|
||||||
|
n1004 [label="0", shape=box];
|
||||||
|
n1004 -> n1005;
|
||||||
|
n1005 [label="a > 0", shape=box];
|
||||||
|
n1005 -> n1006;
|
||||||
|
n1006 [label="b", shape=box];
|
||||||
|
n1006 -> n1007;
|
||||||
|
n1007 [label="a", shape=box];
|
||||||
|
n1007 -> n1008;
|
||||||
|
n1008 [label="b != a", shape=box];
|
||||||
|
n1008 -> n1009;
|
||||||
|
n1009 [label="(a > 0) && (b != a)", shape=box];
|
||||||
|
n1009 -> n1010;
|
||||||
|
n1010 [label="<?>", shape=diamond];
|
||||||
|
n1010 -> n1001 [label="T"];
|
||||||
|
n1010 -> n1012 [label="F"];
|
||||||
|
n1001 [label="END func(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1001 -> n1025;
|
||||||
|
n1025 [label="RET func", shape=box, style=filled, color=orange];
|
||||||
|
n1025 -> n999;
|
||||||
|
n999 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1012 [label="b", shape=box];
|
||||||
|
n1012 -> n1013;
|
||||||
|
n1013 [label="1", shape=box];
|
||||||
|
n1013 -> n1014;
|
||||||
|
n1014 [label="b + 1", shape=box];
|
||||||
|
n1014 -> n1015;
|
||||||
|
n1015 [label="b = (b + 1)", shape=box];
|
||||||
|
n1015 -> n1016;
|
||||||
|
n1016 [label="a", shape=box];
|
||||||
|
n1016 -> n1017;
|
||||||
|
n1017 [label="1", shape=box];
|
||||||
|
n1017 -> n1018;
|
||||||
|
n1018 [label="a - 1", shape=box];
|
||||||
|
n1018 -> n1019;
|
||||||
|
n1019 [label="a = (a - 1)", shape=box];
|
||||||
|
n1019 -> n1005;
|
||||||
|
}
|
||||||
13
Project-02-03-04-05/cfgdots/while_2.dot
Normal file
13
Project-02-03-04-05/cfgdots/while_2.dot
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1027 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1027 -> n1029;
|
||||||
|
n1029 [label="True", shape=box];
|
||||||
|
n1029 -> n1030;
|
||||||
|
n1030 [label="<?>", shape=diamond];
|
||||||
|
n1030 -> n1028 [label="T"];
|
||||||
|
n1030 -> n1032 [label="F"];
|
||||||
|
n1028 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1032 [label="3", shape=box];
|
||||||
|
n1032 -> n1027;
|
||||||
|
}
|
||||||
78
Project-02-03-04-05/cfgdots/wrapped-ggT.dot
Normal file
78
Project-02-03-04-05/cfgdots/wrapped-ggT.dot
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1034 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1034 -> n1076;
|
||||||
|
n1076 [label="21", shape=box];
|
||||||
|
n1076 -> n1077;
|
||||||
|
n1077 [label="49", shape=box];
|
||||||
|
n1077 -> n1078;
|
||||||
|
n1078 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1078 -> n1036;
|
||||||
|
n1078 -> n1080;
|
||||||
|
n1036 [label="START wrapper(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1036 -> n1071;
|
||||||
|
n1071 [label="0", shape=box];
|
||||||
|
n1071 -> n1072;
|
||||||
|
n1072 [label="CALL ggt", shape=box, style=filled, color=orange];
|
||||||
|
n1072 -> n1039;
|
||||||
|
n1072 -> n1074;
|
||||||
|
n1039 [label="START ggt(noneSense)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1039 -> n1042;
|
||||||
|
n1042 [label="a", shape=box];
|
||||||
|
n1042 -> n1043;
|
||||||
|
n1043 [label="b", shape=box];
|
||||||
|
n1043 -> n1044;
|
||||||
|
n1044 [label="a == b", shape=box];
|
||||||
|
n1044 -> n1045;
|
||||||
|
n1045 [label="<?>", shape=diamond];
|
||||||
|
n1045 -> n1049 [label="T"];
|
||||||
|
n1045 -> n1050 [label="F"];
|
||||||
|
n1049 [label="a", shape=box];
|
||||||
|
n1049 -> n1040;
|
||||||
|
n1040 [label="END ggt(noneSense)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1040 -> n1074;
|
||||||
|
n1074 [label="RET ggt", shape=box, style=filled, color=orange];
|
||||||
|
n1074 -> n1037;
|
||||||
|
n1037 [label="END wrapper(a, b)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1037 -> n1063;
|
||||||
|
n1037 -> n1070;
|
||||||
|
n1037 -> n1080;
|
||||||
|
n1063 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1063 -> n1040;
|
||||||
|
n1070 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1070 -> n1040;
|
||||||
|
n1080 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1080 -> n1035;
|
||||||
|
n1035 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1050 [label="a", shape=box];
|
||||||
|
n1050 -> n1051;
|
||||||
|
n1051 [label="b", shape=box];
|
||||||
|
n1051 -> n1052;
|
||||||
|
n1052 [label="a > b", shape=box];
|
||||||
|
n1052 -> n1053;
|
||||||
|
n1053 [label="<?>", shape=diamond];
|
||||||
|
n1053 -> n1057 [label="T"];
|
||||||
|
n1053 -> n1064 [label="F"];
|
||||||
|
n1057 [label="a", shape=box];
|
||||||
|
n1057 -> n1058;
|
||||||
|
n1058 [label="b", shape=box];
|
||||||
|
n1058 -> n1059;
|
||||||
|
n1059 [label="a - b", shape=box];
|
||||||
|
n1059 -> n1060;
|
||||||
|
n1060 [label="b", shape=box];
|
||||||
|
n1060 -> n1061;
|
||||||
|
n1061 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1061 -> n1036;
|
||||||
|
n1061 -> n1063;
|
||||||
|
n1064 [label="b", shape=box];
|
||||||
|
n1064 -> n1065;
|
||||||
|
n1065 [label="a", shape=box];
|
||||||
|
n1065 -> n1066;
|
||||||
|
n1066 [label="b - a", shape=box];
|
||||||
|
n1066 -> n1067;
|
||||||
|
n1067 [label="a", shape=box];
|
||||||
|
n1067 -> n1068;
|
||||||
|
n1068 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1068 -> n1036;
|
||||||
|
n1068 -> n1070;
|
||||||
|
}
|
||||||
51
Project-02-03-04-05/cfgdots/wrapper.dot
Normal file
51
Project-02-03-04-05/cfgdots/wrapper.dot
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
digraph CFG {
|
||||||
|
node [fontname="Helvetica"];
|
||||||
|
n1082 [label="START", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1082 -> n1108;
|
||||||
|
n1108 [label="4", shape=box];
|
||||||
|
n1108 -> n1109;
|
||||||
|
n1109 [label="10", shape=box];
|
||||||
|
n1109 -> n1110;
|
||||||
|
n1110 [label="CALL wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1110 -> n1084;
|
||||||
|
n1110 -> n1112;
|
||||||
|
n1084 [label="START wrapper(number, threshold)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1084 -> n1103;
|
||||||
|
n1103 [label="number", shape=box];
|
||||||
|
n1103 -> n1104;
|
||||||
|
n1104 [label="CALL square", shape=box, style=filled, color=orange];
|
||||||
|
n1104 -> n1087;
|
||||||
|
n1104 -> n1106;
|
||||||
|
n1087 [label="START square(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1087 -> n1090;
|
||||||
|
n1090 [label="x", shape=box];
|
||||||
|
n1090 -> n1091;
|
||||||
|
n1091 [label="x", shape=box];
|
||||||
|
n1091 -> n1092;
|
||||||
|
n1092 [label="x * x", shape=box];
|
||||||
|
n1092 -> n1093;
|
||||||
|
n1093 [label="threshold", shape=box];
|
||||||
|
n1093 -> n1094;
|
||||||
|
n1094 [label="(x * x) > threshold", shape=box];
|
||||||
|
n1094 -> n1095;
|
||||||
|
n1095 [label="<?>", shape=diamond];
|
||||||
|
n1095 -> n1099 [label="T"];
|
||||||
|
n1095 -> n1100 [label="F"];
|
||||||
|
n1099 [label="x", shape=box];
|
||||||
|
n1099 -> n1088;
|
||||||
|
n1088 [label="END square(x)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1088 -> n1106;
|
||||||
|
n1106 [label="RET square", shape=box, style=filled, color=orange];
|
||||||
|
n1106 -> n1085;
|
||||||
|
n1085 [label="END wrapper(number, threshold)", shape=ellipse, style=filled, color=green];
|
||||||
|
n1085 -> n1112;
|
||||||
|
n1112 [label="RET wrapper", shape=box, style=filled, color=orange];
|
||||||
|
n1112 -> n1083;
|
||||||
|
n1083 [label="END", shape=ellipse, style=filled, color=gray];
|
||||||
|
n1100 [label="x", shape=box];
|
||||||
|
n1100 -> n1101;
|
||||||
|
n1101 [label="x", shape=box];
|
||||||
|
n1101 -> n1102;
|
||||||
|
n1102 [label="x * x", shape=box];
|
||||||
|
n1102 -> n1088;
|
||||||
|
}
|
||||||
BIN
Project-02-03-04-05/images/getOptimized/after.png
Normal file
BIN
Project-02-03-04-05/images/getOptimized/after.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 113 KiB |
BIN
Project-02-03-04-05/images/getOptimized/before.png
Normal file
BIN
Project-02-03-04-05/images/getOptimized/before.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 123 KiB |
@@ -1,23 +1,24 @@
|
|||||||
import triplayacc as yacc
|
|
||||||
import cfg_build
|
|
||||||
import syntax
|
|
||||||
|
|
||||||
from pathlib import Path
|
|
||||||
from graphviz import Source
|
|
||||||
from vistram.tram import *
|
|
||||||
|
|
||||||
import tkinter as tk
|
|
||||||
from vistram.vistram import MachineUI
|
|
||||||
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
import matplotlib.image as mpimg
|
|
||||||
import lib.console as cnsl
|
|
||||||
import os
|
import os
|
||||||
|
import tkinter as tk
|
||||||
from cfg.CFG import CFG
|
from pathlib import Path
|
||||||
from cfg.CFG_Node import (CFG_START, CFG_END)
|
|
||||||
|
|
||||||
import matplotlib
|
import matplotlib
|
||||||
|
import matplotlib.image as mpimg
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from graphviz import Source
|
||||||
|
|
||||||
|
import cfg_build
|
||||||
|
import lib.console as cnsl
|
||||||
|
import syntax
|
||||||
|
import triplayacc as yacc
|
||||||
|
from cfa.LiveVariables import LiveVariables
|
||||||
|
from cfa.ReachedUses import ReachedUses
|
||||||
|
from cfa.to_dot import analysis_to_dot
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
from vistram.tram import *
|
||||||
|
from vistram.vistram import MachineUI
|
||||||
|
from optimizations.optimize import optimize
|
||||||
|
|
||||||
matplotlib.use("TkAgg")
|
matplotlib.use("TkAgg")
|
||||||
|
|
||||||
# Assembles the AST into TRAM code
|
# Assembles the AST into TRAM code
|
||||||
@@ -26,15 +27,7 @@ def assemble(ast):
|
|||||||
return code + [halt()]
|
return code + [halt()]
|
||||||
|
|
||||||
def make_cfg(ast):
|
def make_cfg(ast):
|
||||||
start = CFG_START()
|
return CFG(ast)
|
||||||
end = CFG_END()
|
|
||||||
|
|
||||||
last = ast.cfa(start, end)
|
|
||||||
if last is not None:
|
|
||||||
last.add_child(end)
|
|
||||||
|
|
||||||
return CFG(start, end)
|
|
||||||
|
|
||||||
|
|
||||||
# Renders a diagram of the AST
|
# Renders a diagram of the AST
|
||||||
def render_diagram(dot_string: str):
|
def render_diagram(dot_string: str):
|
||||||
@@ -74,14 +67,53 @@ def pretty_print(node, indent=0):
|
|||||||
else:
|
else:
|
||||||
print(f"{prefix} {key}: {value}")
|
print(f"{prefix} {key}: {value}")
|
||||||
|
|
||||||
|
# Print compact Live Variables and Reached Uses reports to console.
|
||||||
|
def print_analysis_reports(cfg, analyses: dict):
|
||||||
|
lv = analyses["lv"]
|
||||||
|
ru = analyses["ru"]
|
||||||
|
ru_edges = ru.reached_uses_by_node()
|
||||||
|
node_by_id = {n.id: n for n in cfg.nodes()}
|
||||||
|
|
||||||
|
def node_text(nid: int) -> str:
|
||||||
|
node = node_by_id.get(nid)
|
||||||
|
if node is None:
|
||||||
|
return "<unknown>"
|
||||||
|
lbl = node.dot_label()
|
||||||
|
return str(lbl) if lbl is not None else "<no-label>"
|
||||||
|
|
||||||
|
print("\nLive Variables Report")
|
||||||
|
print("---------------------")
|
||||||
|
node_ids = sorted(set(lv.incoming.keys()) | set(lv.outgoing.keys()))
|
||||||
|
for nid in node_ids:
|
||||||
|
in_set = sorted(lv.incoming.get(nid, set()))
|
||||||
|
out_set = sorted(lv.outgoing.get(nid, set()))
|
||||||
|
if not in_set and not out_set:
|
||||||
|
continue
|
||||||
|
print(f"n{nid} [{node_text(nid)}]: In={in_set} Out={out_set}")
|
||||||
|
|
||||||
|
print("\nReached Uses Report")
|
||||||
|
print("-------------------")
|
||||||
|
has_ru = False
|
||||||
|
for def_id in sorted(ru_edges):
|
||||||
|
uses = sorted(set(ru_edges[def_id]))
|
||||||
|
if not uses:
|
||||||
|
continue
|
||||||
|
has_ru = True
|
||||||
|
use_desc = [f"n{uid} [{node_text(uid)}]" for uid in uses]
|
||||||
|
print(f"n{def_id} [{node_text(def_id)}] -> {use_desc}")
|
||||||
|
if not has_ru:
|
||||||
|
print("(no reached uses)")
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("\nTRIPLA Parser and TRIPLA to TRAM Compiler")
|
print("\nTRIPLA Parser and TRIPLA to TRAM Compiler")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
mode = cnsl.prompt_choice("\nSelect action:", ["Parse .tripla", "Compile .tripla", "CFG for .tripla", "Exit"])
|
mode = cnsl.prompt_choice(
|
||||||
|
"\nSelect action:",
|
||||||
|
["Parse .tripla", "Compile .tripla", "CFG for .tripla", "Analyze .tripla", "Exit"],
|
||||||
|
)
|
||||||
|
|
||||||
if mode == 3:
|
if mode == 4:
|
||||||
print("\nBye Bye.")
|
print("\nBye Bye.")
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -98,6 +130,9 @@ if __name__ == "__main__":
|
|||||||
ast = yacc.parser.parse(source)
|
ast = yacc.parser.parse(source)
|
||||||
|
|
||||||
if mode == 0:
|
if mode == 0:
|
||||||
|
if cnsl.prompt_confirmation("\nOptimize AST?", default="y"):
|
||||||
|
ast = optimize(ast)
|
||||||
|
|
||||||
# Pretty print
|
# Pretty print
|
||||||
if cnsl.prompt_confirmation("\nPretty-print AST?"):
|
if cnsl.prompt_confirmation("\nPretty-print AST?"):
|
||||||
print("")
|
print("")
|
||||||
@@ -125,6 +160,9 @@ if __name__ == "__main__":
|
|||||||
print("Rendered AST diagram.")
|
print("Rendered AST diagram.")
|
||||||
|
|
||||||
elif mode == 1:
|
elif mode == 1:
|
||||||
|
if cnsl.prompt_confirmation("\nOptimize AST?", default="y"):
|
||||||
|
ast = optimize(ast)
|
||||||
|
|
||||||
tram_code = assemble(ast)
|
tram_code = assemble(ast)
|
||||||
|
|
||||||
# Print TRAM code
|
# Print TRAM code
|
||||||
@@ -168,7 +206,8 @@ if __name__ == "__main__":
|
|||||||
if not filename:
|
if not filename:
|
||||||
filename = default
|
filename = default
|
||||||
|
|
||||||
out_path = Path(__file__).parent / filename
|
out_path = Path(__file__).parent / 'cfgdots' / filename
|
||||||
|
out_path.parent.mkdir(exist_ok=True)
|
||||||
with open(out_path, "w") as f:
|
with open(out_path, "w") as f:
|
||||||
f.write(dot_str)
|
f.write(dot_str)
|
||||||
|
|
||||||
@@ -178,6 +217,43 @@ if __name__ == "__main__":
|
|||||||
render_diagram(dot_str)
|
render_diagram(dot_str)
|
||||||
print("Rendered CFG diagram.")
|
print("Rendered CFG diagram.")
|
||||||
|
|
||||||
|
elif mode == 3:
|
||||||
|
# Reset the global CFG builder state so each analysis run is clean
|
||||||
|
cfg_build.FUNCTIONS.clear()
|
||||||
|
cfg_build.CURRENT_FUNCTION = None
|
||||||
|
|
||||||
|
cfg = make_cfg(ast)
|
||||||
|
analysis_name = "Live Variables + Reached Uses analyses"
|
||||||
|
print(f"\nRunning {analysis_name} …")
|
||||||
|
try:
|
||||||
|
lv = LiveVariables(cfg)
|
||||||
|
ru = ReachedUses(cfg)
|
||||||
|
analyses = {"lv": lv, "ru": ru}
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"Analysis failed: {exc}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if cnsl.prompt_confirmation("\nPrint analysis reports to console?"):
|
||||||
|
print_analysis_reports(cfg, analyses)
|
||||||
|
|
||||||
|
dot_str = analysis_to_dot(cfg, analyses, analysis_name)
|
||||||
|
|
||||||
|
if cnsl.prompt_confirmation("\nExport annotated CFG as .dot file?"):
|
||||||
|
default = f"{path.stem}_analysis.dot"
|
||||||
|
filename = input(f"Filename [{default}]: ").strip()
|
||||||
|
if not filename:
|
||||||
|
filename = default
|
||||||
|
|
||||||
|
out_dir = Path(__file__).parent / "cfadots"
|
||||||
|
out_dir.mkdir(exist_ok=True)
|
||||||
|
out_path = out_dir / filename
|
||||||
|
try:
|
||||||
|
with open(out_path, "w") as f:
|
||||||
|
f.write(dot_str)
|
||||||
|
print(f"Saved annotated DOT file as: {out_path}")
|
||||||
|
except Exception as exc:
|
||||||
|
print(f"Could not save DOT file: {exc}")
|
||||||
|
|
||||||
|
if cnsl.prompt_confirmation("Display annotated CFG diagram?"):
|
||||||
|
render_diagram(dot_str)
|
||||||
|
print("Rendered annotated CFG diagram.")
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import cfg_build
|
||||||
|
from cfg.CFG import CFG
|
||||||
|
from cfg.CFG_Node import CFG_Node
|
||||||
|
from cfa.ReachedUses import ReachedUses
|
||||||
|
from syntax import EXPRESSION, ASSIGN
|
||||||
|
from optimizations.Optimization import Optimization
|
||||||
|
|
||||||
|
class DeadAssignmentElimination(Optimization):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._node_by_ast_id: dict[int, CFG_Node] = {}
|
||||||
|
self.__ru: ReachedUses | None = None
|
||||||
|
|
||||||
|
def setup(self, ast: EXPRESSION) -> None:
|
||||||
|
cfg_build.FUNCTIONS.clear()
|
||||||
|
cfg_build.CURRENT_FUNCTION = None
|
||||||
|
cfg = CFG(ast)
|
||||||
|
self.__ru = ReachedUses(cfg)
|
||||||
|
self._node_by_ast_id = {id(n.ast_node): n for n in self.__ru.cfg.nodes() if n.ast_node is not None}
|
||||||
|
|
||||||
|
def apply(self, node: EXPRESSION) -> EXPRESSION:
|
||||||
|
# Only ASSIGN nodes can be dead assignments.
|
||||||
|
if not isinstance(node, ASSIGN):
|
||||||
|
return node
|
||||||
|
|
||||||
|
# Find the CFG node corresponding to this AST node.
|
||||||
|
# If none is found, the node was not analyzed — leave it unchanged.
|
||||||
|
cfg_node = self._node_by_ast_id.get(id(node))
|
||||||
|
if cfg_node is None:
|
||||||
|
return node
|
||||||
|
|
||||||
|
ru = self.__ru
|
||||||
|
nid = cfg_node.id
|
||||||
|
defined_vars = ru.defs.get(nid, set())
|
||||||
|
out = ru.out_sets.get(nid, set())
|
||||||
|
|
||||||
|
# Check if any use-fact in OUT(n) belongs to a variable defined at n.
|
||||||
|
# If so, the assignment is live — at least one use is reachable from here.
|
||||||
|
for (_, var) in out:
|
||||||
|
if var in defined_vars:
|
||||||
|
return node
|
||||||
|
|
||||||
|
# No reached use found for the assigned variable — the assignment is dead.
|
||||||
|
# Replace ASSIGN(var, expr) with expr to preserve side effects on the RHS.
|
||||||
|
return node.expr
|
||||||
7
Project-02-03-04-05/optimizations/Optimization.py
Normal file
7
Project-02-03-04-05/optimizations/Optimization.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from syntax import EXPRESSION
|
||||||
|
|
||||||
|
|
||||||
|
class Optimization:
|
||||||
|
def setup(self, ast: EXPRESSION) -> None: ...
|
||||||
|
def apply(self, node: EXPRESSION) -> EXPRESSION: ...
|
||||||
2
Project-02-03-04-05/optimizations/__init__.py
Normal file
2
Project-02-03-04-05/optimizations/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from optimizations.DeadAssignmentElimination import DeadAssignmentElimination
|
||||||
|
from optimizations.Optimization import Optimization
|
||||||
36
Project-02-03-04-05/optimizations/optimize.py
Normal file
36
Project-02-03-04-05/optimizations/optimize.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
from optimizations.Optimization import Optimization
|
||||||
|
from optimizations.DeadAssignmentElimination import DeadAssignmentElimination
|
||||||
|
from syntax import EXPRESSION
|
||||||
|
|
||||||
|
# Traverses the AST and applies the given optimizations
|
||||||
|
def __apply_optimizations(node: EXPRESSION, optimizations: list[Optimization]) -> EXPRESSION:
|
||||||
|
for key, value in list(node.__dict__.items()):
|
||||||
|
if key == "pp":
|
||||||
|
continue
|
||||||
|
if isinstance(value, EXPRESSION):
|
||||||
|
new_child = __apply_optimizations(value, optimizations)
|
||||||
|
if new_child is not value:
|
||||||
|
setattr(node, key, new_child)
|
||||||
|
elif isinstance(value, list):
|
||||||
|
for i, elem in enumerate(value):
|
||||||
|
if isinstance(elem, EXPRESSION):
|
||||||
|
new_elem = __apply_optimizations(elem, optimizations)
|
||||||
|
if new_elem is not elem:
|
||||||
|
value[i] = new_elem
|
||||||
|
|
||||||
|
result: EXPRESSION = node
|
||||||
|
for opt in optimizations:
|
||||||
|
result = opt.apply(result)
|
||||||
|
return result
|
||||||
|
|
||||||
|
# Stores the active optimizations
|
||||||
|
ACTIVE_OPTIMIZATIONS: list[Optimization] = [
|
||||||
|
DeadAssignmentElimination(),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Apply optimizations to the given AST node
|
||||||
|
def optimize(ast: EXPRESSION) -> EXPRESSION:
|
||||||
|
for opt in ACTIVE_OPTIMIZATIONS:
|
||||||
|
opt.setup(ast)
|
||||||
|
return __apply_optimizations(ast, ACTIVE_OPTIMIZATIONS)
|
||||||
42
Project-02-03-04-05/tramcodes/example.tram
Normal file
42
Project-02-03-04-05/tramcodes/example.tram
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
GOTO L1
|
||||||
|
L2: NOP
|
||||||
|
CONST 2
|
||||||
|
STORE 1 0
|
||||||
|
LOAD 1 0
|
||||||
|
POP
|
||||||
|
CONST 3
|
||||||
|
STORE 2 0
|
||||||
|
LOAD 2 0
|
||||||
|
POP
|
||||||
|
GOTO L3
|
||||||
|
L4: NOP
|
||||||
|
CONST 7
|
||||||
|
STORE 0 0
|
||||||
|
LOAD 0 0
|
||||||
|
POP
|
||||||
|
LOAD 1 1
|
||||||
|
CONST 0
|
||||||
|
GT
|
||||||
|
IFZERO L5
|
||||||
|
LOAD 1 1
|
||||||
|
INVOKE 1 L4 1
|
||||||
|
GOTO L6
|
||||||
|
L5: NOP
|
||||||
|
CONST 8
|
||||||
|
STORE 0 0
|
||||||
|
LOAD 0 0
|
||||||
|
L6: NOP
|
||||||
|
POP
|
||||||
|
LOAD 0 0
|
||||||
|
RETURN
|
||||||
|
L3: NOP
|
||||||
|
LOAD 0 0
|
||||||
|
INVOKE 1 L4 0
|
||||||
|
LOAD 0 0
|
||||||
|
ADD
|
||||||
|
RETURN
|
||||||
|
L1: NOP
|
||||||
|
CONST 2
|
||||||
|
CONST 3
|
||||||
|
INVOKE 2 L2 0
|
||||||
|
HALT
|
||||||
12
Project-02-03-04-05/triplaprograms/dataflow.tripla
Normal file
12
Project-02-03-04-05/triplaprograms/dataflow.tripla
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
s = 33;
|
||||||
|
i = 0;
|
||||||
|
j = 0;
|
||||||
|
t = i + j;
|
||||||
|
f = 6;
|
||||||
|
while (s < 42) do {
|
||||||
|
a = s - 1;
|
||||||
|
c = (i + j) * (f + 1);
|
||||||
|
if (c > 0) then j = j / c else i = j * c;
|
||||||
|
i = (j * 2) / f;
|
||||||
|
s = s + 1
|
||||||
|
}
|
||||||
11
Project-02-03-04-05/triplaprograms/example.tripla
Normal file
11
Project-02-03-04-05/triplaprograms/example.tripla
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
let f(x,y,z) {
|
||||||
|
y=2;
|
||||||
|
z=3;
|
||||||
|
let g(x) {
|
||||||
|
x=7;
|
||||||
|
if (y>0)
|
||||||
|
then g(y)
|
||||||
|
else x=8;
|
||||||
|
x
|
||||||
|
} in g(x)+x
|
||||||
|
} in f(2,3)
|
||||||
9
Project-02-03-04-05/triplaprograms/getOptimized.tripla
Normal file
9
Project-02-03-04-05/triplaprograms/getOptimized.tripla
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
let f(x, y)
|
||||||
|
{
|
||||||
|
let g(x)
|
||||||
|
{
|
||||||
|
y = x + 7
|
||||||
|
}
|
||||||
|
in x = g(5); y
|
||||||
|
}
|
||||||
|
in f(1, 2)
|
||||||
@@ -5,4 +5,4 @@ let ggT(a, b) {
|
|||||||
ggT(a-b, b)
|
ggT(a-b, b)
|
||||||
else
|
else
|
||||||
ggT(b-a, a)
|
ggT(b-a, a)
|
||||||
} in ggT(3528, 3780) // result should be 252
|
} in ggT(2, 8)
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
let g(a) {
|
let g(a) {
|
||||||
a*a
|
a*a
|
||||||
} in g(5)
|
} in b = g(5)
|
||||||
9
Project-02-03-04-05/triplaprograms/reached.tripla
Normal file
9
Project-02-03-04-05/triplaprograms/reached.tripla
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
let f(x,y,z) {
|
||||||
|
y = 2;
|
||||||
|
z = 3;
|
||||||
|
let g(x) {
|
||||||
|
x = 7;
|
||||||
|
if (y > 0) then g(y) else x = 8;
|
||||||
|
x
|
||||||
|
} in g(x) + x
|
||||||
|
} in f(2,3)
|
||||||
5
Project-02-03-04-05/triplaprograms/simpleSequence.tripla
Normal file
5
Project-02-03-04-05/triplaprograms/simpleSequence.tripla
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
let f(x) { x=2*x;
|
||||||
|
if (x>0) then x=x-1 else x;
|
||||||
|
while (x>0) do { x=x-1 }
|
||||||
|
}
|
||||||
|
in f(3)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user