重构3
This commit is contained in:
+73
-13
@@ -25,13 +25,54 @@ def extract_commons(content):
|
||||
commons = re.findall(r'(?i)^\s*COMMON\s*/(\w+)/', content, re.MULTILINE)
|
||||
return list(set(commons))
|
||||
|
||||
def extract_calls(content):
|
||||
"""提取 CALL 语句调用的子程序"""
|
||||
calls = re.findall(r'(?i)CALL\s+(\w+)\s*\(', content)
|
||||
# 也提取函数调用 ( FUNCTION 形式 )
|
||||
funcs = re.findall(r'(?i)^\s*(?:REAL|INTEGER|DOUBLE\s*PRECISION)?\s*FUNCTION\s+(\w+)', content, re.MULTILINE)
|
||||
# 统一转为大写
|
||||
return list(set(c.upper() for c in calls + funcs))
|
||||
# Fortran 内置函数列表(不需要追踪)
|
||||
FORTRAN_INTRINSICS = {
|
||||
'SIN', 'COS', 'TAN', 'ASIN', 'ACOS', 'ATAN', 'ATAN2',
|
||||
'SINH', 'COSH', 'TANH',
|
||||
'EXP', 'LOG', 'LOG10', 'LOG2',
|
||||
'SQRT', 'ABS', 'MOD', 'SIGN',
|
||||
'MAX', 'MIN', 'MAX0', 'MIN0', 'MAX1', 'MIN1', 'AMAX0', 'AMIN0',
|
||||
'INT', 'IFIX', 'IDINT', 'FLOAT', 'SNGL', 'DBLE', 'CMPLX',
|
||||
'REAL', 'AIMAG', 'CONJG',
|
||||
'ICHAR', 'CHAR', 'INDEX', 'LEN', 'LGE', 'LGT', 'LLE', 'LLT',
|
||||
'DOT_PRODUCT', 'MATMUL', 'TRANSPOSE', 'RESHAPE',
|
||||
'SIZE', 'SHAPE', 'LBOUND', 'UBOUND',
|
||||
'ALLOCATED', 'ALLOCATE', 'DEALLOCATE',
|
||||
'KIND', 'SELECTED_REAL_KIND', 'SELECTED_INT_KIND',
|
||||
'DIGITS', 'EPSILON', 'HUGE', 'TINY', 'PRECISION', 'RANGE',
|
||||
'FLOOR', 'CEILING', 'NINT', 'ANINT',
|
||||
'ADJUSTL', 'ADJUSTR', 'TRIM', 'REPEAT', 'SCAN', 'VERIFY',
|
||||
'PRESENT', 'ASSOCIATED',
|
||||
# TLUSTY 常用数学函数
|
||||
'ERF', 'ERFC', 'GAMMA', 'LOG_GAMMA',
|
||||
}
|
||||
|
||||
def extract_calls(content, known_functions=None):
|
||||
"""提取 CALL 语句和 FUNCTION 调用
|
||||
|
||||
Args:
|
||||
content: Fortran 源码
|
||||
known_functions: 已知的函数名集合(用于区分函数调用和数组访问)
|
||||
"""
|
||||
calls = set()
|
||||
|
||||
# 1. 提取 CALL 语句(支持有括号和无括号两种形式)
|
||||
# CALL NAME(...) 或 CALL NAME
|
||||
call_stmts = re.findall(r'(?i)CALL\s+(\w+)(?:\s*\(|\s*$|\s*\n)', content)
|
||||
calls.update(c.upper() for c in call_stmts)
|
||||
|
||||
# 2. 提取可能的 FUNCTION 调用
|
||||
if known_functions:
|
||||
# 只匹配已知函数名
|
||||
func_assign = re.findall(r'(?i)=\s*([A-Z][A-Z0-9]*)\s*\(', content)
|
||||
calls.update(f.upper() for f in func_assign
|
||||
if f.upper() in known_functions and f.upper() not in FORTRAN_INTRINSICS)
|
||||
|
||||
func_expr = re.findall(r'(?i)[=(,]\s*([A-Z][A-Z0-9]*)\s*\(', content)
|
||||
calls.update(f.upper() for f in func_expr
|
||||
if f.upper() in known_functions and f.upper() not in FORTRAN_INTRINSICS)
|
||||
|
||||
return list(calls)
|
||||
|
||||
def has_file_io(content):
|
||||
"""检查是否有文件 I/O"""
|
||||
@@ -86,6 +127,12 @@ SPECIAL_MAPPINGS = {
|
||||
'erfcx': ['erfcx', 'erfcin'],
|
||||
'lineqs': ['lineqs', 'lineqs_nr'],
|
||||
'gamsp': ['gamsp'], # alias
|
||||
'bhe': ['bhe', 'bhed', 'bhez'], # 流体静力学平衡方程
|
||||
'comset': ['comset'], # Compton 散射参数设置
|
||||
'ghydop': ['ghydop'], # 氢不透明度 (Gomez 表)
|
||||
'levgrp': ['levgrp'], # 能级分组
|
||||
'profil': ['profil'], # 标准吸收轮廓
|
||||
'linspl': ['linspl'], # 谱线轮廓设置
|
||||
}
|
||||
|
||||
def find_rust_module(fortran_name, rust_dir):
|
||||
@@ -247,10 +294,20 @@ def main():
|
||||
extracted_dir = "/home/fmq/program/tlusty/tl208-s54/rust/tlusty/extracted"
|
||||
rust_dir = "/home/fmq/program/tlusty/tl208-s54/rust/src/math"
|
||||
|
||||
# 收集所有单元信息
|
||||
units_dict = {}
|
||||
# 第一遍:收集所有已定义的 SUBROUTINE 和 FUNCTION 名称
|
||||
all_defined_units = set()
|
||||
fortran_files = sorted(glob.glob(os.path.join(extracted_dir, "*.f")))
|
||||
|
||||
for fpath in fortran_files:
|
||||
with open(fpath, 'r', encoding='utf-8', errors='ignore') as f:
|
||||
content = f.read()
|
||||
units = extract_unit_info(content, os.path.basename(fpath))
|
||||
for unit_type, unit_name in units:
|
||||
all_defined_units.add(unit_name)
|
||||
|
||||
# 第二遍:收集所有单元信息(使用已知函数名来过滤调用)
|
||||
units_dict = {}
|
||||
|
||||
for fpath in fortran_files:
|
||||
fname = os.path.basename(fpath)
|
||||
base_name = os.path.splitext(fname)[0]
|
||||
@@ -260,7 +317,7 @@ def main():
|
||||
|
||||
includes = extract_includes(content)
|
||||
commons = extract_commons(content)
|
||||
calls = extract_calls(content)
|
||||
calls = extract_calls(content, known_functions=all_defined_units)
|
||||
io = has_file_io(content)
|
||||
units = extract_unit_info(content, fname)
|
||||
|
||||
@@ -315,6 +372,9 @@ def main():
|
||||
for unit_name, unit in units_dict.items():
|
||||
if unit['status'] == 'done':
|
||||
continue
|
||||
# 跳过无法识别程序单元的文件(如纯注释文件)
|
||||
if unit['unit_type'] == 'UNKNOWN':
|
||||
continue
|
||||
|
||||
depth = calculate_depth(unit_name, units_dict, memo)
|
||||
trans_calls = len(get_transitive_deps(unit_name, units_dict))
|
||||
@@ -335,10 +395,10 @@ def main():
|
||||
'is_pure': unit['is_pure'],
|
||||
})
|
||||
|
||||
# 按优先级排序:未实现依赖少 > 深度低 > 无IO
|
||||
priority_list.sort(key=lambda x: (x['trans_pending'], x['depth'], x['trans_calls'], x['has_io']))
|
||||
# 按优先级排序:无IO > 未实现依赖少 > 深度低
|
||||
priority_list.sort(key=lambda x: (x['has_io'], x['trans_pending'], x['depth'], x['trans_calls']))
|
||||
|
||||
print("重构优先级列表 (按未实现依赖排序)")
|
||||
print("重构优先级列表 (优先无IO,按未实现依赖排序)")
|
||||
print("=" * 100)
|
||||
print(f"{'单元名':<20} {'未实现':>6} {'传递未实现':>10} {'深度':>4} {'直接调用':>8} {'传递调用':>8} {'IO':>4}")
|
||||
print("-" * 100)
|
||||
|
||||
Reference in New Issue
Block a user