Improved exception handling and moved bisonToParser to own file.

parent 2331ecff
...@@ -82,26 +82,24 @@ cdef public object py_callback(object parser, char *target, int option, \ ...@@ -82,26 +82,24 @@ cdef public object py_callback(object parser, char *target, int option, \
cdef void *val cdef void *val
cdef char *termname cdef char *termname
#if parser.verbose:
# print 'py_callback: called with nargs=%d' % nargs
names = PyList_New(nargs) names = PyList_New(nargs)
values = PyList_New(nargs) values = PyList_New(nargs)
Py_INCREF(names) Py_INCREF(names)
Py_INCREF(values) Py_INCREF(values)
#for i in range(nargs):
# print 'i=%d' % i , <char*>va_arg(ap, str_type), \
# hex(<int>va_arg(ap, str_type))
for i in range(nargs): for i in range(nargs):
termname = <char*>va_arg(ap, str_type) termname = <char*>va_arg(ap, str_type)
PyList_SetItem(names, i, termname) PyList_SetItem(names, i, termname)
Py_INCREF(termname) Py_INCREF(termname)
val = <void *>va_arg(ap, void_type) val = <void *>va_arg(ap, void_type)
if val:
valobj = <object>val valobj = <object>val
else:
valobj = None
PyList_SetItem(values, i, valobj) PyList_SetItem(values, i, valobj)
Py_INCREF(valobj) Py_INCREF(valobj)
...@@ -114,6 +112,8 @@ cdef public object py_callback(object parser, char *target, int option, \ ...@@ -114,6 +112,8 @@ cdef public object py_callback(object parser, char *target, int option, \
#signal.signal(signal.SIGALRM, parser.handle_timeout) #signal.signal(signal.SIGALRM, parser.handle_timeout)
#signal.alarm(parser.timeout) #signal.alarm(parser.timeout)
va_end(ap)
res = parser._handle(target, option, names, values) res = parser._handle(target, option, names, values)
#signal.alarm(0) #signal.alarm(0)
...@@ -121,8 +121,6 @@ cdef public object py_callback(object parser, char *target, int option, \ ...@@ -121,8 +121,6 @@ cdef public object py_callback(object parser, char *target, int option, \
#if parser.verbose: #if parser.verbose:
# print 'py_callback: handler returned:', res # print 'py_callback: handler returned:', res
va_end(ap)
return res return res
# callback routine for reading input # callback routine for reading input
...@@ -140,6 +138,12 @@ cdef public void py_input(object parser, char *buf, int *result, int max_size): ...@@ -140,6 +138,12 @@ cdef public void py_input(object parser, char *buf, int *result, int max_size):
if parser.verbose: if parser.verbose:
print '\npy_input: got %s bytes' % buflen print '\npy_input: got %s bytes' % buflen
if buflen == 0 and parser.file:
# Marks the Python file object as being closed from Python's point of
# view. This does not close the associated C stream (which is not
# necessary here, otherwise use "os.close(0)").
parser.file.close()
import sys, os, sha, re, imp, traceback import sys, os, sha, re, imp, traceback
import shutil import shutil
...@@ -269,6 +273,42 @@ cdef class ParserEngine: ...@@ -269,6 +273,42 @@ cdef class ParserEngine:
if parser.verbose: if parser.verbose:
print 'Successfully loaded library' print 'Successfully loaded library'
def generate_exception_handler(self):
s = ''
#s = s + ' if ($$ && $$ != Py_None && PyObject_HasAttrString($$, "_pyBisonError"))\n'
#s = s + ' {\n'
#s = s + ' yyerror(PyString_AsString(PyObject_GetAttrString(py_parser, "lasterror")));\n'
#s = s + ' Py_INCREF(Py_None);\n'
#s = s + ' YYERROR;\n'
#s = s + ' }\n'
s += ' if ($$ && $$ != Py_None)\n'
s += ' {\n'
s += ' if (PyObject_HasAttrString($$, "_pyBisonError"))\n'
s += ' {\n'
s += ' //PyObject* lasterror = PyObject_GetAttrString(py_parser, "lasterror");\n'
s += ' //if (lasterror && PyString_Check(lasterror))\n'
s += ' // yyerror(PyString_AsString(lasterror));\n'
s += ' //else\n'
s += ' // yyerror("No \\"lasterror\\" attribute set in BisonError or not a string");\n'
s += ' Py_INCREF(Py_None);\n'
s += ' YYERROR;\n'
s += ' }\n'
s += ' }\n'
#s += ' else\n'
#s += ' {\n'
#s += ' PyObject* obj = PyErr_Occurred();\n'
#s += ' if (obj)\n'
#s += ' {\n'
#s += ' fprintf(stderr, "exception caught in bison_:\\n");\n'
#s += ' PyErr_Print();\n'
#s += ' YYERROR;\n'
#s += ' }\n'
#s += ' }\n'
return s
def buildLib(self): def buildLib(self):
""" """
Creates the parser engine lib Creates the parser engine lib
...@@ -322,7 +362,6 @@ cdef class ParserEngine: ...@@ -322,7 +362,6 @@ cdef class ParserEngine:
"%{", "%{",
'', '',
'#include "Python.h"', '#include "Python.h"',
"#include <stdio.h>",
"extern FILE *yyin;", "extern FILE *yyin;",
"extern int yylineno;" "extern int yylineno;"
"extern char *yytext;", "extern char *yytext;",
...@@ -415,7 +454,7 @@ cdef class ParserEngine: ...@@ -415,7 +454,7 @@ cdef class ParserEngine:
# now, we have the correct terms count # now, we have the correct terms count
action = action % (i + 1) action = action % (i + 1)
# assemble the full rule + action, ad to list # assemble the full rule + action, add to list
action = action + ",\n " action = action + ",\n "
action = action + ",\n ".join(args) + "\n );\n" action = action + ",\n ".join(args) + "\n );\n"
...@@ -424,13 +463,10 @@ cdef class ParserEngine: ...@@ -424,13 +463,10 @@ cdef class ParserEngine:
action = action + " Py_INCREF(Py_None);\n" action = action + " Py_INCREF(Py_None);\n"
action = action + " yyclearin;\n" action = action + " yyclearin;\n"
action = action + " if ($$ && $$ != Py_None && PyObject_HasAttrString($$, \"_pyBisonError\"))\n" action = action + self.generate_exception_handler()
action = action + " {\n"
action = action + " yyerror(PyString_AsString(PyObject_GetAttrString(py_parser, \"lasterror\")));\n" action = action + ' }\n'
action = action + " Py_INCREF(Py_None);\n"
action = action + " YYERROR;\n"
action = action + " }\n"
action = action + " }\n"
options.append(" ".join(option) + action) options.append(" ".join(option) + action)
idx = idx + 1 idx = idx + 1
write(" | ".join(options) + " ;\n\n") write(" | ".join(options) + " ;\n\n")
......
This diff is collapsed.
This diff is collapsed.
#@+leo-ver=4 #!/usr/bin/env python
#@+node:@file utils/bison2py.py
#@@language python
""" """
Utility which creates a boilerplate pybison-compatible Utility which creates a boilerplate pybison-compatible
python file from a yacc file and lex file python file from a yacc file and lex file
...@@ -9,24 +6,17 @@ python file from a yacc file and lex file ...@@ -9,24 +6,17 @@ python file from a yacc file and lex file
Run it with 2 arguments - filename.y and filename.l Run it with 2 arguments - filename.y and filename.l
Output is filename.py Output is filename.py
""" """
#@+others import sys
#@+node:imports
import sys, os, re, getopt
from bison import bisonToPython from bison import bisonToPython
#@-node:imports
#@+node:globals
argv = sys.argv
argc = len(argv)
progname = argv[0]
reSpaces = re.compile("\\s+")
#@-node:globals
#@+node:usage
def usage(s=None): def usage(s=None):
""" """
Display usage info and exit Display usage info and exit
""" """
progname = sys.argv[0]
if s: if s:
print progname+": "+s print progname+": "+s
...@@ -45,13 +35,13 @@ def usage(s=None): ...@@ -45,13 +35,13 @@ def usage(s=None):
sys.exit(1) sys.exit(1)
#@-node:usage
#@+node:main
def main(): def main():
""" """
Command-line interface for bison2py Command-line interface for bison2py
""" """
global argc, argv argv = sys.argv
argc = len(argv)
if '-c' in argv: if '-c' in argv:
generateClasses = 1 generateClasses = 1
...@@ -72,11 +62,6 @@ def main(): ...@@ -72,11 +62,6 @@ def main():
bisonToPython(bisonfile, lexfile, pyfile, generateClasses) bisonToPython(bisonfile, lexfile, pyfile, generateClasses)
#@-node:main
#@+node:MAINLINE
if __name__ == '__main__': if __name__ == '__main__':
main() main()
#@-node:MAINLINE
#@-others
#@-node:@file utils/bison2py.py
#@-leo
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