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,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,13 +60,21 @@ 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:
for f in fsm_funcs:
sav = StateAssignmentVisitor(ename) sav = StateAssignmentVisitor(ename)
sav.visit(func_table[args.func]) sav.visit(f)
state_asmts += sav.assignments 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,13 +83,14 @@ 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:
for f in fsm_funcs:
sctv = SwitchCaseTranVisitor(sa[0]) sctv = SwitchCaseTranVisitor(sa[0])
sctv.visit(common) sctv.visit(f)
tran_table += sctv.tran_table tran_table += sctv.tran_table
comp_tt = {} comp_tt = {}
@ -104,8 +115,9 @@ if __name__ == "__main__":
print(f"{n}->{{{sstr}}}") print(f"{n}->{{{sstr}}}")
# find properties # find properties
for f in fsm_funcs:
sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa) sccpv = SwitchCaseCodePropertyVisitor(n, pure_sa)
sccpv.visit(common) sccpv.visit(f)
if len(sccpv.properties) > 0: if len(sccpv.properties) > 0:
props_by_state[n] = sccpv.properties props_by_state[n] = sccpv.properties
print("") print("")

View File

@ -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,6 +46,9 @@ 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):
n.show()
rval_str = ''
if not isinstance(n.rvalue, c_ast.Constant):
rval_str = n.rvalue.name 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)