def create_object(json_obj, enc_obj=None): if enc_obj is not None: enc_scope_name = enc_obj.FQSN else: enc_scope_name = None if "mods" in json_obj: modifiers, dim_str, _ = map_keywords(json_obj["mods"]) else: modifiers = [] dim_str = None name = json_obj["name"] args = json_obj.get("args", "") if lowercase_intrinsics: name = name.lower() args = args.lower() if json_obj["type"] == 0: mod_tmp = fortran_module(none_file, 0, name, enc_scope=enc_scope_name) if "use" in json_obj: mod_tmp.add_use(json_obj["use"], 0) return mod_tmp elif json_obj["type"] == 1: return fortran_subroutine(none_file, 0, name, enc_scope=enc_scope_name, args=args) elif json_obj["type"] == 2: return fortran_function( none_file, 0, name, enc_scope=enc_scope_name, args=args, return_type=[json_obj["return"], modifiers, dim_str]) elif json_obj["type"] == 3: return fortran_obj(none_file, 0, name, json_obj["desc"], modifiers, dim_str, enc_scope_name) elif json_obj["type"] == 4: return fortran_type(none_file, 0, name, modifiers, enc_scope_name) else: raise ValueError
def create_object(json_obj, enc_obj=None): enc_scope_name = None args = "" modifiers = [] if enc_obj is not None: enc_scope_name = enc_obj.FQSN if "args" in json_obj: args = json_obj["args"] if "mods" in json_obj: modifiers = parse_keywords(json_obj["mods"]) if json_obj["type"] == 0: mod_tmp = fortran_module(none_file, 0, json_obj["name"], enc_scope=enc_scope_name) if "use" in json_obj: mod_tmp.add_use(json_obj["use"], 0) return mod_tmp elif json_obj["type"] == 1: return fortran_subroutine(none_file, 0, json_obj["name"], enc_scope=enc_scope_name, args=args) elif json_obj["type"] == 2: return fortran_function( none_file, 0, json_obj["name"], enc_scope=enc_scope_name, args=args, return_type=[json_obj["return"], modifiers]) elif json_obj["type"] == 3: return fortran_obj(none_file, 0, json_obj["name"], json_obj["desc"], modifiers, enc_scope_name) elif json_obj["type"] == 4: return fortran_type(none_file, 0, json_obj["name"], modifiers, enc_scope_name) else: raise ValueError
def create_object(json_obj, enc_obj=None): if enc_obj is not None: none_ast.enc_scope_name = enc_obj.FQSN else: none_ast.enc_scope_name = None if "mods" in json_obj: keywords, keyword_info = map_keywords(json_obj["mods"]) else: keywords = [] keyword_info = {} name = json_obj["name"] args = json_obj.get("args", "") if lowercase_intrinsics: name = name.lower() args = args.lower() if json_obj["type"] == 0: mod_tmp = fortran_module(none_ast, 0, name) if "use" in json_obj: mod_tmp.add_use(json_obj["use"], 0) return mod_tmp elif json_obj["type"] == 1: return fortran_subroutine(none_ast, 0, name, args=args) elif json_obj["type"] == 2: return fortran_function( none_ast, 0, name, args=args, return_type=[json_obj["return"], keywords, keyword_info]) elif json_obj["type"] == 3: return fortran_var(none_ast, 0, name, json_obj["desc"], keywords, keyword_info) elif json_obj["type"] == 4: return fortran_type(none_ast, 0, name, keywords) else: raise ValueError
def process_file(file_str, close_open_scopes, path=None, fixed_format=False, debug=False, pp_defs=None): def preprocess(): # Look for and mark excluded preprocessor paths in file # Initial implementation only looks for "if" and "ifndef" statements. # For "if" statements all blocks are excluded except the "else" block if present # For "ifndef" statements all blocks excluding the first block are exlucded def eval_pp_if(text, defs={}): def replace_ops(expr): expr = expr.replace("&&", " and ") expr = expr.replace("||", " or ") expr = expr.replace("!=", " <> ") expr = expr.replace("!", " not ") expr = expr.replace(" <> ", " != ") return expr def replace_defined(line): DEFINED_REGEX = re.compile( r'defined[ ]*\([ ]*([a-z_][a-z0-9_]*)[ ]*\)', re.I) i0 = 0 out_line = "" for match in DEFINED_REGEX.finditer(line): if match.group(1) in defs: out_line += line[i0:match.start(0)] + "($@)" else: out_line += line[i0:match.start(0)] + "($%)" i0 = match.end(0) if i0 < len(line): out_line += line[i0:] return out_line def replace_vars(line): WORD_REGEX = re.compile(r'[a-z_][a-z0-9_]*', re.I) i0 = 0 out_line = "" for match in WORD_REGEX.finditer(line): if match.group(0) in defs: out_line += line[i0:match.start(0)] + defs[match.group( 0)] else: out_line += line[i0:match.start(0)] + "False" i0 = match.end(0) if i0 < len(line): out_line += line[i0:] out_line = out_line.replace("$@", "True") out_line = out_line.replace("$%", "False") return out_line out_line = replace_defined(text) out_line = replace_vars(out_line) try: line_res = eval(replace_ops(out_line)) except: return False else: return line_res # pp_skips = [] pp_defines = [] pp_stack = [] defs_tmp = pp_defs.copy() output_file = [] for (i, line) in enumerate(file_str): match = PP_REGEX.match(line) if (match is not None): output_file.append(line) def_name = None if_start = False if match.group(1) == 'if ': is_path = eval_pp_if(line[match.end(1):], defs_tmp) if_start = True elif match.group(1) == 'ifdef': if_start = True def_name = line[match.end(0):].strip() is_path = (def_name in defs_tmp) elif match.group(1) == 'ifndef': if_start = True def_name = line[match.end(0):].strip() is_path = not (def_name in defs_tmp) if if_start: if is_path: pp_stack.append([-1, -1]) if debug: print('{1} !!! Conditional TRUE({0})'.format( i + 1, line.strip())) else: pp_stack.append([i + 1, -1]) if debug: print('{1} !!! Conditional FALSE({0})'.format( i + 1, line.strip())) continue if len(pp_stack) == 0: continue # inc_start = False exc_start = False if (match.group(1) == 'elif'): if (pp_stack[-1][0] < 0): pp_stack[-1][0] = i + 1 exc_start = True else: if eval_pp_if(line[match.end(1):], defs_tmp): pp_stack[-1][1] = i - 1 pp_stack.append([-1, -1]) inc_start = True elif match.group(1) == 'else': if pp_stack[-1][0] < 0: pp_stack[-1][0] = i + 1 exc_start = True else: pp_stack[-1][1] = i + 1 inc_start = True elif match.group(1) == 'endif': if pp_stack[-1][0] < 0: pp_stack.pop() continue if pp_stack[-1][1] < 0: pp_stack[-1][1] = i + 1 if debug: print('{1} !!! Conditional FALSE/END({0})'.format( i + 1, line.strip())) pp_skips.append(pp_stack.pop()) if debug: if inc_start: print('{1} !!! Conditional TRUE({0})'.format( i + 1, line.strip())) elif exc_start: print('{1} !!! Conditional FALSE({0})'.format( i + 1, line.strip())) continue # match = PP_DEF_REGEX.match(line) if (match is not None) and ((len(pp_stack) == 0) or (pp_stack[-1][0] < 0)): output_file.append(line) pp_defines.append(i + 1) def_name = match.group(2) if (match.group(1) == 'define') and (def_name not in defs_tmp): eq_ind = line[match.end(0):].find(' ') if eq_ind >= 0: defs_tmp[def_name] = line[match.end(0) + eq_ind:].strip() else: defs_tmp[def_name] = "True" elif (match.group(1) == 'undef') and (def_name in defs_tmp): defs_tmp.pop(def_name, None) if debug: print('{1} !!! Define statement({0})'.format( i + 1, line.strip())) continue # for def_tmp, value in defs_tmp.items(): if line.find(def_tmp) >= 0: if debug: print('{1} !!! Macro sub({0}) "{2}" -> "{3}"'.format( i + 1, line.strip(), def_tmp, value)) line = line.replace(def_tmp, value) output_file.append(line) return pp_skips, pp_defines, output_file # if fixed_format: COMMENT_LINE_MATCH = FIXED_COMMENT_LINE_MATCH CONT_REGEX = FIXED_CONT_REGEX else: COMMENT_LINE_MATCH = FREE_COMMENT_LINE_MATCH CONT_REGEX = FREE_CONT_REGEX # file_obj = fortran_file(path) # if pp_defs is not None: if debug: print("=== PreProc Pass ===\n") pp_skips, pp_defines, file_str = preprocess() for pp_reg in pp_skips: file_obj.start_ppif(pp_reg[0]) file_obj.end_ppif(pp_reg[1]) if debug: print("\n=== Parsing Pass ===\n") else: pp_skips = [] pp_defines = [] # line_number = 0 next_line_num = 1 int_counter = 0 block_counter = 0 do_counter = 0 if_counter = 0 select_counter = 0 block_id_stack = [] next_line = None line_ind = 0 while ((line_ind < len(file_str)) or (next_line is not None)): # Get next line if next_line is None: line = file_str[line_ind] line_ind += 1 else: line = next_line next_line = None line_number = next_line_num next_line_num = line_number + 1 if line == '': continue # Skip empty lines # Skip comment lines match = COMMENT_LINE_MATCH.match(line) if (match is not None): continue do_skip = False for pp_reg in pp_skips: if (line_number >= pp_reg[0]) and (line_number <= pp_reg[1]): do_skip = True break if line_number in pp_defines: do_skip = True if do_skip: continue # Get line label line, line_label = strip_line_label(line) # Merge lines with continuations if fixed_format: if line_ind < len(file_str): next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) while (cont_match is not None and (line_ind < len(file_str))): line = line.rstrip() + next_line[6:].strip() next_line_num += 1 next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) else: line_stripped = strip_strings(line, maintain_len=True) iAmper = line_stripped.find('&') iComm = line_stripped.find('!') if iComm < 0: iComm = iAmper + 1 while (iAmper >= 0 and iAmper < iComm): line_prefix = line[:iAmper] next_line = file_str[line_ind] line_ind += 1 # Skip empty or comment lines match = COMMENT_LINE_MATCH.match(next_line) if (next_line.rstrip() == '') or (match is not None): next_line_num += 1 continue next_stripped = strip_strings(next_line, maintain_len=True) cont_match = CONT_REGEX.match(next_stripped) if cont_match is not None: next_line = next_line[cont_match.end(0):] next_line_num += 1 line = line_prefix.rstrip() + ' ' + next_line.strip() line_stripped = strip_strings(line, maintain_len=True) iAmper = line_stripped.find('&') iComm = line_stripped.find('!') if iComm < 0: iComm = iAmper + 1 next_line = None line = line.rstrip() line_no_comment = line.split('!')[0] # Test for scope end if file_obj.END_SCOPE_WORD is not None: match = END_WORD_REGEX.match(line_no_comment) # Handle end statement if match is not None: end_scope_word = match.group(1) if (end_scope_word is not None) or (match.group(2) == ""): if end_scope_word is not None: end_scope_word = end_scope_word.strip().upper() if ((end_scope_word != file_obj.END_SCOPE_WORD) and (file_obj.current_scope.req_named_end() or (end_scope_word is not None)) and (file_obj.current_scope is not file_obj.none_scope)): file_obj.end_errors.append( [line_number, file_obj.current_scope.sline]) if (file_obj.current_scope.get_type() == 9) and (file_obj.current_scope.type in (3, 4)): file_obj.end_scope(line_number) file_obj.end_scope(line_number) if (debug): print('{1} !!! END "{2}" scope({0})'.format( line_number, line.strip(), end_scope_word)) continue # Look for old-style end of DO loops with line labels if (file_obj.END_SCOPE_WORD == 'DO') and (line_label is not None): did_close = False while (len(block_id_stack) > 0) and (line_label == block_id_stack[-1]): file_obj.end_scope(line_number) block_id_stack.pop() did_close = True if (debug): print('{1} !!! END "DO" scope({0})'.format( line_number, line.strip())) if did_close: continue # Mark contains statement match = CONTAINS_REGEX.match(line_no_comment) if match is not None: err_message = None try: if file_obj.current_scope is None: err_message = "Contains statement without enclosing scope" else: file_obj.current_scope.mark_contains(line_number) except ValueError: err_message = "Multiple contains statements in scope" if err_message is not None: file_obj.parse_errors.append({ "line": line_number, "schar": match.start(1), "echar": match.end(1), "mess": err_message, "sev": 1 }) if (debug): print('{1} !!! CONTAINS statement({0})'.format( line_number, line.strip())) continue # Loop through tests obj_read = None for test in def_tests: obj_read = test(line) if obj_read is not None: break # if obj_read is not None: obj_type = obj_read[0] obj = obj_read[1] if obj_type == 'var': if obj[2] is None: continue link_name = None if obj[0][:3] == 'PRO': if isinstance(file_obj.current_scope, fortran_int): for var_name in obj[2]: file_obj.add_int_member(var_name) if (debug): print( '{1} !!! INTERFACE-PRO statement({0})'.format( line_number, line.strip())) continue i1 = obj[0].find('(') i2 = obj[0].find(')') if i1 > -1 and i2 > -1: link_name = obj[0][i1 + 1:i2] for var_name in obj[2]: link_name = None if var_name.find('=>') > -1: name_split = var_name.split('=>') name_stripped = name_split[0] link_name = name_split[1].split('(')[0].strip() if link_name.lower() == 'null': link_name = None else: name_stripped = var_name.split('=')[0] var_dim_str = None if name_stripped.find('(') > -1: var_dim_str = get_var_dims(name_stripped) name_stripped = name_stripped.split('(')[0].strip() modifiers, dim_str, pass_name = map_keywords(obj[1]) if obj[0][:3] == 'PRO': new_var = fortran_meth(file_obj, line_number, name_stripped, obj[0], modifiers, file_obj.enc_scope_name, link_name, pass_name=pass_name) else: new_var = fortran_obj(file_obj, line_number, name_stripped, obj[0], modifiers, dim_str, file_obj.enc_scope_name, link_name) if var_dim_str is not None: new_var.set_dim(var_dim_str) file_obj.add_variable(new_var) if (debug): print('{1} !!! VARIABLE statement({0})'.format( line_number, line.strip())) elif obj_type == 'mod': new_mod = fortran_module(file_obj, line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_mod, END_MOD_WORD) if (debug): print('{1} !!! MODULE statement({0})'.format( line_number, line.strip())) elif obj_type == 'smod': new_smod = fortran_submodule(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1]) file_obj.add_scope(new_smod, END_SMOD_WORD) if (debug): print('{1} !!! SUBMODULE statement({0})'.format( line_number, line.strip())) elif obj_type == 'prog': new_prog = fortran_program(file_obj, line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_prog, END_PROG_WORD) if (debug): print('{1} !!! PROGRAM statement({0})'.format( line_number, line.strip())) elif obj_type == 'sub': new_sub = fortran_subroutine(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1], obj[2]) file_obj.add_scope(new_sub, END_SUB_WORD) if (debug): print('{1} !!! SUBROUTINE statement({0})'.format( line_number, line.strip())) elif obj_type == 'fun': new_fun = fortran_function(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1], obj[3], return_type=obj[2][0], result_var=obj[2][1]) file_obj.add_scope(new_fun, END_FUN_WORD) if obj[2][0] is not None: new_obj = fortran_obj(file_obj, line_number, obj[0], obj[2][0][0], obj[2][0][1], file_obj.enc_scope_name, None) file_obj.add_variable(new_obj) if (debug): print('{1} !!! FUNCTION statement({0})'.format( line_number, line.strip())) elif obj_type == 'block': name = obj[0] if name is None: block_counter += 1 name = '#BLOCK{0}'.format(block_counter) new_block = fortran_block(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_block, END_BLOCK_WORD, req_container=True) if (debug): print('{1} !!! BLOCK statement({0})'.format( line_number, line.strip())) elif obj_type == 'do': do_counter += 1 name = '#DO{0}'.format(do_counter) if obj[0] != '': block_id_stack.append(obj[0]) new_do = fortran_do(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_do, END_DO_WORD, req_container=True) if (debug): print('{1} !!! DO statement({0})'.format( line_number, line.strip())) elif obj_type == 'where': # Add block if WHERE is not single line if not obj: do_counter += 1 name = '#WHERE{0}'.format(do_counter) new_do = fortran_where(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_do, END_WHERE_WORD, req_container=True) if (debug): print('{1} !!! WHERE statement({0})'.format( line_number, line.strip())) elif obj_type == 'assoc': block_counter += 1 name = '#ASSOC{0}'.format(block_counter) new_assoc = fortran_associate(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_assoc, END_ASSOCIATE_WORD, req_container=True) if (debug): print('{1} !!! ASSOCIATE statement({0})'.format( line_number, line.strip())) elif obj_type == 'if': if_counter += 1 name = '#IF{0}'.format(if_counter) new_if = fortran_if(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_if, END_IF_WORD, req_container=True) if (debug): print('{1} !!! IF statement({0})'.format( line_number, line.strip())) elif obj_type == 'select': select_counter += 1 name = '#SELECT{0}'.format(select_counter) binding_name = None bound_var = None if file_obj.current_scope is not None: if (obj[0] in (3, 4)) and (file_obj.current_scope.get_type() == 9): if file_obj.current_scope.type in (3, 4): file_obj.end_scope(line_number) if file_obj.current_scope is not None: if (obj[0] in (3, 4)) and (file_obj.current_scope.get_type() == 9): if file_obj.current_scope.type == 2: binding_name = file_obj.current_scope.binding_name bound_var = file_obj.current_scope.bound_var new_select = fortran_select(file_obj, line_number, name, obj, file_obj.enc_scope_name) file_obj.add_scope(new_select, END_SELECT_WORD, req_container=True) if binding_name is not None: if obj[0] != 4: bound_var = None new_var = fortran_obj(file_obj, line_number, binding_name, '{0}({1})'.format(obj[2], obj[1]), [], file_obj.enc_scope_name, link_obj=bound_var) file_obj.add_variable(new_var) elif (binding_name is None) and (bound_var is not None): new_var = fortran_obj(file_obj, line_number, bound_var, '{0}({1})'.format(obj[2], obj[1]), [], file_obj.enc_scope_name) file_obj.add_variable(new_var) if (debug): print('{1} !!! SELECT statement({0})'.format( line_number, line.strip())) elif obj_type == 'typ': modifiers, _, _ = map_keywords(obj[2]) new_type = fortran_type(file_obj, line_number, obj[0], modifiers, file_obj.enc_scope_name) if obj[1] is not None: new_type.set_inherit(obj[1]) file_obj.add_scope(new_type, END_TYPED_WORD, req_container=True) if (debug): print('{1} !!! TYPE statement({0})'.format( line_number, line.strip())) elif obj_type == 'enum': block_counter += 1 name = '#ENUM{0}'.format(block_counter) new_enum = fortran_enum(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_enum, END_ENUMD_WORD, req_container=True) if (debug): print('{1} !!! ENUM statement({0})'.format( line_number, line.strip())) elif obj_type == 'int': abstract = obj[1] name = obj[0] if name is None: int_counter += 1 name = '#GEN_INT{0}'.format(int_counter) new_int = fortran_int(file_obj, line_number, name, file_obj.enc_scope_name, abstract) file_obj.add_scope(new_int, END_INT_WORD, req_container=True) if (debug): print('{1} !!! INTERFACE statement({0})'.format( line_number, line.strip())) elif obj_type == 'gen': name = obj[0] new_int = fortran_int(file_obj, line_number, name, file_obj.enc_scope_name, False) file_obj.add_scope(new_int, END_INT_WORD, req_container=True) for pro_link in obj[1]: file_obj.add_int_member(pro_link) file_obj.end_scope(line_number) if (debug): print('{1} !!! GENERIC statement({0})'.format( line_number, line.strip())) elif obj_type == 'int_pro': if file_obj.current_scope is None: continue if not isinstance(file_obj.current_scope, fortran_int): continue for name in obj: file_obj.add_int_member(name) if (debug): print('{1} !!! INTERFACE-PRO statement({0})'.format( line_number, line.strip())) elif obj_type == 'use': file_obj.add_use(obj[0], line_number, obj[1]) if (debug): print('{1} !!! USE statement({0})'.format( line_number, line.strip())) elif obj_type == 'inc': file_obj.add_include(obj[0], line_number) if (debug): print('{1} !!! INCLUDE statement({0})'.format( line_number, line.strip())) elif obj_type == 'vis': if (len(obj[1]) == 0) and (obj[0] == 1): file_obj.current_scope.set_default_vis(-1) else: if obj[0] == 1: for word in obj[1]: file_obj.add_private(word) else: for word in obj[1]: file_obj.add_public(word) if (debug): print('{1} !!! Visiblity statement({0})'.format( line_number, line.strip())) file_obj.close_file(line_number) return file_obj
def process_file(file_str, close_open_scopes, fixed_format=False, debug=False): # if fixed_format: COMMENT_LINE_MATCH = FIXED_COMMENT_LINE_MATCH CONT_REGEX = FIXED_CONT_REGEX else: COMMENT_LINE_MATCH = FREE_COMMENT_LINE_MATCH CONT_REGEX = FREE_CONT_REGEX # file_obj = fortran_file() line_number = 0 next_line_num = 1 int_counter = 0 # at_eof = False next_line = None line_ind = 0 while (line_ind < len(file_str)): # Get next line if next_line is None: line = file_str[line_ind] line_ind += 1 else: line = next_line next_line = None line_number = next_line_num next_line_num = line_number + 1 if line == '': continue # Skip empty lines # Skip comment lines match = COMMENT_LINE_MATCH.match(line) if (match is not None): continue # Merge lines with continuations if fixed_format: if line_ind < len(file_str): next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) while (cont_match is not None and (line_ind < len(file_str))): line = line.rstrip() + next_line[6:].strip() next_line_num += 1 next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) else: iAmper = line.find('&') iComm = line.find('!') if iComm < 0: iComm = iAmper + 1 while (iAmper >= 0 and iAmper < iComm): split_line = line.split('&') next_line = file_str[line_ind] line_ind += 1 if next_line == '': break # Next line is empty # at_eof = True # break # Reached end of file # Skip comment lines match = COMMENT_LINE_MATCH.match(next_line) if (match is not None): continue cont_match = CONT_REGEX.match(next_line) if cont_match is not None: next_line = next_line[cont_match.end(0):] next_line_num += 1 line = split_line[0].rstrip() + ' ' + next_line.strip() iAmper = line.find('&') iComm = line.find('!') if iComm < 0: iComm = iAmper + 1 next_line = None line = line.rstrip() # Test for scope end if file_obj.END_REGEX is not None: match = file_obj.END_REGEX.match(line) if (match is not None): file_obj.end_scope(line_number) if (debug): print('{1} !!! END scope({0})'.format( line_number, line.strip())) continue line_no_comment = line.split('!')[0] match = END_GEN_REGEX.match(line_no_comment) if (match is not None): file_obj.end_scope(line_number) if (debug): print('{1} !!! END scope({0})'.format( line_number, line.strip())) continue # Loop through tests obj_read = None for test in def_tests: obj_read = test(line) if obj_read is not None: break # if obj_read is not None: obj_type = obj_read[0] obj = obj_read[1] if obj_type == 'var': link_name = None if obj[0][:3] == 'PRO': if isinstance(file_obj.current_scope, fortran_int): for var_name in obj[2]: file_obj.add_int_member(var_name) if (debug): print( '{1} !!! INTERFACE-PRO statement({0})'.format( line_number, line.strip())) continue i1 = obj[0].find('(') i2 = obj[0].find(')') if i1 > -1 and i2 > -1: link_name = obj[0][i1 + 1:i2] for var_name in obj[2]: if var_name.find('=>') > -1: name_split = var_name.split('=>') name_stripped = name_split[0] link_name = name_split[1].split('(')[0].strip() if link_name.lower() == 'null': link_name = None else: name_stripped = var_name.split('=')[0] var_dim = 0 if name_stripped.find('(') > -1: var_dim = get_var_dims(name_stripped) name_stripped = name_stripped.split('(')[0].strip() modifiers = parse_keywords(obj[1]) if obj[0][:3] == 'PRO': new_var = fortran_meth(line_number, name_stripped, obj[0], modifiers, file_obj.enc_scope_name, link_name) else: new_var = fortran_obj(line_number, name_stripped, obj[0], modifiers, file_obj.enc_scope_name, link_name) if var_dim > 0: new_var.set_dim(var_dim) file_obj.add_variable(new_var) if (debug): print('{1} !!! VARIABLE statement({0})'.format( line_number, line.strip())) elif obj_type == 'mod': new_mod = fortran_module(line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_mod, END_MOD_REGEX) if (debug): print('{1} !!! MODULE statement({0})'.format( line_number, line.strip())) elif obj_type == 'prog': new_prog = fortran_program(line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_prog, END_PROG_REGEX) if (debug): print('{1} !!! PROGRAM statement({0})'.format( line_number, line.strip())) elif obj_type == 'sub': new_sub = fortran_subroutine(line_number, obj[0], file_obj.enc_scope_name, obj[1]) file_obj.add_scope(new_sub, END_SUB_REGEX) if (debug): print('{1} !!! SUBROUTINE statement({0})'.format( line_number, line.strip())) elif obj_type == 'fun': new_fun = fortran_function(line_number, obj[0], file_obj.enc_scope_name, obj[1], return_type=obj[2][0], result_var=obj[2][1]) file_obj.add_scope(new_fun, END_FUN_REGEX) if obj[2][0] is not None: new_obj = fortran_obj(line_number, obj[0], obj[2][0][0], obj[2][0][1], file_obj.enc_scope_name, None) file_obj.add_variable(new_obj) if (debug): print('{1} !!! FUNCTION statement({0})'.format( line_number, line.strip())) elif obj_type == 'typ': modifiers = parse_keywords(obj[2]) new_type = fortran_type(line_number, obj[0], modifiers, file_obj.enc_scope_name) if obj[1] is not None: new_type.set_inherit(obj[1]) file_obj.add_scope(new_type, END_TYPED_REGEX) if (debug): print('{1} !!! TYPE statement({0})'.format( line_number, line.strip())) elif obj_type == 'int': if obj is None: int_counter += 1 obj = 'GEN_INT{0}'.format(int_counter) new_int = fortran_int(line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_int, END_INT_REGEX, True) if (debug): print('{1} !!! INTERFACE statement({0})'.format( line_number, line.strip())) elif obj_type == 'int_pro': if file_obj.current_scope is None: continue if not isinstance(file_obj.current_scope, fortran_int): continue for name in obj: file_obj.add_int_member(name) if (debug): print('{1} !!! INTERFACE-PRO statement({0})'.format( line_number, line.strip())) elif obj_type == 'use': file_obj.current_scope.add_use(obj[0], line_number, obj[1]) if (debug): print('{1} !!! USE statement({0})'.format( line_number, line.strip())) # Look for visiblity statement match = VIS_REGEX.match(line) if (match is not None): match_lower = match.group(0).lower() trailing_line = line[match.end(0):] mod_words = WORD_REGEX.findall(trailing_line) if len(mod_words) == 0: if match_lower == 'private': file_obj.current_scope.set_default_vis(-1) else: if match_lower == 'private': for word in mod_words: file_obj.add_private(word) else: for word in mod_words: file_obj.add_public(word) if (debug): print('{1} !!! Visiblity statement({0})'.format( line_number, line.strip())) continue file_obj.close_file() return file_obj
def process_file(file_str, close_open_scopes, path=None, fixed_format=False, debug=False): # if fixed_format: COMMENT_LINE_MATCH = FIXED_COMMENT_LINE_MATCH CONT_REGEX = FIXED_CONT_REGEX else: COMMENT_LINE_MATCH = FREE_COMMENT_LINE_MATCH CONT_REGEX = FREE_CONT_REGEX # file_obj = fortran_file(path) line_number = 0 next_line_num = 1 int_counter = 0 block_counter = 0 select_counter = 0 # at_eof = False next_line = None line_ind = 0 while((line_ind < len(file_str)) or (next_line is not None)): # Get next line if next_line is None: line = file_str[line_ind] line_ind += 1 else: line = next_line next_line = None line_number = next_line_num next_line_num = line_number + 1 if line == '': continue # Skip empty lines # Skip comment lines match = COMMENT_LINE_MATCH.match(line) if (match is not None): continue # Start preproccesor if stmt match = PPIF_START_TEST.match(line) if (match is not None): file_obj.start_ppif(line_number) continue # End preproccesor if stmt match = PPIF_END_TEST.match(line) if (match is not None): file_obj.end_ppif(line_number) continue # Merge lines with continuations if fixed_format: if line_ind < len(file_str): next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) while(cont_match is not None and (line_ind < len(file_str))): line = line.rstrip() + next_line[6:].strip() next_line_num += 1 next_line = file_str[line_ind] line_ind += 1 cont_match = CONT_REGEX.match(next_line) else: iAmper = line.find('&') iComm = line.find('!') if iComm < 0: iComm = iAmper + 1 while (iAmper >= 0 and iAmper < iComm): split_line = line.split('&') next_line = file_str[line_ind] line_ind += 1 if next_line == '': break # Next line is empty # at_eof = True # break # Reached end of file # Skip comment lines match = COMMENT_LINE_MATCH.match(next_line) if (match is not None): continue cont_match = CONT_REGEX.match(next_line) if cont_match is not None: next_line = next_line[cont_match.end(0):] next_line_num += 1 line = split_line[0].rstrip() + ' ' + next_line.strip() iAmper = line.find('&') iComm = line.find('!') if iComm < 0: iComm = iAmper + 1 next_line = None line = line.rstrip() # Test for scope end if file_obj.END_REGEX is not None: match = file_obj.END_REGEX.match(line) if (match is not None): if (file_obj.current_scope.get_type() == 9) and (file_obj.current_scope.type in (3, 4)): file_obj.end_scope(line_number) file_obj.end_scope(line_number) if(debug): print('{1} !!! END scope({0})'.format(line_number, line.strip())) continue line_no_comment = line.split('!')[0] match = END_GEN_REGEX.match(line_no_comment) if (match is not None): file_obj.end_scope(line_number) if(debug): print('{1} !!! END scope({0})'.format(line_number, line.strip())) continue # Loop through tests obj_read = None for test in def_tests: obj_read = test(line) if obj_read is not None: break # if obj_read is not None: obj_type = obj_read[0] obj = obj_read[1] if obj_type == 'var': if obj[2] is None: continue link_name = None if obj[0][:3] == 'PRO': if isinstance(file_obj.current_scope, fortran_int): for var_name in obj[2]: file_obj.add_int_member(var_name) if(debug): print('{1} !!! INTERFACE-PRO statement({0})'.format(line_number, line.strip())) continue i1 = obj[0].find('(') i2 = obj[0].find(')') if i1 > -1 and i2 > -1: link_name = obj[0][i1+1:i2] for var_name in obj[2]: link_name = None if var_name.find('=>') > -1: name_split = var_name.split('=>') name_stripped = name_split[0] link_name = name_split[1].split('(')[0].strip() if link_name.lower() == 'null': link_name = None else: name_stripped = var_name.split('=')[0] var_dim_str = None if name_stripped.find('(') > -1: var_dim_str = get_var_dims(name_stripped) name_stripped = name_stripped.split('(')[0].strip() modifiers, dim_str, pass_name = map_keywords(obj[1]) if obj[0][:3] == 'PRO': new_var = fortran_meth(file_obj, line_number, name_stripped, obj[0], modifiers, file_obj.enc_scope_name, link_name, pass_name=pass_name) else: new_var = fortran_obj(file_obj, line_number, name_stripped, obj[0], modifiers, dim_str, file_obj.enc_scope_name, link_name) if var_dim_str is not None: new_var.set_dim(var_dim_str) file_obj.add_variable(new_var) if(debug): print('{1} !!! VARIABLE statement({0})'.format(line_number, line.strip())) elif obj_type == 'mod': new_mod = fortran_module(file_obj, line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_mod, END_MOD_REGEX) if(debug): print('{1} !!! MODULE statement({0})'.format(line_number, line.strip())) elif obj_type == 'smod': new_smod = fortran_submodule(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1]) file_obj.add_scope(new_smod, END_SMOD_REGEX) if(debug): print('{1} !!! SUBMODULE statement({0})'.format(line_number, line.strip())) elif obj_type == 'prog': new_prog = fortran_program(file_obj, line_number, obj, file_obj.enc_scope_name) file_obj.add_scope(new_prog, END_PROG_REGEX) if(debug): print('{1} !!! PROGRAM statement({0})'.format(line_number, line.strip())) elif obj_type == 'sub': new_sub = fortran_subroutine(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1], obj[2]) file_obj.add_scope(new_sub, END_SUB_REGEX) if(debug): print('{1} !!! SUBROUTINE statement({0})'.format(line_number, line.strip())) elif obj_type == 'fun': new_fun = fortran_function(file_obj, line_number, obj[0], file_obj.enc_scope_name, obj[1], obj[3], return_type=obj[2][0], result_var=obj[2][1]) file_obj.add_scope(new_fun, END_FUN_REGEX) if obj[2][0] is not None: new_obj = fortran_obj(file_obj, line_number, obj[0], obj[2][0][0], obj[2][0][1], file_obj.enc_scope_name, None) file_obj.add_variable(new_obj) if(debug): print('{1} !!! FUNCTION statement({0})'.format(line_number, line.strip())) elif obj_type == 'block': name = obj[0] if name is None: block_counter += 1 name = '#BLOCK{0}'.format(block_counter) new_block = fortran_block(file_obj, line_number, name, file_obj.enc_scope_name) file_obj.add_scope(new_block, END_BLOCK_REGEX, req_container=True) if(debug): print('{1} !!! BLOCK statement({0})'.format(line_number, line.strip())) elif obj_type == 'select': select_counter += 1 name = '#SELECT{0}'.format(select_counter) binding_name = None bound_var = None if file_obj.current_scope is not None: if (obj[0] in (3, 4)) and (file_obj.current_scope.get_type() == 9): if file_obj.current_scope.type in (3, 4): file_obj.end_scope(line_number) if file_obj.current_scope is not None: if (obj[0] in (3, 4)) and (file_obj.current_scope.get_type() == 9): if file_obj.current_scope.type == 2: binding_name = file_obj.current_scope.binding_name bound_var = file_obj.current_scope.bound_var new_select = fortran_select(file_obj, line_number, name, obj, file_obj.enc_scope_name) file_obj.add_scope(new_select, END_SELECT_REGEX, req_container=True) if binding_name is not None: if obj[0] != 4: bound_var = None new_var = fortran_obj(file_obj, line_number, binding_name, '{0}({1})'.format(obj[2], obj[1]), [], file_obj.enc_scope_name, link_obj=bound_var) file_obj.add_variable(new_var) elif (binding_name is None) and (bound_var is not None): new_var = fortran_obj(file_obj, line_number, bound_var, '{0}({1})'.format(obj[2], obj[1]), [], file_obj.enc_scope_name) file_obj.add_variable(new_var) if(debug): print('{1} !!! SELECT statement({0})'.format(line_number, line.strip())) elif obj_type == 'typ': modifiers, _, _ = map_keywords(obj[2]) new_type = fortran_type(file_obj, line_number, obj[0], modifiers, file_obj.enc_scope_name) if obj[1] is not None: new_type.set_inherit(obj[1]) file_obj.add_scope(new_type, END_TYPED_REGEX, req_container=True) if(debug): print('{1} !!! TYPE statement({0})'.format(line_number, line.strip())) elif obj_type == 'int': abstract = obj[1] name = obj[0] if name is None: int_counter += 1 name = '#GEN_INT{0}'.format(int_counter) new_int = fortran_int(file_obj, line_number, name, file_obj.enc_scope_name, abstract) file_obj.add_scope(new_int, END_INT_REGEX, req_container=True) if(debug): print('{1} !!! INTERFACE statement({0})'.format(line_number, line.strip())) elif obj_type == 'int_pro': if file_obj.current_scope is None: continue if not isinstance(file_obj.current_scope, fortran_int): continue for name in obj: file_obj.add_int_member(name) if(debug): print('{1} !!! INTERFACE-PRO statement({0})'.format(line_number, line.strip())) elif obj_type == 'use': file_obj.add_use(obj[0], line_number, obj[1]) if(debug): print('{1} !!! USE statement({0})'.format(line_number, line.strip())) elif obj_type == 'inc': file_obj.add_include(obj[0], line_number) if(debug): print('{1} !!! INCLUDE statement({0})'.format(line_number, line.strip())) # Look for visiblity statement match = VIS_REGEX.match(line) if (match is not None): match_lower = match.group(0).lower() trailing_line = line[match.end(0):] mod_words = WORD_REGEX.findall(trailing_line) if len(mod_words) == 0: if match_lower == 'private': file_obj.current_scope.set_default_vis(-1) else: if match_lower == 'private': for word in mod_words: file_obj.add_private(word) else: for word in mod_words: file_obj.add_public(word) if(debug): print('{1} !!! Visiblity statement({0})'.format(line_number, line.strip())) continue file_obj.close_file(line_number) return file_obj