1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
"""
Various utility functions.
-----
Permission to use, modify, and distribute this software is given under the
terms of the NumPy License. See http://scipy.org.
NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
Author: Pearu Peterson <pearu@cens.ioc.ee>
Created: May 2006
-----
"""
__all__ = ['split_comma', 'specs_split_comma',
'ParseError','AnalyzeError',
'get_module_file','parse_bind','parse_result','is_name','parse_array_spec',
'CHAR_BIT','str2stmt']
import re
import os, glob
class ParseError(Exception):
pass
class AnalyzeError(Exception):
pass
is_name = re.compile(r'^[a-z_]\w*$',re.I).match
name_re = re.compile(r'[a-z_]\w*',re.I).match
is_entity_decl = re.compile(r'^[a-z_]\w*',re.I).match
is_int_literal_constant = re.compile(r'^\d+(_\w+|)$').match
def split_comma(line, item = None, comma=',', keep_empty=False):
items = []
if item is None:
for s in line.split(comma):
s = s.strip()
if not s and not keep_empty: continue
items.append(s)
return items
newitem = item.copy(line, True)
apply_map = newitem.apply_map
for s in newitem.get_line().split(comma):
s = apply_map(s).strip()
if not s and not keep_empty: continue
items.append(s)
return items
def parse_array_spec(line, item = None):
items = []
for spec in split_comma(line, item):
items.append(tuple(split_comma(spec, item, comma=':', keep_empty=True)))
return items
def specs_split_comma(line, item = None, upper=False):
specs0 = split_comma(line, item)
specs = []
for spec in specs0:
i = spec.find('=')
if i!=-1:
kw = spec[:i].strip().upper()
v = spec[i+1:].strip()
specs.append('%s = %s' % (kw, v))
else:
if upper:
spec = spec.upper()
specs.append(spec)
return specs
def parse_bind(line, item = None):
if not line.lower().startswith('bind'):
return None, line
if item is not None:
newitem = item.copy(line, apply_map=True)
newline = newitem.get_line()
else:
newitem = None
newline = newline[4:].lstrip()
i = newline.find(')')
assert i!=-1,`newline`
args = []
for a in specs_split_comma(newline[1:i].strip(), newitem, upper=True):
args.append(a)
rest = newline[i+1:].lstrip()
if item is not None:
rest = newitem.apply_map(rest)
return args, rest
def parse_result(line, item = None):
if not line.lower().startswith('result'):
return None, line
line = line[6:].lstrip()
i = line.find(')')
assert i != -1,`line`
name = line[1:i].strip()
assert is_name(name),`name`
return name, line[i+1:].lstrip()
def filter_stmts(content, classes):
""" Pop and return classes instances from content.
"""
stmts = []
indices = []
for i in range(len(content)):
stmt = content[i]
if isinstance(stmt, classes):
stmts.append(stmt)
indices.append(i)
indices.reverse()
for i in indices:
del content[i]
return stmts
def get_module_files(directory, _cache={}):
if directory in _cache:
return _cache[directory]
module_line = re.compile(r'(\A|^)module\s+(?P<name>\w+)\s*(!.*|)$',re.I | re.M)
d = {}
for fn in glob.glob(os.path.join(directory,'*.f90')):
f = open(fn,'r')
for name in module_line.findall(f.read()):
name = name[1]
if name in d:
print d[name],'already defines',name
continue
d[name] = fn
_cache[directory] = d
return d
def get_module_file(name, directory, _cache={}):
fn = _cache.get(name, None)
if fn is not None:
return fn
if name.endswith('_module'):
f1 = os.path.join(directory,name[:-7]+'.f90')
if os.path.isfile(f1):
_cache[name] = fn
return f1
pattern = re.compile(r'\s*module\s+(?P<name>[a-z]\w*)', re.I).match
for fn in glob.glob(os.path.join(directory,'*.f90')):
f = open(fn,'r')
for line in f:
m = pattern(line)
if m and m.group('name')==name:
_cache[name] = fn
f.close()
return fn
f.close()
return
def str2stmt(string, isfree=True, isstrict=False):
""" Convert Fortran code to Statement tree.
"""
from readfortran import Line, FortranStringReader
from parsefortran import FortranParser
reader = FortranStringReader(string, isfree, isstrict)
parser = FortranParser(reader)
parser.parse()
parser.analyze()
block = parser.block
while len(block.content)==1:
block = block.content[0]
return block
def get_char_bit():
import numpy
one = numpy.ubyte(1)
two = numpy.ubyte(2)
n = numpy.ubyte(2)
i = 1
while n>=two:
n <<= one
i += 1
return i
CHAR_BIT = get_char_bit()
|