diff --git a/CHANGELOG b/CHANGELOG
index effa5db..0715b77 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -84,4 +84,5 @@
- Implemented selection_and_product specific optimization
- Added stub for converting SQL to relational algebra
- Implemented futile_union_intersection_subtraction general optimization
-- Implemented swap_rename_projection general optimization
\ No newline at end of file
+- Implemented swap_rename_projection general optimization
+- Replaced old relational algebra to python compiler with new one based on the new tokenizer/parser (Rev 188)
\ No newline at end of file
diff --git a/relational/optimizer.py b/relational/optimizer.py
index c8406d8..629dd8f 100644
--- a/relational/optimizer.py
+++ b/relational/optimizer.py
@@ -97,11 +97,13 @@ class node (object):
#Converting parameters
if self.name=='π':#Projection
- prop=prop.replace(' ','').replace(',','\",\"')
+ prop='\"%s\"' % prop.replace(' ','').replace(',','\",\"')
elif self.name=="ρ": #Rename
- prop=prop.replace(',','\",\"').replace('➡','\":\"').replace(' ','')
+ prop='{\"%s\"}' % prop.replace(',','\",\"').replace('➡','\":\"').replace(' ','')
+ else: #Selection
+ prop='\"%s\"' % prop
- return '%s.%s(\"%s\")' % (self.child.toPython(),op_functions[self.name],prop)
+ return '%s.%s(%s)' % (self.child.toPython(),op_functions[self.name],prop)
else:
return self.name
pass
@@ -317,6 +319,13 @@ if __name__=="__main__":
#print optimizations.selection_and_product(n,rels)
+ '''
+ σ skill=='C' (π id,name,chief,age (σ chief==i and age>a (ρ id➡i,age➡a(π id,age(people))*people)) ᐅᐊ skills)
+ (π id,name,chief,age (σ chief == i and age > a ((ρ age➡a,id➡i (π id,age (people)))*people)))ᐅᐊ(σ skill == 'C' (skills))
+
+
+ '''
+
#print specific_optimize("σ name==skill and age>21 and id==indice and skill=='C'(P1ᐅᐊS1)",rels)
#print n
diff --git a/relational/parser.py b/relational/parser.py
index 7ba70c6..9a49705 100644
--- a/relational/parser.py
+++ b/relational/parser.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
# coding=UTF-8
# Relational
# Copyright (C) 2008 Salvo "LtWorf" Tomaselli
@@ -16,6 +17,9 @@
# along with this program. If not, see .
#
# author Salvo "LtWorf" Tomaselli
+
+import optimizer
+
def parse(expr):
'''This function parses a relational algebra expression, converting it into python,
executable by eval function to get the result of the expression.
@@ -46,120 +50,8 @@ def parse(expr):
ρid➡i,name➡n(π a,b(A))
A ᐅᐊ B
'''
- symbols=("σ","π","ρ")
+ return optimizer.tree(expr).toPython()
- starts=[]#List with starts and ends
- parenthesis=0
- lexpr=list(expr)
- #Parses the string finding all 1st level parenthesis
- for i in range(len(lexpr)):
- if lexpr[i]=="(":
- if parenthesis==0:
- starts.append(i+1)
- parenthesis+=1
- elif lexpr[i]==")":
- parenthesis-=1
- if parenthesis==0:
- starts.append(i)
-
-
- if len(starts)==0: #No parenthesis: no operators with parameters
- return parse_op(expr)
-
- while len(starts)>0:
- #Converting the last complex operator into python
- end=starts.pop()
- start=starts.pop()
-
- internal=parse(expr[start:end])
-
- endp=start-1
- symbol=""
- for i in range(endp,-1,-1):
- if expr[i:i+2] in symbols:
- symbol=expr[i:i+2]
- start=i+2
- break
- if expr[i:i+1] ==")":
- break #No symbol before
-
- parameters=expr[start:endp]
-
- res="" #String for result
- if symbol=="π":#Projection
- params=""
- count=0
- for i in parameters.split(","):
- if count!=0:
- params+=","
- else:
- count=1
- params+="\"%s\"" % (i.strip())
-
- res="%s.projection(%s)" % (internal,params)
- expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
- elif symbol== "σ": #Selection
- res="%s.selection(\"%s\")" % (internal,parameters)
- expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
- elif symbol=="ρ": #Rename
- params=parameters.replace(",","\",\"").replace("➡","\":\"").replace(" ","")
- res="%s.rename({\"%s\"})" % (internal,params)
- expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
- else:
- res="(%s)" % (internal)
- expr= ("%s%s%s") % (expr[0:start-1],res,expr[end+1:])
- #Last complex operator is replaced with it's python code
- #Next cycle will do the same to the new last unparsed complex operator
- #At the end, parse_op will convert operators without parameters
- return parse_op(expr)
-
-def parse_op(expr):
- '''This function parses a relational algebra expression including only operators
- without parameters, converting it into python.
- Executable by eval function to get the result of the expression.'''
-
- result=""
- symbols={}
-
- symbols["*"]=".product(%s)"
- symbols["-"]=".difference(%s)"
- symbols["ᑌ"]=".union(%s)"
- symbols["ᑎ"]=".intersection(%s)"
- symbols["ᐅLEFTᐊ"]=".outer_left(%s)"
- symbols["ᐅRIGHTᐊ"]=".outer_right(%s)"
- symbols["ᐅFULLᐊ"]=".outer(%s)"
- symbols["ᐅᐊ"]=".join(%s)"
-
-
- #We want to avoid to parse expressions within quotes.
- #We split the string into an array, and we parse only the ones with even index
- quotes=expr.split('"');
-
-
-
- for i in range (0,len(quotes),2):
- for j in symbols:
- quotes[i]=quotes[i].replace(j,"_____%s_____"% (j))
-
- #The parts outside the quotes was parsed, put the string together again
- if (len(quotes)>1):
- expr= '"'.join(quotes)
- else:
- expr= quotes[0]
-
- tokens=expr.split("_____")
-
- i=0;
- tk_l=len(tokens)
- while i