parser completed

git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@18 014f5005-505e-4b48-8d0a-63407b615a7c
master
LtWorf 2008-07-21 07:31:17 +07:00
parent 0f8d0b68ac
commit 889c333058
1 changed files with 80 additions and 58 deletions

@ -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
ρidi,namen(A) - π a,b(π a,b(A)) σage > 25 or rank = weight(A)
π a,b(π a,b(A))
ρidi,namen(π 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={}