|
|
@ -18,35 +18,65 @@
|
|
|
|
# author Salvo "LtWorf" Tomaselli <tiposchi@tiscali.it>
|
|
|
|
# author Salvo "LtWorf" Tomaselli <tiposchi@tiscali.it>
|
|
|
|
def parse(expr):
|
|
|
|
def parse(expr):
|
|
|
|
'''This function parses a relational algebra expression, converting it into python,
|
|
|
|
'''This function parses a relational algebra expression, converting it into python,
|
|
|
|
executable by eval function to get the result of the expression.'''
|
|
|
|
executable by eval function to get the result of the expression.
|
|
|
|
|
|
|
|
It has 2 class of operators:
|
|
|
|
|
|
|
|
without parameters
|
|
|
|
|
|
|
|
*, -, ᑌ, ᑎ, ᐅᐊ, ᐅᐊLEFT, ᐅᐊRIGHT, ᐅᐊFULL
|
|
|
|
|
|
|
|
with parameters:
|
|
|
|
|
|
|
|
σ, π, ρ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Syntax for operators without parameters is:
|
|
|
|
|
|
|
|
relation operator relation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Syntax for operators with parameters is:
|
|
|
|
|
|
|
|
operator parameters (relation)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Since a*b is a relation itself, you can parse π a,b (a*b).
|
|
|
|
|
|
|
|
And since π a,b (A) is a relation, you can parse π a,b (A) ᑌ B.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can't use parenthesis to change priority: a ᐅᐊ (q ᑌ d)
|
|
|
|
|
|
|
|
must be written as q ᑌ d ᐅᐊ a
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
IMPORTANT: The encoding used by this module is UTF-8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EXAMPLES
|
|
|
|
|
|
|
|
σage > 25 and rank == weight(A)
|
|
|
|
|
|
|
|
Q ᐅᐊ π a,b(A) ᐅᐊ B
|
|
|
|
|
|
|
|
ρid➡i,name➡n(A) - π a,b(π a,b(A)) ᑎ σage > 25 or rank = weight(A)
|
|
|
|
|
|
|
|
π a,b(π a,b(A))
|
|
|
|
|
|
|
|
ρid➡i,name➡n(π a,b(A))
|
|
|
|
|
|
|
|
A ᐅᐊ B
|
|
|
|
|
|
|
|
'''
|
|
|
|
symbols=("σ","π","ρ")
|
|
|
|
symbols=("σ","π","ρ")
|
|
|
|
|
|
|
|
|
|
|
|
expr=expr.strip()
|
|
|
|
starts=[]#List with starts and ends
|
|
|
|
|
|
|
|
|
|
|
|
print "====PARSING: ",expr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
start=-1
|
|
|
|
|
|
|
|
end=-1
|
|
|
|
|
|
|
|
parenthesis=0
|
|
|
|
parenthesis=0
|
|
|
|
lexpr=list(expr)
|
|
|
|
lexpr=list(expr)
|
|
|
|
#Parses the string from end to begin
|
|
|
|
#Parses the string finding all 1st level parenthesis
|
|
|
|
for i in range(len(lexpr)):
|
|
|
|
for i in range(len(lexpr)):
|
|
|
|
if lexpr[i]=="(":
|
|
|
|
if lexpr[i]=="(":
|
|
|
|
if parenthesis==0:
|
|
|
|
if parenthesis==0:
|
|
|
|
start=i+1
|
|
|
|
starts.append(i+1)
|
|
|
|
parenthesis+=1
|
|
|
|
parenthesis+=1
|
|
|
|
elif lexpr[i]==")":
|
|
|
|
elif lexpr[i]==")":
|
|
|
|
parenthesis-=1
|
|
|
|
parenthesis-=1
|
|
|
|
if parenthesis==0:
|
|
|
|
if parenthesis==0:
|
|
|
|
end=i
|
|
|
|
starts.append(i)
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if start==-1: #No complex operators
|
|
|
|
|
|
|
|
|
|
|
|
if len(starts)==0: #No parenthesis: no operators with parameters
|
|
|
|
return parse_op(expr)
|
|
|
|
return parse_op(expr)
|
|
|
|
else:
|
|
|
|
|
|
|
|
#internal=expr[0:start]+ parse(expr[start:end])+expr[end:]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while len(starts)>0:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#Converting the last complex operator into python
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
end=starts.pop()
|
|
|
|
|
|
|
|
start=starts.pop()
|
|
|
|
|
|
|
|
|
|
|
|
internal=parse(expr[start:end])
|
|
|
|
internal=parse(expr[start:end])
|
|
|
|
print "EXPRESSION: %s" % (internal)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
endp=start-1
|
|
|
|
endp=start-1
|
|
|
|
start=-1
|
|
|
|
start=-1
|
|
|
@ -57,10 +87,8 @@ def parse(expr):
|
|
|
|
start=i+2
|
|
|
|
start=i+2
|
|
|
|
break
|
|
|
|
break
|
|
|
|
parameters=expr[start:endp]
|
|
|
|
parameters=expr[start:endp]
|
|
|
|
print "===Internal: %s\t Parameters: %s" %(internal,parameters)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
res="" #String for result
|
|
|
|
res=""
|
|
|
|
|
|
|
|
if symbol=="π":#Projection
|
|
|
|
if symbol=="π":#Projection
|
|
|
|
params=""
|
|
|
|
params=""
|
|
|
|
count=0
|
|
|
|
count=0
|
|
|
@ -77,22 +105,16 @@ def parse(expr):
|
|
|
|
elif symbol=="ρ": #Rename
|
|
|
|
elif symbol=="ρ": #Rename
|
|
|
|
params=parameters.replace(",","\",\"").replace("➡","\",\"")
|
|
|
|
params=parameters.replace(",","\",\"").replace("➡","\",\"")
|
|
|
|
res="%s.rename(\"%s\")" % (internal,params)
|
|
|
|
res="%s.rename(\"%s\")" % (internal,params)
|
|
|
|
print res
|
|
|
|
#Last complex operator is replaced with it's python code
|
|
|
|
res= ("%s%s%s") % (expr[0:start-2],res.replace(" ",""),expr[end+1:])
|
|
|
|
#Next cycle will do the same to the new last unparsed complex operator
|
|
|
|
return parse_op(res)
|
|
|
|
#At the end, parse_op will convert operators without parameters
|
|
|
|
#Selection σage > 25 Λ rank = weight(A)
|
|
|
|
expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
|
|
|
|
#Projection Q ᐅᐊ π a,b(A) ᐅᐊ B
|
|
|
|
return parse_op(expr)
|
|
|
|
#Rename ρid➡i,name➡n(A)
|
|
|
|
|
|
|
|
#π a,b(π a,b(A))
|
|
|
|
|
|
|
|
#ρid➡i,name➡n(π a,b(A))
|
|
|
|
|
|
|
|
#A ᐅᐊ B
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def parse_op(expr):
|
|
|
|
def parse_op(expr):
|
|
|
|
'''This function parses a relational algebra expression including only operators
|
|
|
|
'''This function parses a relational algebra expression including only operators
|
|
|
|
(not functions) and no parenthesis, converting it into python,
|
|
|
|
without parameters, converting it into python.
|
|
|
|
executable by eval function to get the result of the expression.'''
|
|
|
|
Executable by eval function to get the result of the expression.'''
|
|
|
|
|
|
|
|
|
|
|
|
result=""
|
|
|
|
result=""
|
|
|
|
symbols={}
|
|
|
|
symbols={}
|
|
|
|