expanded AST search for referenced functions
This commit is contained in:
parent
83350bd6c9
commit
801b60ce33
34
analyze.py
34
analyze.py
@ -47,6 +47,8 @@ if __name__ == "__main__":
|
|||||||
func_table = {}
|
func_table = {}
|
||||||
enum_table = {}
|
enum_table = {}
|
||||||
state_asmts = []
|
state_asmts = []
|
||||||
|
fsm_funcs = []
|
||||||
|
proc_func = None
|
||||||
|
|
||||||
fdv = FuncDefVisitor()
|
fdv = FuncDefVisitor()
|
||||||
fdv.visit(ast)
|
fdv.visit(ast)
|
||||||
@ -58,14 +60,22 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
if not(args.func in func_table):
|
if not(args.func in func_table):
|
||||||
raise Exception(f"Function name '{args.func}' not found!")
|
raise Exception(f"Function name '{args.func}' not found!")
|
||||||
|
else:
|
||||||
|
proc_func = func_table[args.func]
|
||||||
|
fsm_funcs.append(proc_func)
|
||||||
|
func_table[args.func].show()
|
||||||
|
fcv = FuncCallVisitor()
|
||||||
|
fcv.visit(proc_func)
|
||||||
|
fsm_funcs += [ func_table[x] for x in fcv.func_calls ]
|
||||||
|
|
||||||
if args.enum in enum_table:
|
if args.enum in enum_table:
|
||||||
ev = EnumVisitor()
|
ev = EnumVisitor()
|
||||||
ev.visit(enum_table[args.enum])
|
ev.visit(enum_table[args.enum])
|
||||||
for ename in ev.enum_names:
|
for ename in ev.enum_names:
|
||||||
sav = StateAssignmentVisitor(ename)
|
for f in fsm_funcs:
|
||||||
sav.visit(func_table[args.func])
|
sav = StateAssignmentVisitor(ename)
|
||||||
state_asmts += sav.assignments
|
sav.visit(f)
|
||||||
|
state_asmts += sav.assignments
|
||||||
else:
|
else:
|
||||||
print(f"Initial State Enum '{args.enum}' not found")
|
print(f"Initial State Enum '{args.enum}' not found")
|
||||||
|
|
||||||
@ -73,14 +83,15 @@ if __name__ == "__main__":
|
|||||||
for asm in state_asmts:
|
for asm in state_asmts:
|
||||||
paths.append(asm[1])
|
paths.append(asm[1])
|
||||||
|
|
||||||
common = find_common_ancestor(paths)
|
#common = find_common_ancestor(paths)
|
||||||
|
|
||||||
tran_table = []
|
tran_table = []
|
||||||
|
|
||||||
for sa in state_asmts:
|
for sa in state_asmts:
|
||||||
sctv = SwitchCaseTranVisitor(sa[0])
|
for f in fsm_funcs:
|
||||||
sctv.visit(common)
|
sctv = SwitchCaseTranVisitor(sa[0])
|
||||||
tran_table += sctv.tran_table
|
sctv.visit(f)
|
||||||
|
tran_table += sctv.tran_table
|
||||||
|
|
||||||
comp_tt = {}
|
comp_tt = {}
|
||||||
print("Transitions")
|
print("Transitions")
|
||||||
@ -104,10 +115,11 @@ if __name__ == "__main__":
|
|||||||
print(f"{n}->{{{sstr}}}")
|
print(f"{n}->{{{sstr}}}")
|
||||||
|
|
||||||
# find properties
|
# find properties
|
||||||
sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa)
|
for f in fsm_funcs:
|
||||||
sccpv.visit(common)
|
sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa)
|
||||||
if len(sccpv.properties) > 0:
|
sccpv.visit(f)
|
||||||
props_by_state[n] = sccpv.properties
|
if len(sccpv.properties) > 0:
|
||||||
|
props_by_state[n] = sccpv.properties
|
||||||
print("")
|
print("")
|
||||||
|
|
||||||
properties = {}
|
properties = {}
|
||||||
|
|||||||
@ -3,9 +3,17 @@ from pycparser import c_ast
|
|||||||
class FuncDefVisitor(c_ast.NodeVisitor):
|
class FuncDefVisitor(c_ast.NodeVisitor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.func_table = {}
|
self.func_table = {}
|
||||||
|
|
||||||
def visit_FuncDef(self, node):
|
def visit_FuncDef(self, node):
|
||||||
self.func_table[node.decl.name] = node
|
self.func_table[node.decl.name] = node
|
||||||
|
|
||||||
|
class FuncCallVisitor(c_ast.NodeVisitor):
|
||||||
|
def __init__(self):
|
||||||
|
self.func_calls = []
|
||||||
|
|
||||||
|
def visit_FuncCall(self, node):
|
||||||
|
self.func_calls.append(node.children()[0][1].name)
|
||||||
|
|
||||||
class StateAssignmentVisitor(c_ast.NodeVisitor):
|
class StateAssignmentVisitor(c_ast.NodeVisitor):
|
||||||
def __init__(self, state):
|
def __init__(self, state):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@ -38,7 +46,10 @@ class StateAssignmentVisitor(c_ast.NodeVisitor):
|
|||||||
self.visit(c, path)
|
self.visit(c, path)
|
||||||
|
|
||||||
def visit_Assignment(self, n, path):
|
def visit_Assignment(self, n, path):
|
||||||
rval_str = n.rvalue.name
|
n.show()
|
||||||
|
rval_str = ''
|
||||||
|
if not isinstance(n.rvalue, c_ast.Constant):
|
||||||
|
rval_str = n.rvalue.name
|
||||||
if rval_str == self.state:
|
if rval_str == self.state:
|
||||||
self.assignments.append((n,path))
|
self.assignments.append((n,path))
|
||||||
|
|
||||||
@ -99,11 +110,19 @@ class SwitchCasePropertyVisitor(c_ast.NodeVisitor):
|
|||||||
|
|
||||||
def visit_Assignment(self, node):
|
def visit_Assignment(self, node):
|
||||||
if not(node in self._sas):
|
if not(node in self._sas):
|
||||||
prop = None
|
lvalue = None
|
||||||
|
rvalue = None
|
||||||
if isinstance(node.lvalue, c_ast.StructRef):
|
if isinstance(node.lvalue, c_ast.StructRef):
|
||||||
prop = f"{node.lvalue.children()[0][1].name}->{node.lvalue.children()[1][1].name}<={node.rvalue.name}";
|
lvalue = f"{node.lvalue.children()[0][1].name}->{node.lvalue.children()[1][1].name}";
|
||||||
else:
|
else:
|
||||||
prop = f"{node.lvalue.name}<={node.rvalue.name}"
|
lvalue = f"{node.lvalue.name}<={node.rvalue.name}"
|
||||||
|
|
||||||
|
if isinstance(node.rvalue, c_ast.Constant):
|
||||||
|
rvalue = f"{node.rvalue.type }({node.rvalue.value})"
|
||||||
|
else:
|
||||||
|
rvalue = node.rvalue.name
|
||||||
|
|
||||||
|
prop = f"{lvalue}<={rvalue}"
|
||||||
self.properties.append(prop)
|
self.properties.append(prop)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user