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:
parent
4bf2f915c6
commit
60c949784b
244
parser.py
244
parser.py
@ -17,159 +17,151 @@
|
|||||||
#
|
#
|
||||||
# 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:
|
It has 2 class of operators:
|
||||||
without parameters
|
without parameters
|
||||||
*, -, ᑌ, ᑎ, ᐅᐊ, ᐅLEFTᐊ, ᐅRIGHTᐊ, ᐅFULLᐊ
|
*, -, ᑌ, ᑎ, ᐅᐊ, ᐅLEFTᐊ, ᐅRIGHTᐊ, ᐅFULLᐊ
|
||||||
with parameters:
|
with parameters:
|
||||||
σ, π, ρ
|
σ, π, ρ
|
||||||
|
|
||||||
Syntax for operators without parameters is:
|
Syntax for operators without parameters is:
|
||||||
relation operator relation
|
relation operator relation
|
||||||
|
|
||||||
Syntax for operators with parameters is:
|
Syntax for operators with parameters is:
|
||||||
operator parameters (relation)
|
operator parameters (relation)
|
||||||
|
|
||||||
Since a*b is a relation itself, you can parse π a,b (a*b).
|
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.
|
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).
|
You can use parenthesis to change priority: a ᐅᐊ (q ᑌ d).
|
||||||
|
|
||||||
IMPORTANT: The encoding used by this module is UTF-8
|
IMPORTANT: The encoding used by this module is UTF-8
|
||||||
|
|
||||||
EXAMPLES
|
EXAMPLES
|
||||||
σage > 25 and rank == weight(A)
|
σage > 25 and rank == weight(A)
|
||||||
Q ᐅᐊ π a,b(A) ᐅᐊ B
|
Q ᐅᐊ π a,b(A) ᐅᐊ B
|
||||||
ρid➡i,name➡n(A) - π a,b(π a,b(A)) ᑎ σage > 25 or rank = weight(A)
|
ρid➡i,name➡n(A) - π a,b(π a,b(A)) ᑎ σage > 25 or rank = weight(A)
|
||||||
π a,b(π a,b(A))
|
π a,b(π a,b(A))
|
||||||
ρid➡i,name➡n(π a,b(A))
|
ρid➡i,name➡n(π a,b(A))
|
||||||
A ᐅᐊ B
|
A ᐅᐊ B
|
||||||
'''
|
'''
|
||||||
symbols=("σ","π","ρ")
|
symbols=("σ","π","ρ")
|
||||||
|
|
||||||
starts=[]#List with starts and ends
|
starts=[]#List with starts and ends
|
||||||
parenthesis=0
|
parenthesis=0
|
||||||
lexpr=list(expr)
|
lexpr=list(expr)
|
||||||
#Parses the string finding all 1st level parenthesis
|
#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:
|
||||||
starts.append(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:
|
||||||
starts.append(i)
|
starts.append(i)
|
||||||
|
|
||||||
|
|
||||||
if len(starts)==0: #No parenthesis: no operators with parameters
|
if len(starts)==0: #No parenthesis: no operators with parameters
|
||||||
return parse_op(expr)
|
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])
|
||||||
|
|
||||||
while len(starts)>0:
|
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
|
||||||
|
|
||||||
#Converting the last complex operator into python
|
parameters=expr[start:endp]
|
||||||
|
|
||||||
end=starts.pop()
|
res="" #String for result
|
||||||
start=starts.pop()
|
if symbol=="π":#Projection
|
||||||
|
params=""
|
||||||
|
count=0
|
||||||
|
for i in parameters.split(","):
|
||||||
|
if count!=0:
|
||||||
|
params+=","
|
||||||
|
else:
|
||||||
|
count=1
|
||||||
|
params+="\"%s\"" % (i.strip())
|
||||||
|
|
||||||
internal=parse(expr[start:end])
|
res="%s.projection(%s)" % (internal,params)
|
||||||
|
expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
|
||||||
endp=start-1
|
elif symbol== "σ": #Selection
|
||||||
symbol=""
|
res="%s.selection(\"%s\")" % (internal,parameters)
|
||||||
for i in range(endp,-1,-1):
|
expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
|
||||||
if expr[i:i+2] in symbols:
|
elif symbol=="ρ": #Rename
|
||||||
symbol=expr[i:i+2]
|
params=parameters.replace(",","\",\"").replace("➡","\":\"").replace(" ","")
|
||||||
start=i+2
|
res="%s.rename({\"%s\"})" % (internal,params)
|
||||||
break
|
expr= ("%s%s%s") % (expr[0:start-2],res,expr[end+1:])
|
||||||
if expr[i:i+1] ==")":
|
else:
|
||||||
break #No symbol before
|
res="(%s)" % (internal)
|
||||||
|
expr= ("%s%s%s") % (expr[0:start-1],res,expr[end+1:])
|
||||||
parameters=expr[start:endp]
|
#Last complex operator is replaced with it's python code
|
||||||
|
#Next cycle will do the same to the new last unparsed complex operator
|
||||||
res="" #String for result
|
#At the end, parse_op will convert operators without parameters
|
||||||
if symbol=="π":#Projection
|
return parse_op(expr)
|
||||||
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):
|
def parse_op(expr):
|
||||||
'''This function parses a relational algebra expression including only operators
|
'''This function parses a relational algebra expression including only operators
|
||||||
without parameters, 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={}
|
||||||
|
|
||||||
symbols["*"]=".product(%s)"
|
symbols["*"]=".product(%s)"
|
||||||
symbols["-"]=".difference(%s)"
|
symbols["-"]=".difference(%s)"
|
||||||
symbols["ᑌ"]=".union(%s)"
|
symbols["ᑌ"]=".union(%s)"
|
||||||
symbols["ᑎ"]=".intersection(%s)"
|
symbols["ᑎ"]=".intersection(%s)"
|
||||||
symbols["ᐅLEFTᐊ"]=".outer_left(%s)"
|
symbols["ᐅLEFTᐊ"]=".outer_left(%s)"
|
||||||
symbols["ᐅRIGHTᐊ"]=".outer_right(%s)"
|
symbols["ᐅRIGHTᐊ"]=".outer_right(%s)"
|
||||||
symbols["ᐅFULLᐊ"]=".outer(%s)"
|
symbols["ᐅFULLᐊ"]=".outer(%s)"
|
||||||
symbols["ᐅᐊ"]=".join(%s)"
|
symbols["ᐅᐊ"]=".join(%s)"
|
||||||
|
|
||||||
|
|
||||||
#We want to avoid to parse expressions within quotes.
|
#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
|
#We split the string into an array, and we parse only the ones with even index
|
||||||
quotes=expr.split('"');
|
quotes=expr.split('"');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for i in range (0,len(quotes),2):
|
for i in range (0,len(quotes),2):
|
||||||
for j in symbols:
|
for j in symbols:
|
||||||
quotes[i]=quotes[i].replace(j,"_____%s_____"% (j))
|
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]
|
||||||
|
|
||||||
#The parts outside the quotes was parsed, put the string together again
|
tokens=expr.split("_____")
|
||||||
if (len(quotes)>1):
|
|
||||||
expr= '"'.join(quotes)
|
|
||||||
else:
|
|
||||||
expr= quotes[0]
|
|
||||||
|
|
||||||
tokens=expr.split("_____")
|
i=0;
|
||||||
|
tk_l=len(tokens)
|
||||||
i=0;
|
while i<tk_l:
|
||||||
tk_l=len(tokens)
|
if tokens[i] not in symbols:
|
||||||
while i<tk_l:
|
result+=tokens[i].strip()
|
||||||
if tokens[i] not in symbols:
|
else:
|
||||||
result+=tokens[i].strip()
|
result+=symbols[tokens[i]] % (tokens[i+1].strip())
|
||||||
else:
|
i+=1
|
||||||
|
i+=1
|
||||||
result+=symbols[tokens[i]] % (tokens[i+1].strip())
|
return result
|
||||||
i+=1
|
|
||||||
i+=1
|
|
||||||
return result
|
|
||||||
|
|
||||||
if __name__=="__main__":
|
if __name__=="__main__":
|
||||||
while True:
|
while True:
|
||||||
e=raw_input("Expression: ")
|
e=raw_input("Expression: ")
|
||||||
print parse(e)
|
print parse(e)
|
||||||
|
|
@ -27,11 +27,14 @@ import maingui
|
|||||||
version="0.7"
|
version="0.7"
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app = QtGui.QApplication(sys.argv)
|
if len (sys.argv) > 1 and sys.argv[1] == "-v":
|
||||||
Form = QtGui.QWidget()
|
print version
|
||||||
|
sys.exit(0)
|
||||||
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
Form = QtGui.QWidget()
|
||||||
|
|
||||||
ui = maingui.Ui_Form()
|
ui = maingui.Ui_Form()
|
||||||
ui.setupUi(Form)
|
ui.setupUi(Form)
|
||||||
Form.show()
|
Form.show()
|
||||||
|
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
137
rtypes.py
137
rtypes.py
@ -21,79 +21,78 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
class rstring (str):
|
class rstring (str):
|
||||||
'''String subclass with some custom methods'''
|
'''String subclass with some custom methods'''
|
||||||
def isFloat(self):
|
def isFloat(self):
|
||||||
'''True if the string is a float number, false otherwise'''
|
'''True if the string is a float number, false otherwise'''
|
||||||
lst=('0','1','2','3','4','5','6','7','8','9','.')
|
lst=('0','1','2','3','4','5','6','7','8','9','.')
|
||||||
for i in self:
|
for i in self:
|
||||||
if i not in lst:
|
if i not in lst:
|
||||||
return False;
|
return False;
|
||||||
return True;
|
return True;
|
||||||
|
|
||||||
class rdate (object):
|
class rdate (object):
|
||||||
'''Represents a date'''
|
'''Represents a date'''
|
||||||
def __init__(self,date):
|
def __init__(self,date):
|
||||||
sep=('-','/','\\')
|
sep=('-','/','\\')
|
||||||
splitter=None
|
splitter=None
|
||||||
for i in sep:
|
for i in sep:
|
||||||
if i in date:
|
if i in date:
|
||||||
splitter=i
|
splitter=i
|
||||||
break;
|
break;
|
||||||
elems=date.split(splitter)
|
elems=date.split(splitter)
|
||||||
|
|
||||||
year=int(elems[0])
|
year=int(elems[0])
|
||||||
month=int(elems[1])
|
month=int(elems[1])
|
||||||
day=int(elems[2])
|
day=int(elems[2])
|
||||||
|
|
||||||
self.intdate=datetime.date(year,month,day)
|
self.intdate=datetime.date(year,month,day)
|
||||||
self.day= self.intdate.day
|
self.day= self.intdate.day
|
||||||
self.month=self.intdate.month
|
self.month=self.intdate.month
|
||||||
self.weekday=self.intdate.weekday()
|
self.weekday=self.intdate.weekday()
|
||||||
self.year=self.intdate.year
|
self.year=self.intdate.year
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.intdate.__str__()
|
return self.intdate.__str__()
|
||||||
def __add__(self,days):
|
def __add__(self,days):
|
||||||
res=self.intdate+datetime.timedelta(days)
|
res=self.intdate+datetime.timedelta(days)
|
||||||
return rdate(res.__str__())
|
return rdate(res.__str__())
|
||||||
|
def __eq__(self,other):
|
||||||
def __eq__(self,other):
|
return self.intdate==other.intdate
|
||||||
return self.intdate==other.intdate
|
def __ge__(self,other):
|
||||||
def __ge__(self,other):
|
return self.intdate>=other.intdate
|
||||||
return self.intdate>=other.intdate
|
def __gt__ (self,other):
|
||||||
def __gt__ (self,other):
|
return self.intdate>other.intdate
|
||||||
return self.intdate>other.intdate
|
def __le__ (self,other):
|
||||||
def __le__ (self,other):
|
return self.intdate<=other.intdate
|
||||||
return self.intdate<=other.intdate
|
def __lt__ (self,other):
|
||||||
def __lt__ (self,other):
|
return self.intdate<other.intdate
|
||||||
return self.intdate<other.intdate
|
def __ne__(self,other):
|
||||||
def __ne__(self,other):
|
return self.intdate!=other.intdate
|
||||||
return self.intdate!=other.intdate
|
def __sub__ (self,other):
|
||||||
def __sub__ (self,other):
|
return (self.intdate-other.intdate).days
|
||||||
return (self.intdate-other.intdate).days
|
|
||||||
def isDate(date):
|
def isDate(date):
|
||||||
sep=('-','/','\\')
|
sep=('-','/','\\')
|
||||||
splitter=None
|
splitter=None
|
||||||
for i in sep:
|
for i in sep:
|
||||||
if i in date:
|
if i in date:
|
||||||
splitter=i
|
splitter=i
|
||||||
break;
|
break;
|
||||||
elems=date.split(splitter)
|
elems=date.split(splitter)
|
||||||
if len(elems)!=3:
|
if len(elems)!=3:
|
||||||
return False #Wrong number of elements
|
return False #Wrong number of elements
|
||||||
year=elems[0]
|
year=elems[0]
|
||||||
month=elems[1]
|
month=elems[1]
|
||||||
day=elems[2]
|
day=elems[2]
|
||||||
if not (year.isdigit() and month.isdigit() and day.isdigit()):
|
if not (year.isdigit() and month.isdigit() and day.isdigit()):
|
||||||
return False
|
return False
|
||||||
year=int(year)
|
year=int(year)
|
||||||
month=int(month)
|
month=int(month)
|
||||||
day=int(day)
|
day=int(day)
|
||||||
|
|
||||||
if year<datetime.MINYEAR or year>datetime.MAXYEAR:
|
if year<datetime.MINYEAR or year>datetime.MAXYEAR:
|
||||||
return False
|
return False
|
||||||
if month<1 or month>12:
|
if month<1 or month>12:
|
||||||
return False
|
return False
|
||||||
if day<1 or day >31:
|
if day<1 or day >31:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
@ -22,35 +22,38 @@ import urllib
|
|||||||
|
|
||||||
|
|
||||||
class surveyForm (QtGui.QWidget):
|
class surveyForm (QtGui.QWidget):
|
||||||
'''This class is the form used for the survey, needed to intercept the events'''
|
'''This class is the form used for the survey, needed to intercept the events.
|
||||||
def setUi(self,ui):
|
It also sends the data with http POST to a page hosted on galileo'''
|
||||||
self.ui=ui
|
def setUi(self,ui):
|
||||||
def send(self):
|
self.ui=ui
|
||||||
#Creates the string
|
def send(self):
|
||||||
post="Relational algebra\n"
|
'''Sends the data inserted in the form'''
|
||||||
post+="system:" + str(self.ui.txtSystem.text().toUtf8())+ "\n"
|
#Creates the string
|
||||||
post+="country:" + str(self.ui.txtCountry.text().toUtf8())+ "\n"
|
post="Relational algebra\n"
|
||||||
post+="school:" + str(self.ui.txtSchool.text().toUtf8())+ "\n"
|
post+="system:" + str(self.ui.txtSystem.text().toUtf8())+ "\n"
|
||||||
post+="age:" + str(self.ui.txtAge.text().toUtf8())+ "\n"
|
post+="country:" + str(self.ui.txtCountry.text().toUtf8())+ "\n"
|
||||||
post+="find:" + str(self.ui.txtFind.text().toUtf8())+ "\n"
|
post+="school:" + str(self.ui.txtSchool.text().toUtf8())+ "\n"
|
||||||
post+="comments:" + str(self.ui.txtComments.toPlainText().toUtf8())
|
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()
|
#Clears the form
|
||||||
self.ui.txtCountry.clear()
|
self.ui.txtSystem.clear()
|
||||||
self.ui.txtSchool.clear()
|
self.ui.txtCountry.clear()
|
||||||
self.ui.txtAge.clear()
|
self.ui.txtSchool.clear()
|
||||||
self.ui.txtFind.clear()
|
self.ui.txtAge.clear()
|
||||||
self.ui.txtComments.clear()
|
self.ui.txtFind.clear()
|
||||||
|
self.ui.txtComments.clear()
|
||||||
|
|
||||||
#sends the string
|
#sends the string
|
||||||
params = urllib.urlencode({'survey':post})
|
params = urllib.urlencode({'survey':post})
|
||||||
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
|
headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "text/plain"}
|
||||||
connection = httplib.HTTPConnection('galileo.dmi.unict.it')
|
connection = httplib.HTTPConnection('galileo.dmi.unict.it')
|
||||||
connection.request("POST","/~ltworf/survey.php",params,headers)
|
connection.request("POST","/~ltworf/survey.php",params,headers)
|
||||||
response=connection.getresponse()
|
response=connection.getresponse()
|
||||||
if response.status!=200:
|
if response.status!=200:
|
||||||
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Error"),QtGui.QApplication.translate("Form", "Unable to send the data!") )
|
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Error"),QtGui.QApplication.translate("Form", "Unable to send the data!") )
|
||||||
else:
|
else:
|
||||||
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Thanks"),QtGui.QApplication.translate("Form", "Thanks for sending!") )
|
QtGui.QMessageBox.information(None,QtGui.QApplication.translate("Form", "Thanks"),QtGui.QApplication.translate("Form", "Thanks for sending!") )
|
||||||
|
|
||||||
self.hide()
|
self.hide()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user