diff --git a/gui/gui.py b/gui/gui.py index deb0c23..4029815 100644 --- a/gui/gui.py +++ b/gui/gui.py @@ -226,7 +226,7 @@ class Gui: output_name = secrets.token_hex(16) nassi(input_path=file_path, output_path=output_path, outputname=output_name, gui=self, - font_filepath=font_filepath, behaviour=exists_choice, types=types, remove_tages=modifier, comments=comments) + font_filepath=font_filepath, behaviour=exists_choice, types=types, remove_tags=modifier, comments=comments) fnames = output(values['-OUTPUT FOLDER-']) sg.popup_annoying('Successfully created!', title='Created', diff --git a/gui/utils.py b/gui/utils.py index 62c81b6..9fb5cb1 100644 --- a/gui/utils.py +++ b/gui/utils.py @@ -20,8 +20,10 @@ def nassi(input_path: str, output_path: str, outputname: str, types, remove_tags logging.error('Error: Creating directory. ' + output_directory) except: raise + + custom_tags = {"comments" : comments, "ignore" : remove_tags, "types" : types} - NSD.load_from_file(input_path, types, remove_tags, comments) + NSD.load_from_file(input_path, custom_tags) NSD.convert_to_image(output_directory, on_conflict=behaviour, x_size=750) return output_directory diff --git a/interpreter/NassiShneidermann.py b/interpreter/NassiShneidermann.py index 220d206..cc4e973 100644 --- a/interpreter/NassiShneidermann.py +++ b/interpreter/NassiShneidermann.py @@ -1,5 +1,5 @@ from interpreter.interpret_source import Function_scope -from typing import List +from typing import Dict, List import logging from enum import IntEnum import os.path @@ -69,6 +69,7 @@ class NassiShneidermanDiagram: logging.error(f"Failed to save image {filepath}. Unknown error") raise - def load_from_file(self, filepath:str): + def load_from_file(self, filepath:str, itp_custom_tags: Dict[str, List[str]]): itp = JavaInterpreter(filepath) + itp.reset_tags(itp_custom_tags) self.function_scopes = itp.load_instruction_scopes() \ No newline at end of file diff --git a/interpreter/interpret_source.py b/interpreter/interpret_source.py index eaa438f..e868b7e 100644 --- a/interpreter/interpret_source.py +++ b/interpreter/interpret_source.py @@ -8,6 +8,7 @@ from draw.Iinstruction import * logging.warning("""Because the Interpreter is still WIP, some Java language features are not supported. These include: *else if statements *for loops + *Constructors (will be ignored) Please remove these features from the source code as they will result in incorrect behaviour""") class Function_scope(Iterable): @@ -32,8 +33,8 @@ class JavaInterpreter: with open(filepath) as file: if not file.readable(): raise InterpreterException(f"Unable to read input file {filepath}") - self.src = file.read() - self.lines = [] # to be filled in later + self._src = file.read() + self._lines = [] # to be filled in later self._init_regex() self._recompile_regex() @@ -46,56 +47,63 @@ class JavaInterpreter: if additional_tags: if "comments" in additional_tags.keys(): - self.comment_tags.extend(additional_tags["comments"]) + if tags := additional_tags["comments"]: + self._comment_tags.extend(tags) if "ignore" in additional_tags.keys(): - self.remove_tags.extend(additional_tags["ignore"]) + if tags := additional_tags["ignore"]: + self._remove_tags.extend(tags) if "types" in additional_tags.keys(): - self.type_tags.extend(additional_tags["types"]) - self.function_tags.extend(additional_tags["types"]) + if tags := additional_tags["types"]: + self._type_tags.extend(tags) + self._function_tags.extend(tags) else: self._init_regex() self._recompile_regex() + def load_instruction_scopes(self): + self._remove_keywords() + return self._get_function_scopes() + def _init_regex(self): """Initialize all tag lists to their default state""" - self.comment_tags = ["//", "#", "--"] #dont ask why a java interpreter supports lua and python style comments - self.remove_tags = ['\n', "public", "private", "protected", "final"] - self.type_tags = ["byte", "short", "int", "long", "float", "double", "boolean", "char", "String"] - self.function_tags = ["void"] - self.function_tags.extend(self.type_tags) + self._comment_tags = ["//", "#", "--"] #dont ask why a java interpreter supports lua and python style comments + self._remove_tags = ['\n', "public", "private", "protected", "final"] + self._type_tags = ["byte", "short", "int", "long", "float", "double", "boolean", "char", "String"] + self._function_tags = ["void"] + self._function_tags.extend(self._type_tags) def _recompile_regex(self): """recompile all regex's using the new tag lists""" comment_regex = r"""^(""" - for tag in self.comment_tags: + for tag in self._comment_tags: comment_regex += fr"""{re.escape(tag)}|""" - self.comment_pattern = re.compile(comment_regex[:-1]+").*", flags=re.MULTILINE) + self._comment_pattern = re.compile(comment_regex[:-1]+").*", flags=re.MULTILINE) remove_regex = r"""^(""" - for tag in self.remove_tags: - remove_regex += fr"""{re.escape(tag)}|""" - self.remove_pattern = re.compile(remove_regex[:-1]+')', flags=re.MULTILINE) + for tag in self._remove_tags: + remove_regex+= fr"""{re.escape(tag)}|""" + self._remove_pattern = re.compile(remove_regex[:-1]+')', flags=re.MULTILINE) variable_regex = r"""^(""" - for tag in self.type_tags: + for tag in self._type_tags: variable_regex += fr"""{re.escape(tag)}|""" - self.variable_pattern = re.compile(variable_regex[:-1]+")(.*=|.*;)(.*)", flags=re.MULTILINE) + self._variable_pattern = re.compile(variable_regex[:-1]+")(.*=|.*;)(.*)", flags=re.MULTILINE) function_regex = r"""^(?P""" - for tag in self.function_tags: + for tag in self._function_tags: function_regex += fr"""{re.escape(tag)}|""" - self.function_pattern = re.compile(function_regex[:-1]+")(?P.*)[(](?P.*)[)][^;]", flags=re.MULTILINE) + self._function_pattern = re.compile(function_regex[:-1]+")(?P.*)[(](?P.*)[)][^;]", flags=re.MULTILINE) def _check_src(self, idx: int, tag: str) -> bool: - if idx >= len(self.lines): + if idx >= len(self._lines): return False - return tag in self.lines[idx] + return tag in self._lines[idx] def _check_line_start(self, idx: int, tag: str) -> bool: - if idx >= len(self.lines): + if idx >= len(self._lines): return False - return self.lines[idx].startswith(tag) + return self._lines[idx].startswith(tag) def _get_scope_start_offset(self, i: int) -> int: if self._check_src(i, "{"): @@ -145,12 +153,12 @@ class JavaInterpreter: instruction_txt = None if self._check_line_start(idx, "}while("): - end_line = self.lines[idx] + end_line = self._lines[idx] bracket_index = end_line.rindex(')') #throws if contruct id ill-formed instruction_txt = end_line[7:bracket_index] elif self._check_line_start(idx+1, "while("): idx += 1 - end_line = self.lines[idx] + end_line = self._lines[idx] bracket_index = end_line.rindex(')') instruction_txt = end_line[6:bracket_index] else: @@ -159,7 +167,7 @@ class JavaInterpreter: return while_instruction_back(instruction_txt, child_instructions), idx def _handle_variable(self, line: str, idx: int): - groups = self.variable_pattern.match(line).groups() + groups = self._variable_pattern.match(line).groups() var_type = groups[0] var_name = groups[1][:-1] var_value = groups[2] @@ -180,7 +188,7 @@ class JavaInterpreter: logging.debug("Found do-while construct in line: %i", idx+1) return self._handle_do_while(line, idx) - elif self.variable_pattern.match(line): + elif self._variable_pattern.match(line): logging.debug("Found variable in line %i", idx+1) return self._handle_variable(line, idx) @@ -191,8 +199,8 @@ class JavaInterpreter: def _get_instructions_in_scope(self, idx: int=0) -> Tuple[List[Iinstruction], int]: scope: List[Iinstruction] = [] i = idx - while i < len(self.lines): - line = self.lines[i] + while i < len(self._lines): + line = self._lines[i] if self._check_src(i, '}'): break @@ -204,103 +212,34 @@ class JavaInterpreter: return scope, i def _remove_keywords(self): - self.src = self.src.replace(' ', '') - self.src = self.comment_pattern.sub('', self.src) - self.src = self.remove_pattern.sub('', self.src) - self.lines = self.src.splitlines() + self.src = self._src.replace(' ', '') + self.src = self._comment_pattern.sub('', self.src) + self.src = self._remove_pattern.sub('', self.src) + self._lines = self.src.splitlines() def _get_function_info(self, match: Match[str]) -> Tuple[str, str, List[str]]: groups = match.groupdict() ftype = groups["return_type"] - fargs = groups["args"] + fargs = groups["args"].split(',') fname = groups["name"] - return ftype, fname, fargs.split(',') + return ftype, fname, fargs def _get_function_instructions(self, function_header: str) -> List[Iinstruction]: - idx = self.lines.index(function_header) + idx = self._lines.index(function_header) brace_offset = self._get_scope_start_offset(idx) return self._get_instructions_in_scope(idx+brace_offset)[0] + def _get_function_scope(self, match: re.Match[str]): + span = match.span() + header = self.src[span[0]:span[1]].replace('\n', '') + + rtype, name, args = self._get_function_info(match) + + child_instructions = self._get_function_instructions(header) + + return Function_scope(child_instructions, name, rtype, args) + + def _get_function_scopes(self) -> List[Function_scope]: - scopes = [] - for match in self.function_pattern.finditer(self.src): - span = match.span() - header = self.src[span[0]:span[1]].replace('\n', '') - - rtype, name, args = self._get_function_info(match) - - child_instructions = self._get_function_instructions(header) - - scopes.append(Function_scope(child_instructions, name, rtype, args)) - return scopes - - - def load_instruction_scopes(self): - self._remove_keywords() - return self._get_function_scopes() - - -# COMMENT_PATTERN = re.compile(r"""^(//|#|--)""") -# REMOVE_KEYWORDS = [' ', "public", "private", "final", "protected"] -# VARIABLE_TAGS = ["byte", "short", "int", "long", "float", "double", "boolean", "char", "String"] -# FUNCTION_IDENTIFIERS = ["void"] -# FUNCTION_IDENTIFIERS.extend(VARIABLE_TAGS) - -# WHILE_TAG = "solange " #german for 'while'. Change this depending on your language - -# REPLACE = dict((re.escape(k), '') for k in REMOVE_KEYWORDS) -# remove_pattern = re.compile("|".join(REPLACE.keys()), flags=re.MULTILINE) - -# variable_regex = "^(" -# for kw in VARIABLE_TAGS: -# variable_regex += fr"""{kw}|""" -# variable_pattern = re.compile(variable_regex[0:-1]+")(.*=|.*;)(.*)", flags=re.MULTILINE) - -# function_regex = "^(?P" -# for kw in FUNCTION_IDENTIFIERS: -# function_regex += fr"""{kw}|""" -# function_regex = function_regex[0:-1]+ ")(?P.*)[(](?P.*)[)][^;]" - -# function_pattern = re.compile(function_regex, flags=re.MULTILINE) - -# def check_src(src: List[str], line_index: int, tag: str) -> bool: -# if line_index >= len(src): -# return False -# return tag in src[line_index] - -# def check_line_start(src: List[str], line_index: int, tag: str) -> bool: -# if line_index >= len(src): -# return False -# return src[line_index].startswith(tag) - -# def get_next_occurence_of(src: List[str], start_idx:int, tag:str) -> int: -# """Returns the index of the next occurence of tag in src from start_idx""" -# i = start_idx -# while i < len(src): -# if check_src(src, i, tag): -# break -# i += 1 -# return i - -# def get_scope_start_offset(src: List[str], i: int) -> int: -# if check_src(src, i, "{"): -# return 1 -# elif check_src(src, i+1, "{"): -# return 2 -# raise ScopeNotFoundException("Unable to find scope start. Is the program ill-formed?") - - -# def get_function_scopes(src: str) -> List[Function_scope]: -# scopes = [] -# lines = src.splitlines(True) -# for match in function_pattern.finditer(src): - -# span = match.span() -# matched_str = src[span[0]:span[1]] - -# rtype, name, args = get_function_info(match, matched_str) - -# child_instructions = get_function_instructions(lines, matched_str) - -# scopes.append(Function_scope(child_instructions, name, rtype, args)) -# return scopes \ No newline at end of file + matches = self._function_pattern.finditer(self.src) + return list(map(self._get_function_scope, matches)) \ No newline at end of file diff --git a/res/input/input.java b/res/input/input.java index 67d01ba..5527716 100644 --- a/res/input/input.java +++ b/res/input/input.java @@ -10,6 +10,12 @@ public class Rover extends Actor * this function is to be implemented by the user * depending on the needed actions */ + + public Display getDisplay() + { + return anzeige; + } + public void act() { S66Nr3(7);