Prechádzať zdrojové kódy

Improved error reporting facilities.

Sander Mathijs van Veen 14 rokov pred
rodič
commit
b200b18e40
2 zmenil súbory, kde vykonal 26 pridanie a 20 odobranie
  1. 7 7
      src/pyrex/bison_.pyx
  2. 19 13
      src/python/bison.py

+ 7 - 7
src/pyrex/bison_.pyx

@@ -278,7 +278,7 @@ cdef class ParserEngine:
 
         #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 + ' yyerror(PyString_AsString(PyObject_GetAttrString(py_parser, "last_error")));\n'
         #s = s + '             Py_INCREF(Py_None);\n'
         #s = s + '             YYERROR;\n'
         #s = s + '          }\n'
@@ -287,11 +287,11 @@ cdef class ParserEngine:
         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 += '              //PyObject* last_error = PyObject_GetAttrString(py_parser, "last_error");\n'
+        s += '              //if (last_error && PyString_Check(last_error))\n'
+        s += '              //  yyerror(PyString_AsString(last_error));\n'
         s += '              //else\n'
-        s += '              //  yyerror("No \\"lasterror\\" attribute set in BisonError or not a string");\n'
+        s += '              //  yyerror("No \\"last_error\\" attribute set in BisonError or not a string");\n'
         s += '              Py_INCREF(Py_None);\n'
         s += '              YYERROR;\n'
         s += '            }\n'
@@ -459,7 +459,7 @@ cdef class ParserEngine:
                     action = action + ",\n            ".join(args) + "\n            );\n"
 
                     if 'error' in option:
-                        action = action + "             PyObject_SetAttrString(py_parser, \"lasterror\", Py_None);\n"
+                        action = action + " PyObject_SetAttrString(py_parser, \"last_error\", Py_None);\n"
                         action = action + "             Py_INCREF(Py_None);\n"
                         action = action + "             yyclearin;\n"
 
@@ -504,7 +504,7 @@ cdef class ParserEngine:
             '  PyTuple_SetItem(args, 1, PyString_FromString(mesg));',
             '  PyTuple_SetItem(args, 2, PyString_FromString(yytext));',
             '',
-            '  ret = PyObject_SetAttrString((PyObject *)py_parser, "lasterror", args);',
+            '  ret = PyObject_SetAttrString((PyObject *)py_parser, "last_error", args);',
             '  //printf("PyObject_SetAttrString: %d\\n", ret);',
             '',
             '  //printf("line %d: %s before %s\\n", yylineno+1, mesg, yytext);',

+ 19 - 13
src/python/bison.py

@@ -45,8 +45,9 @@ class BisonError(object):
     """
     _pyBisonError = 1
 
-    def __init__(self, value='syntax error'):
-        self.value = value
+    def __init__(self, error, traceback_info):
+        self.value = error
+        self.traceback_info = traceback_info
 
 
 class BisonException(Exception):
@@ -244,7 +245,7 @@ class BisonParser(object):
 
     last = None # last parsed target, top of parse tree
 
-    lasterror = None # gets set if there was an error
+    last_error = None # gets set if there was an error
 
     keepfiles = 0 # set to 1 to keep temporary engine build files
 
@@ -328,9 +329,9 @@ class BisonParser(object):
             try:
                 self.last = handler(target=targetname, option=option,
                                     names=names, values=values)
-            except:
+            except Exception as e:
                 #traceback.print_exception(*sys.exc_info())
-                return self.error(sys.exc_info())
+                return self.error(e, sys.exc_info())
             #    raise
 
             #if self.verbose:
@@ -342,7 +343,7 @@ class BisonParser(object):
             self.last = BisonNode(targetname, option=option, names=names, values=values)
 
         # reset any resulting errors (assume they've been handled)
-        #self.lasterror = None
+        #self.last_error = None
 
         # assumedly the last thing parsed is at the top of the tree
         return self.last
@@ -395,11 +396,11 @@ class BisonParser(object):
         while not self.file.closed:
             # do the parsing job, spew if error
             self.last = None
-            self.lasterror = None
+            self.last_error = None
             self.engine.runEngine(debug)
 
-            if self.lasterror:
-                self.report_last_error(filename, self.lasterror)
+            if self.last_error:
+                self.report_last_error(filename, self.last_error)
 
             if self.verbose:
                 print 'Parser.run: back from engine'
@@ -446,13 +447,14 @@ class BisonParser(object):
         print 'Parser: line %s: syntax error "%s" before "%s"' \
               % (linenum, msg, tok)
 
-    def error(self, value):
+    def error(self, exception, traceback_info):
         """
         Return the result of this method from a handler to notify a syntax error
         """
         # TODO: should this function be removed?
-        self.lasterror = value
-        return BisonError(value)
+        self.last_error = BisonError(exception, traceback_info)
+
+        return self.last_error
 
     def exception(self, exception):
         # TODO: should this function be removed?
@@ -476,7 +478,11 @@ class BisonParser(object):
 
             print >>sys.stderr, msg
         else:
-            traceback.print_exception(*error)
+            print error
+            if not self.interactive:
+                raise error[3]
+
+            traceback.print_exception(*error[:2])
 
     def toxml(self):
         """