1
2 """Parameter file is read into memory and modified there"""
3
4 from FileBasis import FileBasisBackup
5 from PyFoam.Basics.PlyParser import PlyParser
6 from PyFoam.Basics.FoamFileGenerator import FoamFileGenerator
7
8 from PyFoam.Basics.DataStructures import Vector,Field,Dimension,DictProxy,TupleProxy,Tensor,SymmTensor,Unparsed,UnparsedList
9
11 """ Parameterfile whose complete representation is read into
12 memory, can be manipulated and afterwards written to disk"""
13
14 - def __init__(self,name,backup=False,debug=False,boundaryDict=False,listLengthUnparsed=None):
15 """@param name: The name of the parameter file
16 @param backup: create a backup-copy of the file
17 @param boundaryDict: the file to parse is a boundary file
18 @param listLengthUnparsed: Lists longer than that length are not parsed"""
19
20 FileBasisBackup.__init__(self,name,backup=backup)
21 self.debug=debug
22 self.boundaryDict=boundaryDict
23 self.listLengthUnparsed=listLengthUnparsed
24
25 self.header=None
26 self.content=None
27
28 self.readFile()
29
39
41 return key in self.content
42
44 return self.content[key]
45
47 self.content[key]=value
48
50 """Generates a string from the contents in memory
51 Used to be called makeString"""
52
53 string="// File generated by PyFoam - sorry for the ugliness\n\n"
54
55 generator=FoamFileGenerator(self.content,header=self.header)
56 string+=str(generator)
57
58 return string
59
61 """Class that parses a string that contains the contents of an
62 OpenFOAM-file and builds a nested structure of directories and
63 lists from it"""
64
65 - def __init__(self,content,debug=False,noHeader=False,boundaryDict=False,listLengthUnparsed=None):
66 """@param content: the string to be parsed
67 @param debug: output debug information during parsing
68 @param noHeader: switch that turns off the parsing of the header"""
69
70 self.data=None
71 self.header=None
72 self.debug=debug
73 self.listLengthUnparsed=listLengthUnparsed
74
75 if noHeader:
76 self.start='noHeader'
77
78 if boundaryDict:
79 self.start='boundaryDict'
80
81 PlyParser.__init__(self,debug=debug)
82
83
84
85
86 self.header,self.data=self.parse(content)
87
90
93
95 """ Get the data structure"""
96 return self.data
97
99 """ Get the OpenFOAM-header"""
100 return self.header
101
102 - def printContext(self,c,ind):
103 """Prints the context of the current index"""
104 print "------"
105 print c[max(0,ind-100):max(0,ind-1)]
106 print "------"
107 print ">",c[ind-1],"<"
108 print "------"
109 print c[min(len(c),ind):min(len(c),ind+100)]
110 print "------"
111
113 """Prints the error message of the parser and exit"""
114 print "PARSER ERROR:",text
115 print "On index",ind
116 self.printContext(c,ind)
117 raise PyFoamParserError("Unspecified")
118
119 tokens = (
120 'NAME',
121 'ICONST',
122 'FCONST',
123 'SCONST',
124 'FOAMFILE',
125 'UNIFORM',
126 'NONUNIFORM',
127 'UNPARSEDCHUNK',
128 )
129
130 reserved = {
131 'FoamFile' : 'FOAMFILE',
132 'uniform' : 'UNIFORM',
133 'nonuniform' : 'NONUNIFORM',
134 }
135
136 states = (
137 ('unparsed', 'exclusive'),
138 )
139
141 r'\('
142 t.lexer.level+=1
143
144
146 r'\)'
147 t.lexer.level-=1
148
149 if t.lexer.level < 0 :
150 t.value = t.lexer.lexdata[t.lexer.code_start:t.lexer.lexpos-1]
151
152 t.lexer.lexpos-=1
153 t.type = "UNPARSEDCHUNK"
154 t.lexer.lineno += t.value.count('\n')
155 t.lexer.begin('INITIAL')
156 return t
157
158 t_unparsed_ignore = ' \t\n0123456789.-e'
159
161 print "Error",t.lexer.lexdata[t.lexer.lexpos]
162 t.lexer.skip(1)
163
174
175 t_ICONST = r'(-|)\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'
176
177 t_FCONST = r'(-|)((\d+)(\.\d*)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
178
179 t_SCONST = r'\"([^\\\n]|(\\.))*?\"'
180
181 literals = "(){};[]"
182
183 t_ignore=" \t"
184
185
189
190
195
196
198 print "Illegal character '%s'" % t.value[0]
199 t.lexer.skip(1)
200
202 'global : header dictbody'
203 p[0] = ( p[1] , p[2] )
204
206 'noHeader : dictbody'
207 p[0] = ( None , p[1] )
208
210 '''boundaryDict : header list
211 | header prelist '''
212
213 p[0] = ( p[1] , p[2] )
214
216 'header : FOAMFILE dictionary'
217 p[0] = p[2]
218
220 '''integer : ICONST'''
221 p[0] = int(p[1])
222
224 '''integer : FCONST'''
225 p[0] = float(p[1])
226
228 '''dictionary : '{' dictbody '}'
229 | '{' '}' '''
230 if len(p)==4:
231 p[0] = p[2]
232 else:
233 p[0] = DictProxy()
234
235 - def p_dictbody(self,p):
236 '''dictbody : dictbody dictline
237 | dictline
238 | empty'''
239
240 if len(p)==3:
241 p[0]=p[1]
242 p[0][p[2][0]]=p[2][1]
243 else:
244 if p[1]:
245 p[0]=DictProxy()
246 p[0][p[1][0]]=p[1][1]
247 else:
248 p[0]=DictProxy()
249
251 '''list : '(' itemlist ')' '''
252 p[0] = p[2]
253 if len(p[2])==3 or len(p[2])==9 or len(p[2])==6:
254 isVector=True
255 for i in p[2]:
256 try:
257 float(i)
258 except:
259 isVector=False
260 if isVector:
261 if len(p[2])==3:
262 p[0]=apply(Vector,p[2])
263 elif len(p[2])==9:
264 p[0]=apply(Tensor,p[2])
265 else:
266 p[0]=apply(SymmTensor,p[2])
267
269 '''unparsed : UNPARSEDCHUNK'''
270 p[0] = Unparsed(p[1])
271
273 '''prelist_seen : '''
274 if self.listLengthUnparsed!=None:
275
276 if int(p[-1])>=self.listLengthUnparsed:
277
278 p.lexer.begin('unparsed')
279 p.lexer.level=0
280 p.lexer.code_start = p.lexer.lexpos
281
282
283
284
285
286
287
289 '''prelist : integer prelist_seen '(' itemlist ')'
290 | integer prelist_seen '(' unparsed ')' '''
291 if type(p[4])==Unparsed:
292 p[0] = UnparsedList(int(p[1]),p[4].data)
293 else:
294 p[0] = p[4]
295
297 '''itemlist : itemlist item
298 | item '''
299 if len(p)==2:
300 if p[1]==None:
301 p[0]=[]
302 else:
303 p[0]=[ p[1] ]
304 else:
305 p[0]=p[1]
306 p[0].append(p[2])
307
309 '''dictline : NAME dictitem ';'
310 | NAME list ';'
311 | NAME prelist ';'
312 | NAME fieldvalue ';'
313 | NAME dictionary'''
314 p[0]= ( p[1] , p[2] )
315
317 '''number : integer
318 | FCONST'''
319 p[0] = p[1]
320
322 '''dimension : '[' number number number number number number number ']' '''
323 p[0]=apply(Dimension,p[2:-1])
324
326 '''vector : '(' number number number ')' '''
327 p[0]=apply(Vector,p[2:5])
328
330 '''tensor : '(' number number number number number number number number number ')' '''
331 p[0]=apply(Tensor,p[2:11])
332
334 '''symmtensor : '(' number number number number number number ')' '''
335 p[0]=apply(SymmTensor,p[2:8])
336
343
348
350 '''dictitem : longitem
351 | pitem'''
352 if type(p[1])==tuple:
353 p[0]=TupleProxy(p[1])
354 else:
355 p[0] = p[1]
356
358 '''longitem : pitemlist pitem'''
359 p[0] = p[1]+(p[2],)
360
362 '''pitemlist : pitemlist pitem
363 | pitem '''
364 if len(p)==2:
365 p[0]=(p[1],)
366 else:
367 p[0]=p[1]+(p[2],)
368
370 '''pitem : NAME
371 | SCONST
372 | number
373 | dictionary
374 | list
375 | dimension
376 | empty'''
377 p[0] = p[1]
378
380 '''item : pitem
381 | list
382 | dictionary'''
383 p[0] = p[1]
384
388
391
392
393
396 self.descr=descr
397 self.data=data
398
400 result="Error in PyFoamParser: '"+self.descr+"'"
401 if self.data!=None:
402 val=self.data.value
403 if len(val)>100:
404 val=val[:40]+" .... "+val[-40:]
405
406 result+=" @ %r (Type: %s ) in line %d at position %d" % (val,
407 self.data.type,
408 self.data.lineno,
409 self.data.lexpos)
410
411 return result
412
415
417 """Convenience class that parses only a headerless OpenFOAM dictionary"""
418
419 - def __init__(self,content,debug=False):
424
427
429 """Convenience class that parses only a OpenFOAM polyMesh-boundaries file"""
430
431 - def __init__(self,name,backup=False,debug=False):
436
437 - def parse(self,content):
438 """Constructs a representation of the file"""
439 temp=ParsedParameterFile.parse(self,content)
440 self.content={}
441 for i in range(0,len(temp),2):
442 self.content[temp[i]]=temp[i+1]
443 return self.content
444
446 string="// File generated by PyFoam - sorry for the ugliness\n\n"
447 temp=[]
448 for k,v in self.content.iteritems():
449 temp.append((k,v))
450
451 temp.sort(lambda x,y:cmp(int(x[1]["startFace"]),int(y[1]["startFace"])))
452
453 temp2=[]
454
455 for b in temp:
456 temp2.append(b[0])
457 temp2.append(b[1])
458
459 generator=FoamFileGenerator(temp2,header=self.header)
460 string+=str(generator)
461
462 return string
463