using 4 spaces to indent

git-svn-id: http://galileo.dmi.unict.it/svn/relational/trunk@58 014f5005-505e-4b48-8d0a-63407b615a7c
This commit is contained in:
LtWorf 2008-11-15 13:15:26 +00:00
parent 4bf2f915c6
commit 60c949784b
4 changed files with 261 additions and 264 deletions

300
parser.py
View File

@ -17,159 +17,151 @@
#
# author Salvo "LtWorf" Tomaselli <tiposchi@tiscali.it>
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.
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 use parenthesis to change priority: a ᐅᐊ (q d).
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=("σ","π","ρ")
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)
'''This function parses a relational algebra expression, converting it into python,
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 use parenthesis to change priority: a ᐅᐊ (q d).
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=("σ","π","ρ")
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<tk_l:
if tokens[i] not in symbols:
result+=tokens[i].strip()
else:
result+=symbols[tokens[i]] % (tokens[i+1].strip())
i+=1
i+=1
return result
'''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<tk_l:
if tokens[i] not in symbols:
result+=tokens[i].strip()
else:
result+=symbols[tokens[i]] % (tokens[i+1].strip())
i+=1
i+=1
return result
if __name__=="__main__":
while True:
e=raw_input("Expression: ")
print parse(e)
while True:
e=raw_input("Expression: ")
print parse(e)

View File

@ -27,11 +27,14 @@ import maingui
version="0.7"
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = maingui.Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
if len (sys.argv) > 1 and sys.argv[1] == "-v":
print version
sys.exit(0)
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = maingui.Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())

145
rtypes.py
View File

@ -21,79 +21,78 @@
import datetime
class rstring (str):
'''String subclass with some custom methods'''
def isFloat(self):
'''True if the string is a float number, false otherwise'''
lst=('0','1','2','3','4','5','6','7','8','9','.')
for i in self:
if i not in lst:
return False;
return True;
'''String subclass with some custom methods'''
def isFloat(self):
'''True if the string is a float number, false otherwise'''
lst=('0','1','2','3','4','5','6','7','8','9','.')
for i in self:
if i not in lst:
return False;
return True;
class rdate (object):
'''Represents a date'''
def __init__(self,date):
sep=('-','/','\\')
splitter=None
for i in sep:
if i in date:
splitter=i
break;
elems=date.split(splitter)
year=int(elems[0])
month=int(elems[1])
day=int(elems[2])
self.intdate=datetime.date(year,month,day)
self.day= self.intdate.day
self.month=self.intdate.month
self.weekday=self.intdate.weekday()
self.year=self.intdate.year
def __str__(self):
return self.intdate.__str__()
def __add__(self,days):
res=self.intdate+datetime.timedelta(days)
return rdate(res.__str__())
def __eq__(self,other):
return self.intdate==other.intdate
def __ge__(self,other):
return self.intdate>=other.intdate
def __gt__ (self,other):
return self.intdate>other.intdate
def __le__ (self,other):
return self.intdate<=other.intdate
def __lt__ (self,other):
return self.intdate<other.intdate
def __ne__(self,other):
return self.intdate!=other.intdate
def __sub__ (self,other):
return (self.intdate-other.intdate).days
'''Represents a date'''
def __init__(self,date):
sep=('-','/','\\')
splitter=None
for i in sep:
if i in date:
splitter=i
break;
elems=date.split(splitter)
year=int(elems[0])
month=int(elems[1])
day=int(elems[2])
self.intdate=datetime.date(year,month,day)
self.day= self.intdate.day
self.month=self.intdate.month
self.weekday=self.intdate.weekday()
self.year=self.intdate.year
def __str__(self):
return self.intdate.__str__()
def __add__(self,days):
res=self.intdate+datetime.timedelta(days)
return rdate(res.__str__())
def __eq__(self,other):
return self.intdate==other.intdate
def __ge__(self,other):
return self.intdate>=other.intdate
def __gt__ (self,other):
return self.intdate>other.intdate
def __le__ (self,other):
return self.intdate<=other.intdate
def __lt__ (self,other):
return self.intdate<other.intdate
def __ne__(self,other):
return self.intdate!=other.intdate
def __sub__ (self,other):
return (self.intdate-other.intdate).days
def isDate(date):
sep=('-','/','\\')
splitter=None
for i in sep:
if i in date:
splitter=i
break;
elems=date.split(splitter)
if len(elems)!=3:
return False #Wrong number of elements
year=elems[0]
month=elems[1]
day=elems[2]
if not (year.isdigit() and month.isdigit() and day.isdigit()):
return False
year=int(year)
month=int(month)
day=int(day)
if year<datetime.MINYEAR or year>datetime.MAXYEAR:
return False
if month<1 or month>12:
return False
if day<1 or day >31:
return False
return True
sep=('-','/','\\')
splitter=None
for i in sep:
if i in date:
splitter=i
break;
elems=date.split(splitter)
if len(elems)!=3:
return False #Wrong number of elements
year=elems[0]
month=elems[1]
day=elems[2]
if not (year.isdigit() and month.isdigit() and day.isdigit()):
return False
year=int(year)
month=int(month)
day=int(day)
if year<datetime.MINYEAR or year>datetime.MAXYEAR:
return False
if month<1 or month>12:
return False
if day<1 or day >31:
return False
return True

