changeset 16224:4a848eb52de2

use stack for tracking lexer start states * lex.h (octave_lexer::start_state_stack): New member variable. (octave_lexer::push_start_state, octave_lexer::pop_start_state, octave_lexer::clear_start_state, octave_lexer::start_state, octave_lexer::display_start_state): New functions. * lex.ll (INPUT_FILE_START): Rename from INPUT_FILE_BEGIN. Use push_start_state and pop_start_state instead of switching flex start states directly with the flex BEGIN macro. (octave_lexer::init, octave_lexer::reset): Clear start state stack. (octave_lexer::prep_for_file, octave_lexer::process_comment, octave_lexer::handle_close_bracket): Don't use OCTAVE_YYG macro. (octave_lexer::display_start_state): Rename from display_state. Eliminate argument. Display current start state.
author John W. Eaton <jwe@octave.org>
date Fri, 08 Mar 2013 10:46:13 -0500
parents caf4f386aaab
children 28be9be86240
files libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll
diffstat 2 files changed, 98 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h	Thu Mar 07 16:35:12 2013 -0500
+++ b/libinterp/parse-tree/lex.h	Fri Mar 08 10:46:13 2013 -0500
@@ -524,11 +524,23 @@
     return input_source () == "eval_string";
   }
 
+  void push_start_state (int state);
+
+  void pop_start_state (void);
+
+  void clear_start_state (void);
+
+  int start_state (void) const { return start_state_stack.top (); }
+
+  void display_start_state (void) const;
+
   // For unwind protect.
   static void cleanup (octave_lexer *lexer) { delete lexer; }
 
 private:
 
+  std::stack<int> start_state_stack;
+
   // No copying!
 
   octave_lexer (const octave_lexer&);
--- a/libinterp/parse-tree/lex.ll	Thu Mar 07 16:35:12 2013 -0500
+++ b/libinterp/parse-tree/lex.ll	Fri Mar 08 10:46:13 2013 -0500
@@ -46,7 +46,7 @@
 %s COMMAND_START
 %s MATRIX_START
 
-%x INPUT_FILE_BEGIN
+%x INPUT_FILE_START
 
 %{
 
@@ -259,16 +259,17 @@
 // the parser go down a special path.
 %}
 
-<INPUT_FILE_BEGIN>. {
-    LEXER_DEBUG ("<INPUT_FILE_BEGIN>.");
-
-    BEGIN (INITIAL);
+<INPUT_FILE_START>. {
+    LEXER_DEBUG ("<INPUT_FILE_START>.");
+
     curr_lexer->xunput (yytext[0]);
 
     // May be reset later if we see "function" or "classdef" appears
     // as the first token.
     curr_lexer->reading_script_file = true;
 
+    curr_lexer->pop_start_state ();
+
     DISPLAY_TOK_AND_RETURN (INPUT_FILE);
   }
 
@@ -279,7 +280,6 @@
 <COMMAND_START>{NL} {
     LEXER_DEBUG ("<COMMAND_START>{NL}");
 
-    BEGIN (INITIAL);
     curr_lexer->input_line_number++;
     curr_lexer->current_input_column = 1;
 
@@ -288,6 +288,8 @@
     curr_lexer->looking_for_object_index = false;
     curr_lexer->at_beginning_of_statement = true;
 
+    curr_lexer->pop_start_state ();
+
     COUNT_TOK_AND_RETURN ('\n');
   }
 
@@ -297,7 +299,7 @@
     curr_lexer->looking_for_object_index = false;
     curr_lexer->at_beginning_of_statement = true;
 
-    BEGIN (INITIAL);
+    curr_lexer->pop_start_state ();
 
     if (strcmp (yytext, ",") == 0)
       TOK_RETURN (',');
@@ -542,7 +544,9 @@
     curr_lexer->eat_whitespace ();
 
     curr_lexer->bracketflag++;
-    BEGIN (MATRIX_START);
+
+    curr_lexer->push_start_state (MATRIX_START);
+
     COUNT_TOK_AND_RETURN ('[');
   }
 
@@ -924,7 +928,9 @@
     curr_lexer->eat_whitespace ();
 
     curr_lexer->braceflag++;
-    BEGIN (MATRIX_START);
+
+    curr_lexer->push_start_state (MATRIX_START);
+
     COUNT_TOK_AND_RETURN ('{');
   }
 
@@ -1424,13 +1430,15 @@
   // Make octave_lexer object available through yyextra in
   // flex-generated lexer.
   yyset_extra (this, scanner);
+
+  clear_start_state ();
 }
 
 // Inside Flex-generated functions, yyg is the scanner cast to its real
