Added buildDirectory and started to fix segfaults.

parent a0e01183
#!/usr/bin/env python #!/usr/bin/env python
import readline import readline
import sys
sys.path.insert(0, '../../build/lib.linux-x86_64-2.7/')
import calc import calc
......
...@@ -71,9 +71,10 @@ cdef extern from "../c/bisondynlib.h": ...@@ -71,9 +71,10 @@ cdef extern from "../c/bisondynlib.h":
# Callback function which is invoked by target handlers # Callback function which is invoked by target handlers
# within the C yyparse() function. # within the C yyparse() function.
cdef public object py_callback(object parser, char *target, int option, int nargs, void *args,...): cdef public object py_callback(object parser, char *target, int option, \
cdef int *pargs int nargs, void *args):
pargs = <int *>(&args) #cdef int *pargs
#pargs = <int *>(&args)
cdef void *objptr cdef void *objptr
cdef object obj cdef object obj
cdef int i cdef int i
...@@ -81,23 +82,38 @@ cdef public object py_callback(object parser, char *target, int option, int narg ...@@ -81,23 +82,38 @@ cdef public object py_callback(object parser, char *target, int option, int narg
cdef void *val cdef void *val
cdef char *tokval cdef char *tokval
if parser.verbose:
print 'py_callback: called with nargs=%d' % nargs
try: try:
names = PyList_New(nargs) names = PyList_New(0)
values = PyList_New(nargs) values = PyList_New(0)
for i in range(nargs): #names = PyList_New(nargs)
termname = <char *>(pargs[i*2]) #values = PyList_New(nargs)
val = <void *>(pargs[i*2+1])
valobj = <object>val #for i in range(nargs):
# print 'i:', i
Py_INCREF(termname)
Py_INCREF(valobj) # termname = <char *>(pargs[i*2])
PyList_SetItem(names, i, termname) # Py_INCREF(termname)
PyList_SetItem(values, i, valobj) # print 'termname:', termname
# PyList_SetItem(names, i, termname)
# val = <void *>(pargs[i*2+1])
# valobj = <object>val
# Py_INCREF(valobj)
# print 'valobj:', valobj
# PyList_SetItem(values, i, valobj)
if parser.verbose: if parser.verbose:
print "py_callback: calling handler for %s" % PyString_FromString(target) print 'py_callback: calling handler for target "%s"' % target
print 'py_callback: with args:', (target, option, names, values)
res = parser._handle(target, option, names, values) res = parser._handle(target, option, names, values)
if parser.verbose:
print 'py_callback: handler returned:', res
return res return res
except: except:
traceback.print_exc() traceback.print_exc()
...@@ -110,17 +126,22 @@ cdef public void py_input(object parser, char *buf, int *result, int max_size): ...@@ -110,17 +126,22 @@ cdef public void py_input(object parser, char *buf, int *result, int max_size):
cdef char *buf1 cdef char *buf1
cdef int buflen cdef int buflen
#print "py_input: want to read up to %s bytes" % max_size if parser.verbose:
print "\npy_input: want to read up to %s bytes" % max_size
raw = parser.read(max_size) raw = parser.read(max_size)
buflen = PyInt_AsLong(len(raw)) buflen = PyInt_AsLong(len(raw))
result[0] = buflen result[0] = buflen
memcpy(buf, PyString_AsString(raw), buflen) memcpy(buf, PyString_AsString(raw), buflen)
#print "py_input: got %s bytes" % buflen
if parser.verbose:
print "\npy_input: got %s bytes" % buflen
#@-node:py_input #@-node:py_input
#@+node:Python imports #@+node:Python imports
import sys, os, sha, re, imp, traceback import sys, os, sha, re, imp, traceback
import shutil
import distutils.sysconfig import distutils.sysconfig
import distutils.ccompiler import distutils.ccompiler
...@@ -180,7 +201,9 @@ cdef class ParserEngine: ...@@ -180,7 +201,9 @@ cdef class ParserEngine:
""" """
self.parser = parser self.parser = parser
self.libFilename_py = parser.bisonEngineLibName + imp.get_suffixes()[0][0] self.libFilename_py = parser.buildDirectory \
+ parser.bisonEngineLibName \
+ imp.get_suffixes()[0][0]
self.parserHash = hashParserObject(self.parser) self.parserHash = hashParserObject(self.parser)
...@@ -257,7 +280,7 @@ cdef class ParserEngine: ...@@ -257,7 +280,7 @@ cdef class ParserEngine:
if parser.verbose: if parser.verbose:
print "Successfully loaded library" print "Successfully loaded library"
#@-node:openLib #@-node:openLib
#@+node:buildLib #@+node:buildLib
def buildLib(self): def buildLib(self):
...@@ -277,7 +300,8 @@ cdef class ParserEngine: ...@@ -277,7 +300,8 @@ cdef class ParserEngine:
# rip the pertinent grammar specs from parser class # rip the pertinent grammar specs from parser class
parser = self.parser parser = self.parser
# get target handler methods, in the order of appearance in the source file # get target handler methods, in the order of appearance in the source
# file.
attribs = dir(parser) attribs = dir(parser)
gHandlers = [] gHandlers = []
for a in attribs: for a in attribs:
...@@ -291,14 +315,18 @@ cdef class ParserEngine: ...@@ -291,14 +315,18 @@ cdef class ParserEngine:
gTokens = parser.tokens gTokens = parser.tokens
gPrecedences = parser.precedences gPrecedences = parser.precedences
gLex = parser.lexscript gLex = parser.lexscript
buildDirectory = parser.buildDirectory
# ------------------------------------------------ # ------------------------------------------------
# now, can generate the grammar file # now, can generate the grammar file
try: if os.path.isfile(buildDirectory + parser.bisonFile):
os.unlink(parser.bisonFile) os.unlink(buildDirectory + parser.bisonFile)
except:
pass if parser.verbose:
f = open(parser.bisonFile, "w") print 'generating bison file:', buildDirectory + parser.bisonFile
f = open(buildDirectory + parser.bisonFile, "w")
write = f.write write = f.write
writelines = f.writelines writelines = f.writelines
...@@ -321,35 +349,35 @@ cdef class ParserEngine: ...@@ -321,35 +349,35 @@ cdef class ParserEngine:
"%}", "%}",
'', '',
])) ]))
# write out tokens and start target dec # write out tokens and start target dec
write("%%token %s\n\n" % " ".join(gTokens)) write("%%token %s\n\n" % " ".join(gTokens))
write("%%start %s\n\n" % gStart) write("%%start %s\n\n" % gStart)
# write out precedences # write out precedences
for p in gPrecedences: for p in gPrecedences:
write("%%%s %s\n" % (p[0], " ".join(p[1]))) write("%%%s %s\n" % (p[0], " ".join(p[1])))
write("\n\n%%\n\n") write("\n\n%%\n\n")
# carve up docstrings # carve up docstrings
rules = [] rules = []
for h in gHandlers: for h in gHandlers:
doc = h.__doc__.strip() doc = h.__doc__.strip()
# added by Eugene Oden # added by Eugene Oden
#target, options = doc.split(":") #target, options = doc.split(":")
doc = re.sub(unquoted % ";", "", doc) doc = re.sub(unquoted % ";", "", doc)
#print "---------------------" #print "---------------------"
s = re.split(unquoted % ":", doc) s = re.split(unquoted % ":", doc)
#print "s=%s" % s #print "s=%s" % s
target, options = s target, options = s
target = target.strip() target = target.strip()
options = options.strip() options = options.strip()
tmp = [] tmp = []
...@@ -466,59 +494,70 @@ cdef class ParserEngine: ...@@ -466,59 +494,70 @@ cdef class ParserEngine:
# ----------------------------------------------- # -----------------------------------------------
# now generate the lex script # now generate the lex script
try: if os.path.isfile(buildDirectory + parser.flexFile):
os.unlink(parser.flexFile) os.unlink(buildDirectory + parser.flexFile)
except:
pass
lexLines = gLex.split("\n") lexLines = gLex.split("\n")
tmp = [] tmp = []
for line in lexLines: for line in lexLines:
tmp.append(line.strip()) tmp.append(line.strip())
f = open(parser.flexFile, "w") f = open(buildDirectory + parser.flexFile, "w")
f.write("\n".join(tmp) + "\n") f.write("\n".join(tmp) + "\n")
f.close() f.close()
# create and set up a compiler object # create and set up a compiler object
ccompiler = distutils.ccompiler.new_compiler(verbose=parser.verbose) ccompiler = distutils.ccompiler.new_compiler(verbose=parser.verbose)
ccompiler.set_include_dirs([distutils.sysconfig.get_python_inc()]) ccompiler.set_include_dirs([distutils.sysconfig.get_python_inc()])
# ----------------------------------------- # -----------------------------------------
# Now run bison on the grammar file # Now run bison on the grammar file
#os.system("bison -d tmp.y") #os.system("bison -d tmp.y")
bisonCmd = parser.bisonCmd + [parser.bisonFile] bisonCmd = parser.bisonCmd + [buildDirectory + parser.bisonFile]
if parser.verbose: if parser.verbose:
print "bisonCmd=%s" % repr(bisonCmd) print 'bison cmd:', ' '.join(bisonCmd)
ccompiler.spawn(bisonCmd) ccompiler.spawn(bisonCmd)
if parser.verbose: if parser.verbose:
print "renaming bison output files" print "renaming bison output files"
print parser.bisonCFile, "=>", parser.bisonCFile1 print '%s => %s%s' % (parser.bisonCFile, buildDirectory,
print parser.bisonHFile, "=>", parser.bisonHFile1 parser.bisonCFile1)
print '%s => %s%s' % (parser.bisonHFile, buildDirectory,
try: parser.bisonHFile1)
os.unlink(parser.bisonCFile1)
except: if os.path.isfile(buildDirectory + parser.bisonCFile1):
pass os.unlink(buildDirectory + parser.bisonCFile1)
os.rename(parser.bisonCFile, parser.bisonCFile1)
try: shutil.copy(parser.bisonCFile, buildDirectory + parser.bisonCFile1)
os.unlink(parser.bisonHFile1)
except: if os.path.isfile(buildDirectory + parser.bisonHFile1):
pass os.unlink(buildDirectory + parser.bisonHFile1)
os.rename(parser.bisonHFile, parser.bisonHFile1)
shutil.copy(parser.bisonHFile, buildDirectory + parser.bisonHFile1)
# ----------------------------------------- # -----------------------------------------
# Now run lex on the lex file # Now run lex on the lex file
#os.system("lex tmp.l") #os.system("lex tmp.l")
ccompiler.spawn(parser.flexCmd + [parser.flexFile]) flexCmd = parser.flexCmd + [buildDirectory + parser.flexFile]
try:
os.unlink(parser.flexCFile1) if parser.verbose:
except: print 'flex cmd:', ' '.join(flexCmd)
pass
os.rename(parser.flexCFile, parser.flexCFile1) ccompiler.spawn(flexCmd)
if os.path.isfile(buildDirectory + parser.flexCFile1):
os.unlink(buildDirectory + parser.flexCFile1)
if parser.verbose:
print '%s => %s%s' % (parser.flexCFile, buildDirectory,
parser.flexCFile1)
shutil.copy(parser.flexCFile, buildDirectory + parser.flexCFile1)
# ----------------------------------------- # -----------------------------------------
# Now compile the files into a shared lib # Now compile the files into a shared lib
# compile bison and lex c sources # compile bison and lex c sources
#bisonObj = ccompiler.compile([parser.bisonCFile1]) #bisonObj = ccompiler.compile([parser.bisonCFile1])
#lexObj = ccompiler.compile([parser.flexCFile1]) #lexObj = ccompiler.compile([parser.flexCFile1])
...@@ -528,17 +567,23 @@ cdef class ParserEngine: ...@@ -528,17 +567,23 @@ cdef class ParserEngine:
# extra_preargs=['/DWIN32', '/G4', '/Gs', '/Oit', '/MT', '/nologo', '/W3', '/WX', '/Id:\python23\include']) # extra_preargs=['/DWIN32', '/G4', '/Gs', '/Oit', '/MT', '/nologo', '/W3', '/WX', '/Id:\python23\include'])
# link 'em into a shared lib # link 'em into a shared lib
objs = ccompiler.compile([parser.bisonCFile1, parser.flexCFile1], objs = ccompiler.compile([buildDirectory + parser.bisonCFile1,
buildDirectory + parser.flexCFile1],
extra_preargs=parser.cflags_pre, extra_preargs=parser.cflags_pre,
extra_postargs=parser.cflags_post) extra_postargs=parser.cflags_post,
libFileName = parser.bisonEngineLibName+imp.get_suffixes()[0][0] debug=parser.debugSymbols)
libFileName = buildDirectory + parser.bisonEngineLibName \
+ imp.get_suffixes()[0][0]
if os.path.isfile(libFileName+".bak"): if os.path.isfile(libFileName+".bak"):
try: os.unlink(libFileName+".bak")
os.unlink(libFileName+".bak")
except:
pass
if os.path.isfile(libFileName): if os.path.isfile(libFileName):
os.rename(libFileName, libFileName+".bak") os.rename(libFileName, libFileName+".bak")
if parser.verbose:
print 'linking: %s => %s' % (', '.join(objs), libFileName)
ccompiler.link_shared_object(objs, libFileName) ccompiler.link_shared_object(objs, libFileName)
#incdir = PyString_AsString(get_python_inc()) #incdir = PyString_AsString(get_python_inc())
...@@ -547,14 +592,15 @@ cdef class ParserEngine: ...@@ -547,14 +592,15 @@ cdef class ParserEngine:
# -------------------------------------------- # --------------------------------------------
# clean up, if we succeeded # clean up, if we succeeded
hitlist = objs[:] hitlist = objs[:]
hitlist.append("tmp.output") hitlist.append(buildDirectory + "tmp.output")
if os.path.isfile(libFileName): if os.path.isfile(libFileName):
for name in ['bisonFile', 'bisonCFile', 'bisonHFile', for name in ['bisonFile', 'bisonCFile', 'bisonHFile',
'bisonCFile1', 'bisonHFile1', 'flexFile', 'bisonCFile1', 'bisonHFile1', 'flexFile',
'flexCFile', 'flexCFile1', 'flexCFile', 'flexCFile1',
] + objs: ] + objs:
if hasattr(parser, name): if hasattr(parser, name):
fname = getattr(parser, name) fname = buildDirectory + getattr(parser, name)
else: else:
fname = None fname = None
#print "want to delete %s" % fname #print "want to delete %s" % fname
...@@ -582,22 +628,24 @@ cdef class ParserEngine: ...@@ -582,22 +628,24 @@ cdef class ParserEngine:
Runs the binary parser engine, as loaded from the lib Runs the binary parser engine, as loaded from the lib
""" """
cdef void *handle cdef void *handle
cdef void *cbvoid cdef void *cbvoid
cdef void *invoid cdef void *invoid
handle = self.libHandle handle = self.libHandle
parser = self.parser parser = self.parser
cbvoid = <void *>py_callback cbvoid = <void *>py_callback
invoid = <void *>py_input invoid = <void *>py_input
if parser.verbose: if parser.verbose:
print "runEngine: about to call, py_input=0x%lx..." % (<int>invoid) print "runEngine: about to call, py_input=0x%lx..." % (<int>invoid)
return bisondynlib_run(handle, parser, cbvoid, invoid, debug) return bisondynlib_run(handle, parser, cbvoid, invoid, debug)
if parser.verbose: if parser.verbose:
print "runEngine: back from parser" print "runEngine: back from parser"
#@-node:runEngine #@-node:runEngine
#@+node:__del__ #@+node:__del__
def __del__(self): def __del__(self):
......
...@@ -243,7 +243,10 @@ class BisonParser(object): ...@@ -243,7 +243,10 @@ class BisonParser(object):
flexCFile1 = "tmp.lex.c" # c output file from lex gets renamed to this flexCFile1 = "tmp.lex.c" # c output file from lex gets renamed to this
cflags_pre = ['-fPIC'] # = CFLAGS added before all arguments. cflags_pre = ['-fPIC'] # = CFLAGS added before all arguments.
cflags_post = ['-O3','-g'] # = CFLAGS added after all arguments. cflags_post = ['-O0','-g'] # = CFLAGS added after all arguments.
buildDirectory = './' # Directory used to store the generated / compiled files.
debugSymbols = 1 # Add debugging symbols to the binary files.
verbose = 0 verbose = 0
...@@ -324,17 +327,23 @@ class BisonParser(object): ...@@ -324,17 +327,23 @@ class BisonParser(object):
Tries to dispatch to on_TargetName() methods if they exist, Tries to dispatch to on_TargetName() methods if they exist,
otherwise wraps the target in a BisonNode object otherwise wraps the target in a BisonNode object
""" """
handler = getattr(self, "on_"+targetname, None) handler = getattr(self, 'on_'+targetname, None)
if handler: if handler:
if self.verbose: if self.verbose:
try: try:
hdlrline = handler.func_code.co_firstlineno hdlrline = handler.func_code.co_firstlineno
except: except:
hdlrline = handler.__init__.func_code.co_firstlineno hdlrline = handler.__init__.func_code.co_firstlineno
print "invoking handler at line %s for %s" % (hdlrline, targetname)
self.last = handler(target=targetname, option=option, names=names, values=values) print '_handle: invoking handler at line %s for "%s"' \
if self.verbose: % (hdlrline, targetname)
print "handler for %s returned %s" % (targetname, repr(self.last))
print handler
self.last = handler(target=targetname, option=option, names=names,
values=values)
#if self.verbose:
# print 'handler for %s returned %s' \
# % (targetname, repr(self.last))
else: else:
if self.verbose: if self.verbose:
print "no handler for %s, using default" % targetname print "no handler for %s, using default" % targetname
...@@ -607,8 +616,8 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0): ...@@ -607,8 +616,8 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
prologue, rulesRaw, epilogue = rawBison.split("\n%%\n") prologue, rulesRaw, epilogue = rawBison.split("\n%%\n")
except: except:
raise Exception( raise Exception(
"File "+bisonfileName+" is not a properly formatted bison file"+\ "File %s is not a properly formatted bison file"
" (needs 3 sections separated by %%%%" " (needs 3 sections separated by %%%%" % (bisonfileName)
) )
# -------------------------------------- # --------------------------------------
...@@ -791,7 +800,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0): ...@@ -791,7 +800,7 @@ def bisonToPython(bisonfileName, lexfileName, pyfileName, generateClasses=0):
' # --------------------------------------------', ' # --------------------------------------------',
' # basename of binary parser engine dynamic lib', ' # basename of binary parser engine dynamic lib',
' # --------------------------------------------', ' # --------------------------------------------',
' bisonEngineLibName = "%s"' % libfileName, ' bisonEngineLibName = "%s"' % (parser.buildDirectory + libfileName),
'\n', '\n',
])) ]))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment