changeset 16294:0925d1f6875e

push parser/lexer interface * lex.h, lex.ll (octave_push_lexer): New class. (octave_base_lexer:is_push_lexer, octave_base_lexer::at_end_of_file, octave_base_lexer::at_end_of_buffer): New functions. (.): Handle special character (ASCII 0x01) that octave_push_lexer::fill_flex_buffer returns for an end-of-buffer condition. * parse.h, oct-parse.in.yy (octave_push_parser): New class. (octave_base_parser::parser_state): Move to octave_push_parser class. (octave_base_parser::~octave_base_parser, octave_base_parser::init): Delete special case for push parser. * configure.ac (--enable-push-parser): Delete option handling. Both push and pull parser interfaces will always be defined.
author John W. Eaton <jwe@octave.org>
date Wed, 13 Mar 2013 03:19:35 -0400
parents 57e87ddfee14
children 4a1300ed5d3c
files configure.ac libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.in.yy libinterp/parse-tree/parse.h
diffstat 5 files changed, 163 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Wed Mar 13 02:46:56 2013 -0400
+++ b/configure.ac	Wed Mar 13 03:19:35 2013 -0400
@@ -190,17 +190,6 @@
   AC_DEFINE(BOUNDS_CHECKING, 1, [Define to 1 to use internal bounds checking.])
 fi
 
-### Enable experimental push parser.
-
-OCTAVE_USE_PUSH_PARSER=no
-AC_ARG_ENABLE([push-parser],
-  [AS_HELP_STRING([--enable-push-parser],
-    [enable experimental push parser])],
-  [if test "$enableval" = yes; then OCTAVE_USE_PUSH_PARSER=yes; fi], [])
-if test $OCTAVE_USE_PUSH_PARSER = yes; then
-  AC_DEFINE(OCTAVE_USE_PUSH_PARSER, 1, [Define to 1 to use experimental push parser.])
-fi
-
 ### Use Octave's built-in memory allocator rather than straightforward malloc.
 ### Disabled by default.
 
@@ -2980,7 +2969,6 @@
   Build Java interface:               $build_java
   Do internal array bounds checking:  $BOUNDS_CHECKING
   Use octave_allocator:               $USE_OCTAVE_ALLOCATOR
-  Use push parser:                    $OCTAVE_USE_PUSH_PARSER
   Build static libraries:             $STATIC_LIBS
   Build shared libraries:             $SHARED_LIBS
   Dynamic Linking:                    $ENABLE_DYNAMIC_LINKING $DL_API_MSG
--- a/libinterp/parse-tree/lex.h	Wed Mar 13 02:46:56 2013 -0400
+++ b/libinterp/parse-tree/lex.h	Wed Mar 13 03:19:35 2013 -0400
@@ -438,12 +438,18 @@
 
   void init (void);
 
+  virtual bool is_push_lexer (void) const { return false; }
+
   virtual void reset (void);
 
   void prep_for_file (void);
 
   virtual int fill_flex_buffer (char *buf, unsigned int max_size) = 0;
 
+  bool at_end_of_buffer (void) const { return input_buf.empty (); }
+
+  bool at_end_of_file (void) const { return input_buf.at_eof (); }
+
   int handle_end_of_input (void);
 
   char *flex_yytext (void);
@@ -646,4 +652,58 @@
   octave_lexer& operator = (const octave_lexer&);
 };
 
+class
+octave_push_lexer : public octave_base_lexer
+{
+public:
+
+  octave_push_lexer (const std::string& input = std::string (),
+                     bool eof = false)
+    : octave_base_lexer (), pflag (1)
+  {
+    append_input (input, eof);
+  }
+
+  bool is_push_lexer (void) const { return true; }
+
+  void reset (void)
+  {
+    promptflag (1);
+
+    octave_base_lexer::reset ();
+  }
+
+  void append_input (const std::string& input, bool eof)
+  {
+    input_buf.fill (input, eof);
+  }
+
+  void increment_promptflag (void) { pflag++; }
+
+  void decrement_promptflag (void) { pflag--; }
+
+  int promptflag (void) const { return pflag; }
+
+  int promptflag (int n)
+  {
+    int retval = pflag;
+    pflag = n;
+    return retval;
+  }
+
+  std::string input_source (void) const { return "push buffer"; }
+
+  int fill_flex_buffer (char *buf, unsigned int max_size);
+
+protected:
+
+  int pflag;
+
+  // No copying!
+
+  octave_push_lexer (const octave_push_lexer&);
+
+  octave_push_lexer& operator = (const octave_push_lexer&);
+};
+
 #endif
--- a/libinterp/parse-tree/lex.ll	Wed Mar 13 02:46:56 2013 -0400
+++ b/libinterp/parse-tree/lex.ll	Wed Mar 13 03:19:35 2013 -0400
@@ -1129,7 +1129,11 @@
 
     int c = curr_lexer->text_yyinput ();
 
