Przeglądaj źródła

Added reset_flex_buffer hook to support flushing flex's internal buffer.

Sander Mathijs van Veen 13 lat temu
rodzic
commit
0a49121e41
4 zmienionych plików z 45 dodań i 9 usunięć
  1. 33 8
      src/c/bisondynlib-linux.c
  2. 1 1
      src/c/bisondynlib.h
  3. 7 0
      src/pyrex/bison_.pyx
  4. 4 0
      src/python/bison.py

+ 33 - 8
src/c/bisondynlib-linux.c

@@ -6,12 +6,23 @@
 #include <stdio.h>
 #include <dlfcn.h>
 
+void (*reset_flex_buffer)(void) = NULL;
+
 void *bisondynlib_open(char *filename)
 {
     void *handle;
 
-    dlerror();
     handle = dlopen(filename, (RTLD_NOW|RTLD_GLOBAL));
+
+    dlerror();
+
+    if (!handle)
+        return NULL;
+
+    reset_flex_buffer = dlsym(handle, "reset_flex_buffer");
+
+    dlerror();
+
     return handle;
 }
 
@@ -20,6 +31,12 @@ int bisondynlib_close(void *handle)
     return dlclose(handle);
 }
 
+void bisondynlib_reset(void)
+{
+    if (reset_flex_buffer)
+        reset_flex_buffer();
+}
+
 char *bisondynlib_err()
 {
     return dlerror();
@@ -28,16 +45,19 @@ char *bisondynlib_err()
 char *bisondynlib_lookup_hash(void *handle)
 {
     char **hash;
-    dlerror();
+
     hash = dlsym(handle, "rules_hash");
-    /*
-    printf("bisondynlib_lookup_hash: hash=%s\n", *hash);
-    */
-    return *hash;
+
+    dlerror();
+
+    return hash ? *hash : NULL;
 }
 
 PyObject *bisondynlib_run(void *handle, PyObject *parser, void *cb, void *in, int debug)
 {
+    if(!handle)
+        return NULL;
+
     PyObject *(*pparser)(PyObject *, void *, void *, int);
 
     pparser = bisondynlib_lookup_parser(handle);
@@ -60,12 +80,17 @@ PyObject *bisondynlib_run(void *handle, PyObject *parser, void *cb, void *in, in
 }
 
 /*
- * function(void *) returns a pointer to a function(PyObject *, char *) returning PyObject*
+ * function(void *) returns a pointer to a function(PyObject *, char *)
+ * returning PyObject*
  */
 PyObject *(*bisondynlib_lookup_parser(void *handle))(PyObject *, void *, void *, int)
 {
+    PyObject *(*do_parse)(PyObject *, void *, void *, int) = dlsym(handle,
+            "do_parse");
+
     dlerror();
-    return dlsym(handle, "do_parse");
+
+    return do_parse;
 }
 
 /*

+ 1 - 1
src/c/bisondynlib.h

@@ -7,6 +7,7 @@
 
 void *bisondynlib_open(char *filename);
 int bisondynlib_close(void *handle);
+void bisondynlib_reset(void);
 char *bisondynlib_err(void);
 
 PyObject *(*bisondynlib_lookup_parser(void *handle))(PyObject *, void *, void *, int);
@@ -14,7 +15,6 @@ PyObject *(*bisondynlib_lookup_parser(void *handle))(PyObject *, void *, void *,
 char *bisondynlib_lookup_hash(void *handle);
 
 PyObject *bisondynlib_run(void *handle, PyObject *parser, void *cb, void *in, int debug);
-
 /*
 int bisondynlib_build(char *libName, char *pyincdir);
 */

+ 7 - 0
src/pyrex/bison_.pyx

@@ -53,6 +53,7 @@ cdef extern from "../c/bison_callback.h":
 cdef extern from "../c/bisondynlib.h":
     void *bisondynlib_open(char *filename)
     int bisondynlib_close(void *handle)
+    void bisondynlib_reset()
     char *bisondynlib_err()
     object (*bisondynlib_lookup_parser(void *handle))(object, char *)
     char *bisondynlib_lookup_hash(void *handle)
@@ -121,6 +122,12 @@ cdef class ParserEngine:
 
         self.openCurrentLib()
 
+    def reset(self):
+        """
+        Reset Flex's buffer and state.
+        """
+        bisondynlib_reset()
+
     def openCurrentLib(self):
         """
         Tests if library exists and is current. If not, builds a fresh one.

+ 4 - 0
src/python/bison.py

@@ -200,6 +200,9 @@ class BisonParser(object):
     def handle_timeout(self, signum, frame):
         raise TimeoutError('Computation exceeded timeout limit.')
 
+    def reset(self):
+        self.engine.reset()
+
     def run(self, **kw):
         """
         Runs the parser, and returns the top-most parse target.
@@ -247,6 +250,7 @@ class BisonParser(object):
         while not self.file.closed:
             # do the parsing job, spew if error
             self.last = None
+            self.engine.reset()
 
             try:
                 self.engine.runEngine(debug)