Package PyFoam :: Package RunDictionary :: Module ParsedParameterFile
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.RunDictionary.ParsedParameterFile

  1  #  ICE Revision: $Id: ParsedParameterFile.py 8664 2008-03-31 17:14:50Z bgschaid $  
  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   
10 -class ParsedParameterFile(FileBasisBackup):
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
30 - def parse(self,content):
31 """Constructs a representation of the file""" 32 parser=FoamFileParser(content,debug=self.debug, 33 boundaryDict=self.boundaryDict, 34 listLengthUnparsed=self.listLengthUnparsed) 35 36 self.content=parser.getData() 37 self.header=parser.getHeader() 38 return self.content
39
40 - def __contains__(self,key):
41 return key in self.content
42
43 - def __getitem__(self,key):
44 return self.content[key]
45
46 - def __setitem__(self,key,value):
47 self.content[key]=value
48
49 - def __str__(self):
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
60 -class FoamFileParser(PlyParser):
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 #sys.setrecursionlimit(50000) 84 #print sys.getrecursionlimit() 85 86 self.header,self.data=self.parse(content)
87
88 - def __getitem__(self,key):
89 return self.data[key]
90
91 - def __setitem__(self,key,value):
92 self.data[key]=value
93
94 - def getData(self):
95 """ Get the data structure""" 96 return self.data
97
98 - def getHeader(self):
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
112 - def parserError(self,text,c,ind):
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
140 - def t_unparsed_left(self,t):
141 r'\(' 142 t.lexer.level+=1
143 # print "left",t.lexer.level, 144
145 - def t_unparsed_right(self,t):
146 r'\)' 147 t.lexer.level-=1 148 # print "right",t.lexer.level, 149 if t.lexer.level < 0 : 150 t.value = t.lexer.lexdata[t.lexer.code_start:t.lexer.lexpos-1] 151 # print t.value 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
160 - def t_unparsed_error(self,t):
161 print "Error",t.lexer.lexdata[t.lexer.lexpos] 162 t.lexer.skip(1)
163
164 - def t_NAME(self,t):
165 r'[a-zA-Z_][+\-<>(),.\*|a-zA-Z_0-9+]*' 166 t.type=self.reserved.get(t.value,'NAME') 167 if t.value[-1]==")": 168 if t.value.count(")")>t.value.count("("): 169 # Give back the last ) because it propably belongs to a list 170 t.value=t.value[:-1] 171 t.lexer.lexpos-=1 172 173 return t
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 # Define a rule so we can track line numbers
186 - def t_newline(self,t):
187 r'\n+' 188 t.lexer.lineno += len(t.value)
189 190 # C or C++ comment (ignore)
191 - def t_ccode_comment(self,t):
192 r'(/\*(.|\n)*?\*/)|(//.*)' 193 t.lexer.lineno += t.value.count('\n') 194 pass
195 196 # Error handling rule
197 - def t_error(self,t):
198 print "Illegal character '%s'" % t.value[0] 199 t.lexer.skip(1)
200
201 - def p_global(self,p):
202 'global : header dictbody' 203 p[0] = ( p[1] , p[2] )
204
205 - def p_noHeader(self,p):
206 'noHeader : dictbody' 207 p[0] = ( None , p[1] )
208
209 - def p_boundaryDict(self,p):
210 '''boundaryDict : header list 211 | header prelist ''' 212 # p[0] = ( p[1] , dict(zip(p[2][::2],p[2][1::2])) ) 213 p[0] = ( p[1] , p[2] )
214
215 - def p_header(self,p):
216 'header : FOAMFILE dictionary' 217 p[0] = p[2]
218
219 - def p_integer(self,p):
220 '''integer : ICONST''' 221 p[0] = int(p[1])
222
223 - def p_float(self,p):
224 '''integer : FCONST''' 225 p[0] = float(p[1])
226
227 - def p_dictionary(self,p):
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
250 - def p_list(self,p):
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
268 - def p_unparsed(self,p):
269 '''unparsed : UNPARSEDCHUNK''' 270 p[0] = Unparsed(p[1])
271
272 - def p_prelist_seen(self,p):
273 '''prelist_seen : ''' 274 if self.listLengthUnparsed!=None: 275 # print "Hepp" 276 if int(p[-1])>=self.listLengthUnparsed: 277 # print "Ho",p.lexer.lexpos,p.lexer.lexdata[p.lexer.lexpos-1:p.lexer.lexpos+2],p[1],len(p[1]) 278 p.lexer.begin('unparsed') 279 p.lexer.level=0 280 p.lexer.code_start = p.lexer.lexpos
281 282 # t=p.lexer.token() 283 284 ## print t.type 285 ## return t 286 # p[0] = None 287
288 - def p_prelist(self,p):
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
296 - def p_itemlist(self,p):
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
308 - def p_dictline(self,p):
309 '''dictline : NAME dictitem ';' 310 | NAME list ';' 311 | NAME prelist ';' 312 | NAME fieldvalue ';' 313 | NAME dictionary''' 314 p[0]= ( p[1] , p[2] )
315
316 - def p_number(self,p):
317 '''number : integer 318 | FCONST''' 319 p[0] = p[1]
320
321 - def p_dimension(self,p):
322 '''dimension : '[' number number number number number number number ']' ''' 323 p[0]=apply(Dimension,p[2:-1])
324
325 - def p_vector(self,p):
326 '''vector : '(' number number number ')' ''' 327 p[0]=apply(Vector,p[2:5])
328
329 - def p_tensor(self,p):
330 '''tensor : '(' number number number number number number number number number ')' ''' 331 p[0]=apply(Tensor,p[2:11])
332
333 - def p_symmtensor(self,p):
334 '''symmtensor : '(' number number number number number number ')' ''' 335 p[0]=apply(SymmTensor,p[2:8])
336
337 - def p_fieldvalue_uniform(self,p):
338 '''fieldvalue : UNIFORM number 339 | UNIFORM vector 340 | UNIFORM tensor 341 | UNIFORM symmtensor''' 342 p[0] = Field(p[2])
343
344 - def p_fieldvalue_nonuniform(self,p):
345 '''fieldvalue : NONUNIFORM NAME list 346 | NONUNIFORM NAME prelist''' 347 p[0] = Field(p[3],name=p[2])
348
349 - def p_dictitem(self,p):
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
357 - def p_longitem(self,p):
358 '''longitem : pitemlist pitem''' 359 p[0] = p[1]+(p[2],)
360
361 - def p_pitemlist(self,p):
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
369 - def p_pitem(self,p):
370 '''pitem : NAME 371 | SCONST 372 | number 373 | dictionary 374 | list 375 | dimension 376 | empty''' 377 p[0] = p[1]
378
379 - def p_item(self,p):
380 '''item : pitem 381 | list 382 | dictionary''' 383 p[0] = p[1]
384
385 - def p_empty(self,p):
386 'empty :' 387 pass
388
389 - def p_error(self,p):
390 raise PyFoamParserError("Syntax error at token", p) # .type, p.lineno
391 # Just discard the token and tell the parser it's okay. 392 # self.yacc.errok() 393
394 -class PyFoamParserError:
395 - def __init__(self,descr,data=None):
396 self.descr=descr 397 self.data=data
398
399 - def __str__(self):
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
413 - def __repr__(self):
414 return str(self)
415
416 -class FoamStringParser(FoamFileParser):
417 """Convenience class that parses only a headerless OpenFOAM dictionary""" 418
419 - def __init__(self,content,debug=False):
420 """@param content: the string to be parsed 421 @param debug: output debug information during parsing""" 422 423 FoamFileParser.__init__(self,content,debug=debug,noHeader=True,boundaryDict=False)
424
425 - def __str__(self):
426 return str(FoamFileGenerator(self.data))
427
428 -class ParsedBoundaryDict(ParsedParameterFile):
429 """Convenience class that parses only a OpenFOAM polyMesh-boundaries file""" 430
431 - def __init__(self,name,backup=False,debug=False):
432 """@param name: The name of the parameter file 433 @param backup: create a backup-copy of the file""" 434 435 ParsedParameterFile.__init__(self,name,backup=backup,debug=debug,boundaryDict=True)
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
445 - def __str__(self):
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