Package Ganga :: Package Utility :: Package external :: Package ARDAMDClient :: Module mdparser
[hide private]
[frames] | no frames]

Source Code for Module Ganga.Utility.external.ARDAMDClient.mdparser

  1   
  2  ################################################################################ 
  3  # Ganga Project. http://cern.ch/ganga 
  4  # 
  5  # $Id: mdparser.py,v 1.1 2008-07-17 16:41:02 moscicki Exp $ 
  6  ################################################################################ 
  7  from mdinterface import CommandException 
  8  from mdtable import EmptyTableException 
  9  import re 
 10   
 11  # TODO: Check types when writing 
 12   
 13  DEBUGS = False 
 14  DEBUG = False 
 15   
16 -class MDParser:
17 - def __init__(self, query, tables, mainTable, loadTable):
18 self.reINT = re.compile("\d+") 19 self.reFLOAT = re.compile("\.\d+\.\d+") 20 self.reNAME = re.compile("[_a-zA-Z0-9.]+") 21 self.reTABLEREF = re.compile("[_a-zA-Z0-9/.]+:[_a-zA-Z0-9.]+") 22 self.reVARID = re.compile("[a-zA-Z][_a-zA-Z0-9]*") 23 self.reSTRING = re.compile('"[^"]*"') 24 self.q = query 25 self.tables=tables 26 if not len(mainTable): 27 mainTable = '/' 28 if mainTable[len(mainTable)-1] == '/': 29 mainTable = mainTable[0:len(mainTable)-1] 30 self.mainTable=mainTable 31 self.loadTable = loadTable 32 self.parseDict=[(None, None, None)]*(len(query)+1)
33 34
35 - def parseWhereClause(self):
36 if DEBUG: print "parsing where clause: ", self.q 37 if len(self.q) == 0: 38 return True 39 self.__qp = 0 40 try: 41 token, v = self.__pStatement() 42 except EmptyTableException: 43 return False 44 if token == 'CONST': 45 return v > 0 46 if token == 'EXP': 47 return v > 0 48 raise CommandException(8, "Illegal " + self.q + ": not boolean")
49 50
51 - def parseStatement(self):
52 if DEBUG: print "parsing statement: ", self.q 53 self.__qp = 0 54 try: 55 token, v = self.__pStatement() 56 except EmptyTableException: 57 return None 58 return v
59 60
61 - def __isLiteral(self, start, literal):
62 if self.__qp+len(literal) <= len(self.q) \ 63 and self.q[self.__qp:self.__qp+len(literal)] == literal \ 64 and ( ( (len(self.q)> self.__qp+len(literal) ) 65 and self.q[self.__qp+len(literal)].isspace() ) 66 or len(self.q) == self.__qp+len(literal) ): 67 self.__qp = self.__qp + len(literal) 68 if DEBUGS: 'Found literal ', literal 69 self.parseDict[start] = literal, literal, self.__qp 70 return literal, literal 71 else: 72 return None, 0
73 74
75 - def __readToken(self):
76 if DEBUGS: print 'Reading token at ' + str(self.__qp) 77 # Check whether it is in our parser dictionary 78 t, v, next = self.parseDict[self.__qp] 79 if t: 80 if DEBUGS: print 'Returning ', [self.__qp], t, ' ', v 81 self.__qp = next 82 return t, v 83 start = self.__qp 84 85 while self.__qp < len(self.q): 86 if self.q[self.__qp].isspace(): 87 self.__qp = self.__qp +1 88 else: 89 break 90 91 if DEBUGS: print 'Reading token 2 ' 92 93 if self.__qp>= len(self.q): 94 if DEBUGS: print "Token " + str(self.__qp) + " END" 95 self.parseDict[start] = 'END', 0, self.__qp 96 return 'END', 0 97 98 t=self.reINT.match(self.q[self.__qp:]) 99 if t!= None: 100 t=t.group() 101 self.__qp=self.__qp+len(t) 102 if DEBUGS: print "Token " + str(self.__qp) + " CONST " + t 103 self.parseDict[start] = 'CONST', int(t), self.__qp 104 return 'CONST', int(t) 105 106 t=self.reFLOAT.match(self.q[self.__qp:]) 107 if t!= None: 108 t=t.group() 109 self.__qp=self.__qp+len(t) 110 if DEBUGS: print "Token " + str(self.__qp) + " CONST " + t 111 self.parseDict[start] = 'CONST', float(t), self.__qp 112 return 'CONST', float(t) 113 114 if DEBUGS: print 'Reading token 3 ' 115 116 t, v = self.__isLiteral(start, 'and') 117 if t: 118 return t, v 119 t, v = self.__isLiteral(start, 'or') 120 if t: 121 return t, v 122 t, v = self.__isLiteral(start, 'FILE') 123 if t: 124 return t, v 125 126 if DEBUGS: print 'Reading token 4 ' 127 t=self.reTABLEREF.match(self.q[self.__qp:]) 128 if t != None: 129 t = t.group() 130 self.__qp=self.__qp+len(t) 131 if DEBUGS: print "Token ", self.__qp, " TABLREF ", t 132 self.parseDict[start] = 'TABLEREF', t, self.__qp 133 return 'TABLEREF', t 134 135 t=self.reNAME.match(self.q[self.__qp:]) 136 if t != None: 137 t = t.group() 138 self.__qp=self.__qp+len(t) 139 if DEBUGS: print "Token ", self.__qp, " NAME ", t 140 self.parseDict[start] = 'NAME', t, self.__qp 141 return 'NAME', t 142 143 if DEBUGS: print 'Reading token 5 ' 144 145 # = > < 146 if self.__qp +1 < len(self.q): 147 t = self.q[self.__qp:self.__qp+1] 148 if "=<>*/+-".find(t) >=0: 149 if DEBUGS: print "Token " + str(self.__qp) + " " + t 150 self.__qp = self.__qp + 1 151 self.parseDict[start] = t, t, self.__qp 152 return t, t 153 154 if DEBUGS: print 'Reading token 6 ' 155 156 if self.__qp +2 < len(self.q): 157 if self.q[self.__qp:self.__qp+2] == '>=': 158 if DEBUGS: print "Token " + str(self.__qp) + " >=" 159 self.__qp = self.__qp + 2 160 self.parseDict[start] = '>=', 0, self.__qp 161 return ">=", 0 162 if self.q[self.__qp:self.__qp+2] == '<=': 163 if DEBUGS: print "Token " + str(self.__qp) + " <=" 164 self.__qp = self.__qp + 2 165 self.parseDict[start] = '<=', 0, self.__qp 166 return "<=", 0 167 if self.q[self.__qp:self.__qp+2] == '!=': 168 if DEBUGS: print "Token " + str(self.__qp) + " !=" 169 self.__qp = self.__qp + 2 170 self.parseDict[start] = '!=', 0, self.__qp 171 return "!=", 0 172 if self.q[self.__qp:self.__qp+2] == '<>': 173 self.__qp = self.__qp + 2 174 self.parseDict[start] = '<>', 0, self.__qp 175 return "<>", 0 176 177 # string 178 t=self.reSTRING.match(self.q[self.__qp:]) 179 if t!= None: 180 t=t.group() 181 self.__qp=self.__qp+len(t) 182 t = t[1:-1] 183 if DEBUGS: print "Token " + str(self.__qp) + " CONST " + t 184 self.parseDict[start] = 'CONST', str(t), self.__qp 185 return 'CONST', str(t) 186 187 return self.q[self.__qp], 0
188 189
190 - def __pStatement(self):
191 token, v = self.__pExpression() 192 ntoken, nv = self.__readToken() 193 if ntoken == 'END': 194 if token: 195 return token, v 196 raise CommandException(8, "Illegal query: expecting END")
197 198
199 - def __pToken(self):
200 token, v = self.__readToken() 201 if DEBUG: print 'Got ', token, " ", v 202 if token == 'CONST': 203 if DEBUG: print 'Token: CONST ', v 204 return 'CONST', v 205 206 return self.__evalVar(token, v)
207 208
209 - def __pEvaluateOp(self, op, exp1, exp2):
210 if DEBUG: print 'Evaluating operation: ', exp1, op, exp2 211 if op == '=': 212 return 'CONST', exp1 == exp2 213 if op == '>': 214 return 'CONST', exp1 > exp2 215 if op == '<': 216 return 'CONST', exp1 < exp2 217 if op == '<=': 218 return 'CONST', exp1 <= exp2 219 if op == '>=': 220 return 'CONST', exp1 >= exp2 221 if op == '!=': 222 return 'CONST', exp1 != exp2 223 if op == '+': 224 return 'CONST', exp1 + exp2 225 if op == '-': 226 return 'CONST', exp1 - exp2 227 if op == '*': 228 return 'CONST', exp1 * exp2 229 if op == '/': 230 return 'CONST', exp1 / exp2 231 if op == 'or': 232 return 'CONST', exp1 or exp2 233 if op == 'and': 234 return 'CONST', exp1 and exp2 235 raise CommandException (8, 'Illegal query: unknown op' + op)
236 237
238 - def __evalVar(self, token, v):
239 if DEBUG: print "Evaluating variable ", token, " : ", v 240 241 if token == 'NAME': 242 v = self.mainTable + ':' + v 243 token = 'TABLEREF' 244 245 if token == 'TABLEREF': 246 table, v = v.split(':', 1) 247 # Ok, that's a hack, it really only helps for absolute paths... 248 if DEBUG: print 'TABLE BEFORE ', table 249 if not self.tables.has_key(table): 250 mdtable, table = self.loadTable(table) 251 if DEBUG: print 'TABLE AFTER ', table 252 mdtable = self.tables[table] 253 # No entries in table: return None 254 if mdtable.currentRow <0: 255 return None, 0 256 row = mdtable.entries[mdtable.currentRow] 257 if DEBUG: print 'Evaluating ', table, v, row 258 if v == 'FILE': 259 return 'CONST', str(row[0]) 260 if not mdtable.attributeDict.has_key(v): 261 raise CommandException (8, 'Illegal query, unknown ' + v) 262 if mdtable.typeDict[v] == 'int': 263 if row[mdtable.attributeDict[v]+1] == '': 264 return 'CONST', None 265 nv = int(row[mdtable.attributeDict[v]+1]) 266 elif mdtable.typeDict[v] == 'float' or mdtable.typeDict[v] == 'double': 267 nv = float(row[mdtable.attributeDict[v]+1]) 268 if DEBUG: print 'CONST ', row[mdtable.attributeDict[v]+1] 269 else: 270 nv = str(row[mdtable.attributeDict[v]+1]) 271 return 'CONST', nv 272 273 if token == 'FILE': 274 return 'CONST', str(row[0]) 275 return None, 0
276 277
278 - def __pExpression(self):
279 if DEBUG: print "Expression: Trying x and/or y" 280 myi=self.__qp 281 if DEBUG: print 'Expression: was ' + str(self.__qp) 282 token, v = self.__pComparison() 283 if DEBUG: print 'Expression: now ' +str(self.__qp) 284 if token: 285 if DEBUG: print 'Comp ' + str(v) 286 myi2 = self.__qp 287 DEBUGS = True 288 op, opv = self.__readToken() 289 DEBUGS = False 290 if DEBUG: print 'Expression token: ' + str(op) + str(opv) 291 if op == 'and' or op == 'or': 292 ntoken, nv = self.__pExpression() 293 if not ntoken: 294 raise CommandException (8, 'Illegal query: expecting exp') 295 if DEBUG: print 'Expression: reducing a op b' 296 return self.__pEvaluateOp(op, v, nv) 297 self.__qp = myi2 298 self.__qp=myi 299 300 if DEBUG: print 'Expression: Trying comp' + str(self.__qp) 301 token, v = self.__pComparison() 302 if not token: 303 raise CommandException (8, 'Illegal query: expecting comp') 304 if DEBUG: print "Expression: Found comp " + str(v) 305 return token, v
306 307
308 - def __pComparison(self):
309 if DEBUG: print "Comparison: Trying x =>< y" 310 myi=self.__qp 311 if DEBUG: print 'Comparison: was ' + str(self.__qp) 312 token, v = self.__pSum() 313 if DEBUG: print 'Comparison: now ' +str(self.__qp) 314 if token: 315 myi2 = self.__qp 316 op, opv = self.__readToken() 317 if DEBUG: print 'Comparison: got op ' + op + ' ' 318 if op == '=' or op == '>' or op == '<' \ 319 or op == '<=' or op == '>=' or op == '!=': 320 ntoken, nv = self.__pComparison() 321 if not ntoken: 322 raise CommandException (8, 'Illegal query: expecting comp') 323 if DEBUG: print 'Comparison: reducing a op b' 324 return self.__pEvaluateOp(op, v, nv) 325 self.__qp = myi2 326 self.__qp=myi 327 328 if DEBUG: print 'Comparison: Trying sum' + str(self.__qp) 329 token, v = self.__pSum() 330 if not token: 331 raise CommandException (8, 'Illegal query: expecting sum') 332 if DEBUG: print "Comparison: Found sum " + str(v) 333 return token, v
334 335
336 - def __pSum(self):
337 if DEBUG: print "Sum: Trying x +- y" 338 myi=self.__qp 339 if DEBUG: print 'Sum: was ' + str(self.__qp) 340 token, v = self.__pTerm() 341 if DEBUG: print 'Sum: now ' +str(self.__qp) 342 if token: 343 if DEBUG: print 'Sum ' + str(v) 344 myi2 = self.__qp 345 op, opv = self.__readToken() 346 if op == '+' or op == '-': 347 ntoken, nv = self.__pSum() 348 if not ntoken: 349 raise CommandException (8, 'Illegal query: expecting term') 350 return self.__pEvaluateOp(op, v, nv) 351 self.__qp = myi2 352 self.__qp=myi 353 354 if DEBUG: print 'Sum: Trying term' + str(self.__qp) 355 token, v = self.__pTerm() 356 if not token: 357 raise CommandException (8, 'Illegal query: expecting term') 358 if DEBUG: print "Sum: Found term " + str(v) 359 return token, v
360 361
362 - def __pTerm(self):
363 if DEBUG: print "Term: Trying x */ y" 364 myi=self.__qp 365 if DEBUG: print 'Term: I was ' + str(self.__qp) 366 token, v = self.__pFactor() 367 if DEBUG: print 'Term: I now ' +str(self.__qp) 368 if token: 369 if DEBUG: print "Term: " +str(v) 370 myi2 = self.__qp 371 op, opv = self.__readToken() 372 if op == '*' or op == '/': 373 ntoken, nv = self.__pTerm() 374 if not ntoken: 375 raise CommandException (8, 'Illegal query: expecting fact') 376 return self.__pEvaluateOp(op, v, nv) 377 self.__qp = myi2 378 self.__qp=myi 379 380 if DEBUG: print 'Term: Trying faktor' + str(self.__qp) 381 token, v = self.__pFactor() 382 if not token: 383 raise CommandException (8, 'Illegal query: expecting factor') 384 if DEBUG: print "Term: Found factor " + str(v) 385 return token, v
386 387
388 - def __pFactor(self):
389 if DEBUG: print "Factor: Trying ()" 390 myi=self.__qp 391 if DEBUG: print 'Factor: I was ' + str(self.__qp) 392 token, v = self.__readToken() 393 if DEBUG: print "Factor: now " + str(self.__qp) 394 if token == '(': 395 token, v = self.__pExpression() 396 ntoken, nv = self.__readToken() 397 if ntoken != ')': 398 raise CommandException (8, 'Illegal query: expecting )') 399 return token, v 400 self.__qp=myi 401 402 # if DEBUG: 403 if DEBUG: print "Factor: Trying Token" 404 token, v = self.__pToken() 405 406 if not token: 407 raise EmptyTableException 408 if DEBUG: print "Factor: Found token " + str(v) 409 return token, v
410