Source code for AutoRPE.UtilsRPE.NatureDeterminer

import AutoRPE.UtilsRPE.BasicFunctions as BasicFunctions
import AutoRPE.UtilsRPE.MaskCreator as MaskCreator
import AutoRPE.UtilsRPE.RegexPattern as RegexPattern
import AutoRPE.UtilsRPE.VariablePrecision as VariablePrecision
import AutoRPE.UtilsRPE.SourceManager as SourceManager

import re


[docs] def is_function_declaration_statement(line: str): """ Checks if the line contains a function declaration statement. Parameters: line (str): A line of source code to check for a function declaration. Returns: bool: True if the line matches the syntax of a function declaration, False otherwise. """ # Remove matches inside write(*,*) statements # Check for function declaration syntax is_start = re.search(RegexPattern.function_declaration, line, re.MULTILINE | re.IGNORECASE) if is_start: return True return False
[docs] def is_end_function_statement(line: str): """ Checks if the line contains an 'end function' statement. Parameters: line (str): A line of source code to check for an 'end function' statement. Returns: - bool: True if the line matches the syntax of an 'end function' statement, False otherwise. """ is_end = re.match(RegexPattern.end_function_declaration, line, re.I) if is_end: return True return False
[docs] def is_a_number(string): """ Checks if a string is a valid number and return its type if applicable. Parameters: string (str): The string to be checked. Returns: str or bool: The type of the number (e.g., 'integer' or 'real'), or False if it's not a number. Raises: ValueError: If the string cannot be converted to a number and does not match valid formats. """ # Check if is just white spaces if not string.strip(): return False else: string = string.lower().strip() # Remove unary operator if present string = BasicFunctions.remove_unary_operator(string) if has_intrinsics(string): return False # Checks for number in exponential notation exp = re.match(RegexPattern.number_exp_DPE_notation, string) # Checks for number with precision specified real_with_precision = re.match("^" + RegexPattern.real_number_with_precision + "$", string) if real_with_precision: # In case the number is a hardcoded real with a type specification, # check the lookup table to know to which type it corresponds and return it new_type = VariablePrecision.lookup_table[real_with_precision.group(2)] return new_type if exp: return VariablePrecision.real_id['wp'] integer_with_precision = re.match(RegexPattern.integer_number_with_precision, string) if integer_with_precision: return "integer" # Check for pure integer and real numbers try: float(string) if string.isdigit(): return "integer" else: return VariablePrecision.real_id['wp'] except ValueError: return False
[docs] def is_hardcoded_array(string, array=None): """ Checks if the string represents a hardcoded array [form (/a, b/)] and optionally populate the array parameter. Parameters: string (str): The string to check if it represents a hardcoded array. array (list, optional): If provided, the array will be populated with the elements found in the array. Returns: bool: True if the string represents a hardcoded array, False otherwise. """ import AutoRPE.UtilsRPE.CallManager as CallManager match = re.match(RegexPattern.hardcoded_array, string) if match: if array is not None: # remove_outer_brackets will remove parenthesis just if present content = "(" + BasicFunctions.remove_outer_brackets(match.group(2)) + ")" array.extend(CallManager.find_call_arguments(content)) return True return False
[docs] def is_pointer_assignment(string: str): """ Checks if the string represents a pointer assignment. Parameters: string (str): The string to check if it contains a pointer assignment. Returns: bool: True if the string represents a pointer assignment, False otherwise. """ pattern = ".* => .*" if re.search(pattern, string, flags=re.I): return True return False
[docs] def is_logical_comparison(string: str): """ Checks if the string contains a logical comparison operator. Parameters: string (str): The string to check for logical comparison operators. Returns: bool: True if the string contains a logical comparison operator, False otherwise. """ for element in SourceManager.comparison_operators: if string.lower().count(element): return True return False
[docs] def is_keyword_argument(argument: str, key_arg=None): """ Checks if the argument is a keyword argument and optionally store the key-value pair. Parameters: argument (str): The argument string to check. key_arg (list, optional): If provided, the list will be populated with the key and argument value. Returns: bool: True if the argument is a keyword argument, False otherwise. """ if re.search(RegexPattern.key_word_argument, argument): if key_arg is not None: [key, argument] = argument.split("=", 1) key = key.strip() argument = argument.strip() key_arg.extend([key, argument]) return True return False
[docs] def is_array(contents: str, check_sliced: bool=False): """ Checks if the contents represent an array, optionally checking for slicing. Parameters: contents (str): The contents to check if they represent an array. check_sliced (bool, optional): If True, the function checks if the array is sliced. Returns: bool: True if the contents represent an array, False otherwise. """ import AutoRPE.UtilsRPE.CallManager as CallManager # First does a first filter checking that the syntax is similar to a function call and afterwards # uses one of the two possible approaches, depending on having a vault available or not. # The syntax is be the same for vector and function (unless vector is sliced) m = re.match(RegexPattern.call_to_function, contents.strip(), re.I) if not m: return False if contents == BasicFunctions.close_brackets(contents): arguments = CallManager.find_call_arguments(contents) # No arguments: it is a function or a single variable if arguments: if not check_sliced: return True else: # check if an argument is a slice for arg in arguments: if re.match(r"\w*:\w*", arg) or arg == ":": return True return False return False
[docs] def has_operations(string: str, operand=None): """ Checks if the string contains mathematical operations and optionally splits the operands. Parameters: string (str): The string to check for operations. operand (list, optional): If provided, the operands will be split and stored in the list. Returns: bool: True if the string contains mathematical operations, False otherwise. """ operations = ["+", "-", "*", "/"] # Exclude key arguments if is_keyword_argument(string): return False # Check if string is just white spaces if not string.strip(): return False else: string = string.replace(" ", "") if is_array(string): return False if operand is not None: # If we want to split the argument by operand, store the masked element in a dictionary dictionary_of_replacements = {} string = MaskCreator.mask_string_for_check_operation(string, dictionary_of_replacements) else: string = MaskCreator.mask_string_for_check_operation(string) # Now that all offenders have been masked, split the elements for op in operations: # Substitute all operators with a placeholder string = string.replace(op, "#") # The string does not contains operations if not string.count("#"): return False else: # Fill the passed vector if operand is not None: # A void unitary operators to be considered operators ( rn_Dt * (-10_wp)) => rn_Dt * -10_wp ) string = re.sub(r"#\s*#", r"#", string) # Remove unary operators at the beginning of the string string = re.sub(r"^\s*#", "", string) # Split by placeholder arguments = string.split("#") # Strip from spaces due to substitutions arguments = [a.strip() for a in arguments] operand.extend(MaskCreator.unmask_from_dict(arguments, dictionary_of_replacements)) # Substitute back all entities that were masked return True
[docs] def has_intrinsics(string: str): """ Checks if the string contains any intrinsic function calls. Parameters: string (str): The string to check for intrinsic function calls. Returns: str or None: The name of the intrinsic function if found, None otherwise. """ for key in SourceManager.list_of_key: if string.lower().count(key): key_match = r"\s*[ ,(+-]%s *= *\w" % key string = re.sub(key_match, "", string, re.I) # Split parenthesis opening if not string.count("("): return False possible_intrinsics = re.findall(r'\s*\b\w+\b\s*\(', string, re.I) for name in possible_intrinsics: # Remove last parenthesis and leading spaces name = name[:-1].strip() try: SourceManager.list_of_intrinsics[name.lower()] return name except KeyError: continue return None
[docs] def is_struct_element(contents: str) -> bool: """ Checks if the contents represent a structure element (derived type). Parameters: contents (str): The contents to check for structure element notation (e.g., 'struct%element'). Returns: bool: True if the contents represent a structure element, False otherwise. """ if contents.count("%"): return True return False ...