-    if (c != EOF)
+    if (c == 1)
+      return -1;
+    else if (c == EOF)
+      return curr_lexer->handle_end_of_input ();
+    else
       {
         curr_lexer->current_input_column++;
 
@@ -1139,8 +1143,6 @@
 
         return LEXICAL_ERROR;
       }
-    else
-      return curr_lexer->handle_end_of_input ();
   }
 
 %%
@@ -3012,3 +3014,24 @@
 
   return status;
 }
+
+int
+octave_push_lexer::fill_flex_buffer (char *buf, unsigned max_size)
+{
+  int status = 0;
+
+  if (input_buf.empty () && ! input_buf.at_eof ())
+    input_buf.fill (std::string (1, static_cast<char> (1)), false);
+ 
+  if (! input_buf.empty ())
+    status = input_buf.copy_chunk (buf, max_size);
+  else
+    {
+      status = YY_NULL;
+
+      if (! input_buf.at_eof ())
+        fatal_error ("octave_base_lexer::fill_flex_buffer failed");
+    }
+
+  return status;
+}
--- a/libinterp/parse-tree/oct-parse.in.yy	Wed Mar 13 02:46:56 2013 -0400
+++ b/libinterp/parse-tree/oct-parse.in.yy	Wed Mar 13 03:19:35 2013 -0400
@@ -1450,10 +1450,6 @@
 
 octave_base_parser::~octave_base_parser (void)
 {
-#if defined (OCTAVE_USE_PUSH_PARSER)
-  yypstate_delete (static_cast<yypstate *> (parser_state));
-#endif
-
   delete stmt_list;
 
   delete &lexer;
@@ -1461,10 +1457,6 @@
 
 void octave_base_parser::init (void)
 {
-#if defined (OCTAVE_USE_PUSH_PARSER)
-  parser_state = yypstate_new ();
-#endif
-
   LEXER = &lexer;
 }
 
@@ -3162,6 +3154,53 @@
   return octave_parse (*this);
 }
 
+octave_push_parser::~octave_push_parser (void)
+{
+  yypstate_delete (static_cast<yypstate *> (parser_state));
+}
+
+void
+octave_push_parser::init (void)
+{
+  parser_state = yypstate_new ();
+
+  octave_base_parser::init ();
+}
+
+// Parse input from INPUT.  Pass TRUE for EOF if the end of INPUT should
+// finish the parse.
+
+int
+octave_push_parser::run (const std::string& input, bool eof)
+{
+  int status = -1;
+
+  dynamic_cast<octave_push_lexer&> (lexer).append_input (input, eof);
+
+  do
+    {   
+      YYSTYPE lval;
+
+      int token = octave_lex (&lval, scanner);
+
+      if (token < 0)
+        {
+          if (! eof && lexer.at_end_of_buffer ())
+            {
+              status = -1;
+              break;
+            }
+        }
+
+      yypstate *pstate = static_cast<yypstate *> (parser_state);
+
+      status = octave_push_parse (pstate, token, &lval, *this);
+    }
+  while (status == YYPUSH_MORE);
+
+  return status;
+}
+
 static void
 safe_fclose (FILE *f)
 {
--- a/libinterp/parse-tree/parse.h	Wed Mar 13 02:46:56 2013 -0400
+++ b/libinterp/parse-tree/parse.h	Wed Mar 13 03:19:35 2013 -0400
@@ -137,7 +137,7 @@
       curr_fcn_depth (0), primary_fcn_scope (-1),
       curr_class_name (), function_scopes (), primary_fcn_ptr (0),
       stmt_list (0),
-      lexer (lxr), parser_state (0)
+      lexer (lxr)
   {
     init ();
   }
@@ -383,10 +383,6 @@
   // State of the lexer.
   octave_base_lexer& lexer;
 
-  // Internal state of the parser.  Only used if USE_PUSH_PARSER is
-  // defined.
-  void *parser_state;
-
 private:
 
   // No copying!
@@ -426,4 +422,33 @@
   octave_parser& operator = (const octave_parser&);
 };
 
+class
+octave_push_parser : public octave_base_parser
+{
+public:
+
+  octave_push_parser (void)
+    : octave_base_parser (*(new octave_push_lexer ())), parser_state (0)
+  {
+    init ();
+  }
+
+  ~octave_push_parser (void);
+
+  void init (void);
+
+  int run (const std::string& input, bool eof);
+
+private:
+
+  // Internal state of the Bison parser.
+  void *parser_state;
+
+  // No copying!
+
+  octave_push_parser (const octave_push_parser&);
+
+  octave_push_parser& operator = (const octave_push_parser&);
+};
+
 #endif