From ebaaa03b854a9344b495f5fc68dd89d6bf75bd87 Mon Sep 17 00:00:00 2001 From: Katherine Braught <braught2@illinois.edu> Date: Tue, 5 Apr 2022 21:44:49 -0500 Subject: [PATCH] WIP on graph generation, fix guard issues --- pythonparser.py | 163 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 22 deletions(-) diff --git a/pythonparser.py b/pythonparser.py index bc2964eb..588014ac 100644 --- a/pythonparser.py +++ b/pythonparser.py @@ -14,6 +14,13 @@ import ast #from cfg import CFG #import clang.cfg +class Edge: + def __init__(self, source, dest, guards, resets): + self.source = source + self.dest = dest + self.guards = guards + self.resets = resets + class Statement: def __init__(self, code, mode, modeType): self.code = code @@ -37,11 +44,11 @@ class Guard(Statement): def parseGuard(node, code): #assume guard is a strict comparision (modeType == mode) if isinstance(node.test, ast.Compare): - if ("mode" in str(node.test.left.id)): - modeType = str(node.test.left.id) - #TODO: get this to work - mode = str(node.test.comparators[0].attr) - return Guard(ast.get_source_segment(code, node.test), mode, modeType) + if isinstance(node.test.comparators[0], ast.Attribute): + if ("Mode" in str(node.test.comparators[0].value.id)): + modeType = str(node.test.comparators[0].value.id) + mode = str(node.test.comparators[0].attr) + return Guard(ast.get_source_segment(code, node.test), mode, modeType) else: return Guard(ast.get_source_segment(code, node.test), None, None) @@ -123,6 +130,96 @@ def parsenodelist(code, nodes, addResets, pathsToMe): return pathsafterme +def resetString(resets): + outstr = "" + for reset in resets: + outstr+= reset.code + ";" + outstr = outstr.strip(";") + return outstr + +def guardString(guards): + return guards + +#modes are the list of all modes in the current vertex +#vertices are all the vertexs +def getIndex(modes, vertices): + #TODO: will this work if ordering is lost, will ordering be lost? + return vertices.index(tuple(modes)) + #for index in range(0, len(vertices)): + # allMatch = True + # for mode in modes: + # if not (mode in vertices[index]): + # allMatch = False + # if allMatch: + # return index + return -1 + +def createTransition(path, vertices, modes): + guards = [] + resets = [] + modeChecks = [] + modeUpdates = [] + for item in path: + if isinstance(item, Guard): + if not item.isModeCheck(): + guards.append(item) + else: + modeChecks.append(item) + if isinstance(item, Reset): + if not item.isModeUpdate(): + resets.append(item) + else: + modeUpdates.append(item) + unfoundSourceModeTypes = [] + sourceModes = [] + unfoundDestModeTypes = [] + destModes = [] + for modeType in modes.keys(): + foundMode = False + for condition in modeChecks: + #print(condition.modeType) + #print(modeType) + if condition.modeType == modeType: + sourceModes.append(condition.mode) + foundMode = True + if foundMode == False: + unfoundSourceModeTypes.append(modeType) + foundMode = False + for condition in modeUpdates: + if condition.modeType == modeType: + destModes.append(condition.mode) + foundMode = True + if foundMode == False: + unfoundDestModeTypes.append(modeType) + + unfoundModes = [] + for modeType in unfoundSourceModeTypes: + unfoundModes.append(modes[modeType]) + unfoundModeCombinations = itertools.product(*unfoundModes) + sourceVertices = [] + for unfoundModeCombo in unfoundModeCombinations: + sourceVertex = sourceModes.copy() + sourceVertex.extend(unfoundModeCombo) + sourceVertices.append(sourceVertex) + + unfoundModes = [] + for modeType in unfoundDestModeTypes: + unfoundModes.append(modes[modeType]) + unfoundModeCombinations = itertools.product(*unfoundModes) + destVertices = [] + for unfoundModeCombo in unfoundModeCombinations: + destVertex = destModes.copy() + destVertex.extend(unfoundModeCombo) + destVertices.append(destVertex) + + edges = [] + for source in sourceVertices: + sourceindex = getIndex(source, vertices) + for dest in destVertices: + destindex = getIndex(dest, vertices) + edges.append(Edge(sourceindex, destindex, guards, resets)) + + return edges ##main code### #print(sys.argv) @@ -147,15 +244,15 @@ if __name__ == "__main__": code = f.read() tree = ast.parse(code) #tree = ast.parse() - results, vars, modes = walktree(code, tree) + paths, vars, modes = walktree(code, tree) - print("Paths found:") - for result in results: - for item in result: - item.print() + #print("Paths found:") + #for result in paths: + # for item in result: + #item.print() #print(item.mode) #print(item.modeType) - print() + # print() print("Modes found: ") print(modes) @@ -163,19 +260,41 @@ if __name__ == "__main__": output_dict.update(input_json) #TODO: create graph! - - + vertices = [] + vertexStrings = [] + for vertex in itertools.product(*modes.values()): + vertices.append(vertex) + vertexstring = vertex[0] + for index in range(1,len(vertex)): + vertexstring += ";" + vertex[index] + vertexStrings.append(vertexstring) + + edges = [] + guards = [] + resets = [] + + for path in paths: + transitions = createTransition(path, vertices, modes) + for edge in transitions: + edges.append([edge.source, edge.dest]) + guards.append(guardString(edge.guards)) + resets.append(resetString(edge.resets)) + output_dict['vertex'] = vertices + #print(vertices) + output_dict['variables'] = vars # #add edge, transition(guards) and resets - #output_dict['edge'] = edges - #output_dict['guards'] = guards - #output_dict['resets'] = resets - #output_dict['vertex'] = mode_list - - output_json = json.dumps(output_dict, indent=4) - outfile = open(output_file_name, "w") - outfile.write(output_json) - outfile.close() + output_dict['edge'] = edges + #print(edges) + output_dict['guards'] = guards + #print(guards) + output_dict['resets'] = resets + print(resets) + + #output_json = json.dumps(output_dict, indent=4) + #outfile = open(output_file_name, "w") + #outfile.write(output_json) + #outfile.close() print("wrote json to " + output_file_name) -- GitLab