diff --git a/.vscode/launch.json b/.vscode/launch.json index 6e0fa0a..eaba26a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,7 +8,7 @@ "name": "Python: Aktuelle Datei", "type": "python", "request": "launch", - "program": "gui.py", + "program": "interpret_source.py", "console": "integratedTerminal" } ] diff --git a/NassiShneidermann.py b/NassiShneidermann.py index ac2a632..c2b1a7d 100644 --- a/NassiShneidermann.py +++ b/NassiShneidermann.py @@ -1,8 +1,7 @@ -from os import cpu_count -from code_to_image import NSD_save from Iinstruction import Iinstruction -from interpet_source import load_src, get_scoped_instructions +import interpret_source as itp import logging +from typing import List class NassiShneidermanDiagram: @@ -24,16 +23,20 @@ class NassiShneidermanDiagram: def convert_to_image(self, filename: str, x_size=200): logging.info(f"Saving NSD to {filename}.png") - cti.NSD_init(x_size, 1000) + cti.NSD_init(x_size, 5000) x, y, x_sz = 0, 0, x_size for _k, instruction in self.instructions.items(): - x, y = instruction.to_image(x, y, x_sz, 200) + x, y = instruction.to_image(x, y, x_sz, 750) cti.NSD_save(filename) def load_from_file(self, filepath:str): - source_code = load_src(filepath) - instructions = get_scoped_instructions(filepath) + src_code = itp.load_src(filepath) + global_scope = itp.get_instructions_in_scope(src_code)[0] + self.add_instructions_from_scope(global_scope) + def add_instructions_from_scope(self, scope: List[Iinstruction]): + for inst in scope: + self.add_instruction(inst) diff --git a/README.md b/README.md index ee43f6a..3f9f6bc 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,4 @@ This python code generates a Nassi Shneiderman Diagramm from Java Source Code How it works: -In the final Version, you will just have to execute the nassi.exe and choose your Code, it will display the Nassi-Shneiderman-Diagramm and give you the path of the created picture. \ No newline at end of file +In the final version, you will just have to execute the nassi.exe and choose your Code, it will display the Nassi-Shneiderman-Diagramm and give you the path of the created picture. diff --git a/interpet_source.py b/interpet_source.py deleted file mode 100644 index 0dca182..0000000 --- a/interpet_source.py +++ /dev/null @@ -1,90 +0,0 @@ -from Iinstruction import * -import logging -import re -from typing import Any, List, Union - -class Scope(): - - def __init__(self, enclosing_scope) -> None: - self.enclosing_scope = enclosing_scope - self.contents: List = [] - - def add_instruction(self, instruction) -> None: - self.contents.append(instruction) - - def add_subscope(self, subscope) -> None: - self.contents.append(subscope) - -def load_src(filepath: str) -> List[str]: - lines: List[str] = [] - try: - with open(filepath) as file: - for _line in file: - line = _line.strip() - if line and not re.match(r"""^//|^#|^COMMENT|^--""", line): - lines.append(line) - except: - logging.error(f"Failed to open input file {filepath}!") - - return lines - -#TODO: remove debugging-only str -scope_contents = Union[str, Iinstruction, Scope] - -def get_scopes(src: List[str]): - global_scope = Scope(None) - current_scope = global_scope - - for line in src: - logging.debug(line) - if line.__contains__('}'): - current_scope.add_instruction("scope exit") - current_scope = current_scope.enclosing_scope - if line.__contains__('{'): - current_scope.add_instruction("scope enter") - subscope = Scope(current_scope) - current_scope.add_subscope(subscope) - current_scope = subscope - - elif not line.__contains__('}'): - current_scope.add_instruction("generic instruction") - - return global_scope - -def get_instructions(scope: Scope) -> List[scope_contents]: - instructions = [] - - for item in scope.contents: - if isinstance(item, Scope): - instructions.extend(get_instructions(item)) - else: - instructions.append(item) - - return instructions - - - -def get_scoped_instructions(filepath:str) -> List[scope_contents]: - source_code = load_src(filepath) - global_scope = get_scopes(source_code) - - instructions = get_instructions(global_scope) - return instructions - -if __name__ == "__main__": - """debuging""" - - def print_scope(scope: Scope): - print('{') - for item in scope.contents: - if isinstance(item, Scope): - print_scope(item) - else: - print(item, end=";\n") - print('}') - - logging.basicConfig(level=logging.DEBUG) - #inst = get_scoped_instructions("res/input/input.java") - lines = load_src("res/input/input.java") - global_scope = get_scopes(lines) - print_scope(global_scope) \ No newline at end of file diff --git a/interpret_source.py b/interpret_source.py new file mode 100644 index 0000000..582b10b --- /dev/null +++ b/interpret_source.py @@ -0,0 +1,77 @@ +from Iinstruction import * +import logging +import re +from typing import List, Tuple + +class Scope(): + + def __init__(self, enclosing_scope) -> None: + self.enclosing_scope = enclosing_scope + self.contents: List = [] + + def add_instruction(self, instruction: Iinstruction) -> None: + self.contents.append(instruction) + +def load_src(filepath: str) -> List[str]: + lines: List[str] = [] + brace_open_count, brace_closed_count = 0,0 + try: + with open(filepath) as file: + for _line in file: + line = _line.strip() + if line and not re.match(r"""^//|^#|^COMMENT|^--""", line): + lines.append(line) + if line.__contains__('{'): + brace_open_count += 1 + if line.__contains__('}'): + brace_closed_count += 1 + except: + logging.error(f"Failed to open input file {filepath}!") + if brace_open_count != brace_closed_count: + raise Exception("Number of opened braces does not match number of closed ones. Program is illformed!") + + return lines + +def get_instructions_in_scope(src: List[str], start_idx: int = 0) -> Tuple[List[Iinstruction], int]: + outer_scope = Scope(None) + i = start_idx + while i < len(src): + line = src[i] + try: + if line.__contains__('}'): #We exited this scope, return it + return outer_scope.contents, i + + if line.startswith("while("): + logging.debug("Found while instruction in line: %i", i+1) + bracket_idx = line.rindex(')') # throws if the while is illformed + instruction_txt = line[6:bracket_idx] + child_instructions, i = get_instructions_in_scope(src, i+1) + outer_scope.add_instruction(while_instruction_front(instruction_txt, child_instructions)) + + elif line.startswith("if("): + logging.debug("Found if instruction in line: %i", i+1) + bracket_idx = line.rindex(')') # throws if the contruct is illformed + instruction_txt = line[3:bracket_idx] + true_instructions, i = get_instructions_in_scope(src, i+1) + false_instructions = None + if src[i].__contains__("else"): #if there is an else statement, check it + false_instructions, i = get_instructions_in_scope(src, i+1) + outer_scope.add_instruction(if_instruction(instruction_txt, true_instructions, false_instructions)) + + else: + logging.debug("Found generic instruction in line: %i", i+1) + outer_scope.add_instruction(generic_instruction(line)) + except: + logging.error("Encountered error in line: %i", i) + raise # rethrow + i += 1 + return outer_scope.contents, 0 + +if __name__ == "__main__": + """debuging""" + + logging.basicConfig(level=logging.DEBUG) + #inst = get_scoped_instructions("res/input/input.java") + lines = load_src("res/input/input.java") + global_scope = get_instructions_in_scope(lines) + print(global_scope) \ No newline at end of file diff --git a/res/input/input.java b/res/input/input.java index d3a1020..c74e76e 100644 --- a/res/input/input.java +++ b/res/input/input.java @@ -1,23 +1,36 @@ -#comment -//comment -COMMENT this is a comment ---comment - -fahre(); -fahre(); - -while(shouldNiet()) -{ - niet(); - niet(); - if(true) - { - niet(); - niet(); +fahre1(); +fahre2(); +while(shouldNiet()) { + niet4(); + niet5(); + if(if6) { + niet7(); + niet8(); + } else { + niet10(); + niet11(); } + if(if13) { + niet14(); + niet15(); + if(if16) { + niet17(); + niet18(); + } else { + niet20(); + niet21(); + if(if22) { + niet23() + } + } + } else { + niet27(); + niet28(); + } + niet30(); } -niet(); -niet(); +niet32(); +niet33(); // drehe("links"); // while(huegelVorhanden("rechts")) diff --git a/res/output/Nina.png b/res/output/Nina.png index 987d273..d089719 100644 Binary files a/res/output/Nina.png and b/res/output/Nina.png differ