expanded AST search for referenced functions

This commit is contained in:
Dominic Höglinger 2022-11-21 18:06:42 +01:00
parent 83350bd6c9
commit 801b60ce33
2 changed files with 48 additions and 17 deletions

View File

@ -47,7 +47,9 @@ if __name__ == "__main__":
func_table = {}
enum_table = {}
state_asmts = []
fsm_funcs = []
proc_func = None
fdv = FuncDefVisitor()
fdv.visit(ast)
func_table = fdv.func_table
@ -58,14 +60,22 @@ if __name__ == "__main__":
if not(args.func in func_table):
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:
ev = EnumVisitor()
ev.visit(enum_table[args.enum])
for ename in ev.enum_names:
sav = StateAssignmentVisitor(ename)
sav.visit(func_table[args.func])
state_asmts += sav.assignments
for f in fsm_funcs:
sav = StateAssignmentVisitor(ename)
sav.visit(f)
state_asmts += sav.assignments
else:
print(f"Initial State Enum '{args.enum}' not found")
@ -73,14 +83,15 @@ if __name__ == "__main__":
for asm in state_asmts:
paths.append(asm[1])
common = find_common_ancestor(paths)
#common = find_common_ancestor(paths)
tran_table = []
for sa in state_asmts:
sctv = SwitchCaseTranVisitor(sa[0])
sctv.visit(common)
tran_table += sctv.tran_table
for f in fsm_funcs:
sctv = SwitchCaseTranVisitor(sa[0])
sctv.visit(f)
tran_table += sctv.tran_table
comp_tt = {}
print("Transitions")
@ -104,10 +115,11 @@ if __name__ == "__main__":
print(f"{n}->{{{sstr}}}")
# find properties
sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa)
sccpv.visit(common)
if len(sccpv.properties) > 0:
props_by_state[n] = sccpv.properties
for f in fsm_funcs:
sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa)
sccpv.visit(f)
if len(sccpv.properties) > 0:
props_by_state[n] = sccpv.properties
print("")
properties = {}

View File

@ -3,9 +3,17 @@ from pycparser import c_ast
class FuncDefVisitor(c_ast.NodeVisitor):
def __init__(self):
self.func_table = {}
def visit_FuncDef(self, 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):
def __init__(self, state):
super().__init__()
@ -38,7 +46,10 @@ class StateAssignmentVisitor(c_ast.NodeVisitor):
self.visit(c, 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:
self.assignments.append((n,path))
@ -99,11 +110,19 @@ class SwitchCasePropertyVisitor(c_ast.NodeVisitor):
def visit_Assignment(self, node):
if not(node in self._sas):
prop = None
lvalue = None
rvalue = None
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:
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)