-// type.  The BEGIN macro uses yyg and we want to use that in
-// octave_lexer member functions.  If we could set the start state
-// by calling a function instead of using the BEGIN macro, we could
-// eliminate the OCTAVE_YYG macro.
+// type.  Some flex macros that we use in octave_lexer member functions
+// (for example, BEGIN) use yyg.  If we could perform the actions of
+// these macros with functions instead, we could eliminate the
+// OCTAVE_YYG macro.
 
 #define OCTAVE_YYG \
   struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner)
@@ -1438,10 +1446,8 @@
 void
 octave_lexer::reset (void)
 {
-  OCTAVE_YYG;
-
   // Start off on the right foot.
-  BEGIN (INITIAL);
+  clear_start_state ();
 
   parser_symtab_context.clear ();
 
@@ -1467,11 +1473,9 @@
 void
 octave_lexer::prep_for_file (void)
 {
-  OCTAVE_YYG;
-
   reading_script_file = true;
 
-  BEGIN (INPUT_FILE_BEGIN);
+  push_start_state (INPUT_FILE_START);
 }
 
 int
@@ -2157,8 +2161,6 @@
 int
 octave_lexer::process_comment (bool start_in_block, bool& eof)
 {
-  OCTAVE_YYG;
-
   eof = false;
 
   char *yytxt = flex_yytext ();
@@ -2185,8 +2187,8 @@
   convert_spaces_to_comma = true;
   at_beginning_of_statement = true;
 
-  if (YY_START == COMMAND_START)
-    BEGIN (INITIAL);
+  if (start_state () == COMMAND_START)
+    pop_start_state ();
 
   if (nesting_level.none ())
     return '\n';
@@ -2912,8 +2914,6 @@
 int
 octave_lexer::handle_close_bracket (bool spc_gobbled, int bracket_type)
 {
-  OCTAVE_YYG;
-
   int retval = bracket_type;
 
   if (! nesting_level.none ())
@@ -2928,8 +2928,7 @@
         panic_impossible ();
     }
 
-  if (bracketflag == 0 && braceflag == 0)
-    BEGIN (INITIAL);
+  pop_start_state ();
 
   if (bracket_type == ']'
       && next_token_is_assign_op ()
@@ -3477,7 +3476,7 @@
       if (at_bos && spc_gobbled && can_be_command (tok)
           && looks_like_command_arg ())
         {
-          BEGIN (COMMAND_START);
+          push_start_state (COMMAND_START);
         }
       else if (next_tok_is_eq
                || looking_at_decl_list
@@ -3744,35 +3743,6 @@
     }
 }
 
-static void
-display_state (int state)
-{
-  std::cerr << "S: ";
-
-  switch (state)
-    {
-    case INITIAL:
-      std::cerr << "INITIAL" << std::endl;
-      break;
-
-    case COMMAND_START:
-      std::cerr << "COMMAND_START" << std::endl;
-      break;
-
-    case MATRIX_START:
-      std::cerr << "MATRIX_START" << std::endl;
-      break;
-
-    case INPUT_FILE_BEGIN:
-      std::cerr << "INPUT_FILE_BEGIN" << std::endl;
-      break;
-
-    default:
-      std::cerr << "UNKNOWN START STATE!" << std::endl;
-      break;
-    }
-}
-
 void
 octave_lexer::fatal_error (const char *msg)
 {
@@ -3786,12 +3756,68 @@
 void
 octave_lexer::lexer_debug (const char *pattern, const char *text)
 {
-  OCTAVE_YYG;
-
   std::cerr << std::endl;
 
-  display_state (YY_START);
+  display_start_state ();
 
   std::cerr << "P: " << pattern << std::endl;
   std::cerr << "T: " << text << std::endl;
 }
+
+void
+octave_lexer::push_start_state (int state)
+{
+  OCTAVE_YYG;
+
+  start_state_stack.push (state);
+
+  BEGIN (start_state ());
+}
+
+void
+octave_lexer::pop_start_state (void)
+{
+  OCTAVE_YYG;
+
+  start_state_stack.pop ();
+
+  BEGIN (start_state ());
+}
+
+void
+octave_lexer::clear_start_state (void)
+{
+  while (! start_state_stack.empty ())
+    start_state_stack.pop ();
+
+  push_start_state (INITIAL);
+}
+
+void
+octave_lexer::display_start_state (void) const
+{
+  std::cerr << "S: ";
+
+  switch (start_state ())
+    {
+    case INITIAL:
+      std::cerr << "INITIAL" << std::endl;
+      break;
+
+    case COMMAND_START:
+      std::cerr << "COMMAND_START" << std::endl;
+      break;
+
+    case MATRIX_START:
+      std::cerr << "MATRIX_START" << std::endl;
+      break;
+
+    case INPUT_FILE_START:
+      std::cerr << "INPUT_FILE_BEGIN" << std::endl;
+      break;
+
+    default:
+      std::cerr << "UNKNOWN START STATE!" << std::endl;
+      break;
+    }
+}