- Fixes __eq__ method

- Fixes tokenization of python expressions, using python's builtin module tokenizer


git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@256 014f5005-505e-4b48-8d0a-63407b615a7c
This commit is contained in:
LtWorf 2010-10-04 13:44:25 +00:00
parent 54d1301a96
commit 25c4c894c2
3 changed files with 29 additions and 62 deletions

View File

@ -32,6 +32,10 @@ A function will have to return the number of changes performed on the tree.
import optimizer import optimizer
import parser import parser
from cStringIO import StringIO
from tokenize import generate_tokens
sel_op=('//=','**=','and','not','in','//','**','<<','>>','==','!=','>=','<=','+=','-=','*=','/=','%=','or','+','-','*','/','&','|','^','~','<','>','%','=','(',')',',','[',']') sel_op=('//=','**=','and','not','in','//','**','<<','>>','==','!=','>=','<=','+=','-=','*=','/=','%=','or','+','-','*','/','&','|','^','~','<','>','%','=','(',')',',','[',']')
def replace_node(replace,replacement): def replace_node(replace,replacement):
@ -307,58 +311,22 @@ def tokenize_select(expression):
selection. The expression can contain parenthesis. selection. The expression can contain parenthesis.
It will use a subclass of str with the attribute level, which It will use a subclass of str with the attribute level, which
will specify the nesting level of the token into parenthesis.''' will specify the nesting level of the token into parenthesis.'''
sel_op=('//=','**=','and ','not ','in ','//','**','<<','>>','==','!=','>=','<=','+=','-=','*=','/=','%=','or ','+','-','*','/','&','|','^','~','<','>','%','=','(',')',',','[',']') g=generate_tokens(StringIO(expression).readline)
l=0 l=list(token[1] for token in g)
while l!=len(expression):
l=len(expression)
if expression.startswith('(') and parser.find_matching_parenthesis(expression)+1==len(expression):
expression= expression[1:-1]
tokens=[] l.remove('')
temp=''
level=0
while len(expression)!=0: #Changes the 'a','.','method' token group into a single 'a.method' token
expression=expression.strip() try:
while True:
dot=l.index('.')
l[dot]='%s.%s' % (l[dot-1],l[dot+1])
l.pop(dot+1)
l.pop(dot-1)
except:
pass
if expression[0:1]=='(': #Expression into parenthesis return l
level+=1
elif expression[0:1]==')':
level-=1
for i in range(4,0,-1):#operators
if expression[0:i] in sel_op:
t=level_string(temp)
t.level=level
tokens.append(t)
temp=''
t=level_string(expression[0:i].strip())
t.level=level
tokens.append(t)
expression=expression[i:]
if expression[0:1]=="'":#String
end=expression.index("'",1)
while expression[end-1]=='\\':
end=expression.index("'",end+1)
#Add string to list
t=level_string(expression[0:end+1])
t.level=level
tokens.append(t)
expression=expression[end+1:]
else:
temp+=expression[0:1]
expression=expression[1:]
pass
if len(temp)!=0:
t=level_string(temp)
t.level=level
tokens.append(t)
while True:
try:
tokens.remove('')
except:
break
return tokens
def swap_rename_projection(n): def swap_rename_projection(n):
'''This function locates things like π k(ρ j(R)) '''This function locates things like π k(ρ j(R))

View File

@ -54,7 +54,6 @@ def optimize_all(expression,rels):
total+=i(n) #Performs the optimization total+=i(n) #Performs the optimization
return n.__str__() return n.__str__()
def specific_optimize(expression,rels): def specific_optimize(expression,rels):
'''This function performs specific optimizations. Means that it will need to '''This function performs specific optimizations. Means that it will need to
know the fields used by the relations know the fields used by the relations

View File

@ -381,13 +381,15 @@ class relation (object):
def __eq__(self,other): def __eq__(self,other):
'''Returns true if the relations are the same, ignoring order of items. '''Returns true if the relations are the same, ignoring order of items.
This operation is rather heavy, since it requires sorting and comparing.''' This operation is rather heavy, since it requires sorting and comparing.'''
other=self._rearrange_(other) #Rearranges attributes' order so can compare tuples directly
if (self.__class__!=other.__class__)or(self.header!=other.header): if (self.__class__!=other.__class__)or(self.header!=other.header):
return False #Both parameters must be a relation return False #Both parameters must be a relation
if set(self.header.attributes)!=set(other.header.attributes): if set(self.header.attributes)!=set(other.header.attributes):
return False return False
other=self._rearrange_(other) #Rearranges attributes' order so can compare tuples directly
#comparing content #comparing content
return self.content==other.content return self.content==other.content
@ -519,20 +521,18 @@ class header (object):
def rename(self,old,new): def rename(self,old,new):
'''Renames a field. Doesn't check if it is a duplicate. '''Renames a field. Doesn't check if it is a duplicate.
Returns True if the field was renamed, False otherwise''' Returns True if the field was renamed, False otherwise'''
for i in range(len(self.attributes)): print self.attributes,old, new
if self.attributes[i]==old:
self.attributes[i]=new
return True
return False #Requested field was not found
try:
id_=self.attributes.index(old)
self.attributes[id_]=new
except:
return False
return True
def sharedAttributes(self,other): def sharedAttributes(self,other):
'''Returns how many attributes this header has in common with a given one''' '''Returns how many attributes this header has in common with a given one'''
res=0 return len(set(self.attributes).intersection(set(other.attributes)))
for i in self.attributes:
if i in other.attributes:
res+=1
return res
def __str__(self): def __str__(self):
'''Returns String representation of the field's list''' '''Returns String representation of the field's list'''