View File

@ -22,35 +22,38 @@ import urllib
class surveyForm (QtGui.QWidget):
'''This class is the form used for the survey, needed to intercept the events'''
def setUi(self,ui):
self.ui=ui
def send(self):
#Creates the string
post="Relational algebra\n"
post+="system:" + str(self.ui.txtSystem.text().toUtf8())+ "\n"
post+="country:" + str(self.ui.txtCountry.text().toUtf8())+ "\n"
post+="school:" + str(self.ui.txtSchool.text().toUtf8())+ "\n"
post+="age:" + str(self.ui.txtAge.text().toUtf8())+ "\n"
post+="find:" + str(self.ui.txtFind.text().toUtf8())+ "\n"
post+="comments:" + str(self.ui.txtComments.toPlainText().toUtf8())
'''This class is the form used for the survey, needed to intercept the events.
It also sends the data with http POST to a page hosted on galileo'''
def setUi(self,ui):
self.ui=ui
def send(self):
'''Sends the data inserted in the form'''
#Creates the string
post="Relational algebra\n"
post+="system:" + str(self.ui.txtSystem.text().toUtf8())+ "\n"
post+="country:" + str(self.ui.txtCountry.text().toUtf8())+ "\n"
post+="school:" + str(self.ui.txtSchool.text().toUtf8())+ "\n"
post+="age:" + str(self.ui.txtAge.text().toUtf8())+ "\n"
post+="find:" + str(self.ui.txtFind.text().toUtf8())+ "\n"
post+="comments:" + str(self.ui.txtComments.toPlainText().toUtf8())
self.ui.txtSystem.clear()
self.ui.txtCountry.clear()
self.ui.txtSchool.clear()
self.ui.txtAge.clear()
self.ui.txtFind.clear()
self.ui.txtComments.clear()
#Clears the form
self.ui.txtSystem.clear()
self.ui.txtCountry.clear()
self.ui.txtSchool.clear()
self.ui.txtAge.clear()
self.ui.txtFind.clear()
self.ui.txtComments.clear()
#sends the string
params = urllib.urlencode({'survey':post})
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
connection = httplib.HTTPConnection('galileo.dmi.unict.it')
connection.request("POST","/~ltworf/survey.php",params,headers)
response=connection.getresponse()
if response.status!=200:
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Error"),QtGui.QApplication.translate("Form", "Unable to send the data!") )
else:
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Thanks"),QtGui.QApplication.translate("Form", "Thanks for sending!") )
#sends the string
params = urllib.urlencode({'survey':post})
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
connection = httplib.HTTPConnection('galileo.dmi.unict.it')
connection.request("POST","/~ltworf/survey.php",params,headers)
response=connection.getresponse()
if response.status!=200:
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Error"),QtGui.QApplication.translate("Form", "Unable to send the data!") )
else:
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Thanks"),QtGui.QApplication.translate("Form", "Thanks for sending!") )
self.hide()
self.hide()