changeset 16110:7302f8a4df83

use pointer for global lexical_feedback structure * lex.h, lex.ll (curr_lexer): Rename from lexer_flags. Declare as pointer. Change all uses. * lex.h (lexical_feedback): Make copy constructor and operator= private. * toplev.cc (main_loop): Protect existing and initialize new curr_lexer. * input.cc (get_debug_input): Likewise.
author John W. Eaton <jwe@octave.org>
date Tue, 26 Feb 2013 01:10:08 -0500
parents 229eb14653fd
children 3ec4f6488569
files libinterp/interpfcn/input.cc libinterp/interpfcn/toplev.cc libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.yy
diffstat 5 files changed, 404 insertions(+), 458 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/interpfcn/input.cc	Tue Feb 26 00:45:43 2013 -0500
+++ b/libinterp/interpfcn/input.cc	Tue Feb 26 01:10:08 2013 -0500
@@ -678,6 +678,9 @@
       switch_to_buffer (new_buf);
     }
 
+  frame.protect_var (curr_lexer);
+  curr_lexer = new lexical_feedback ();
+
   while (Vdebugging)
     {
       reset_error_handler ();
@@ -1193,7 +1196,7 @@
 static int
 input_event_hook (void)
 {
-  if (! lexer_flags.defining_func)
+  if (! curr_lexer->defining_func)
     {
       hook_fcn_map_type::iterator p = hook_fcn_map.begin ();
 
--- a/libinterp/interpfcn/toplev.cc	Tue Feb 26 00:45:43 2013 -0500
+++ b/libinterp/interpfcn/toplev.cc	Tue Feb 26 01:10:08 2013 -0500
@@ -557,6 +557,11 @@
 
   octave_initialized = true;
 
+  unwind_protect frame;
+
+  frame.protect_var (curr_lexer);
+  curr_lexer = new lexical_feedback ();
+
   // The big loop.
 
   int retval = 0;
@@ -564,7 +569,7 @@
     {
       try
         {
-          unwind_protect frame;
+          unwind_protect inner_frame;
 
           reset_error_handler ();
 
@@ -631,7 +636,7 @@
                         command_editor::increment_current_command_number ();
                     }
                 }
-              else if (lexer_flags.parser_end_of_input)
+              else if (curr_lexer->parser_end_of_input)
                 break;
             }
         }
--- a/libinterp/parse-tree/lex.h	Tue Feb 26 00:45:43 2013 -0500
+++ b/libinterp/parse-tree/lex.h	Tue Feb 26 01:10:08 2013 -0500
@@ -175,74 +175,6 @@
     init ();
   }
 
-  lexical_feedback (const lexical_feedback& lf)
-    : convert_spaces_to_comma (lf.convert_spaces_to_comma),
-      do_comma_insert (lf.do_comma_insert),
-      at_beginning_of_statement (lf.at_beginning_of_statement),
-      looking_at_anon_fcn_args (lf.looking_at_anon_fcn_args),
-      looking_at_return_list (lf.looking_at_return_list),
-      looking_at_parameter_list (lf.looking_at_parameter_list),
-      looking_at_decl_list (lf.looking_at_decl_list),
-      looking_at_initializer_expression (lf.looking_at_initializer_expression),
-      looking_at_matrix_or_assign_lhs (lf.looking_at_matrix_or_assign_lhs),
-      looking_for_object_index (lf.looking_for_object_index),
-      looking_at_indirect_ref (lf.looking_at_indirect_ref),
-      parsing_class_method (lf.parsing_class_method),
-      maybe_classdef_get_set_method (lf.maybe_classdef_get_set_method),
-      parsing_classdef (lf.parsing_classdef),
-      quote_is_transpose (lf.quote_is_transpose),
-      parser_end_of_input (lf.parser_end_of_input),
-      input_line_number (lf.input_line_number),
-      current_input_column (lf.current_input_column),
-      bracketflag (lf.bracketflag),
-      braceflag (lf.braceflag),
-      looping (lf.looping),
-      defining_func (lf.defining_func),
-      looking_at_function_handle (lf.looking_at_function_handle),
-      block_comment_nesting_level (lf.block_comment_nesting_level),
-      looking_at_object_index (lf.looking_at_object_index),
-      parsed_function_name (lf.parsed_function_name),
-      pending_local_variables (lf.pending_local_variables),
-      nesting_level (lf.nesting_level)
-  { }
-
-  lexical_feedback& operator = (const lexical_feedback& lf)
-  {
-    if (&lf != this)
-      {
-        convert_spaces_to_comma = lf.convert_spaces_to_comma;
-        do_comma_insert = lf.do_comma_insert;
-        at_beginning_of_statement = lf.at_beginning_of_statement;
-        looking_at_anon_fcn_args = lf.looking_at_anon_fcn_args;
-        looking_at_return_list = lf.looking_at_return_list;
-        looking_at_parameter_list = lf.looking_at_parameter_list;
-        looking_at_decl_list = lf.looking_at_decl_list;
-        looking_at_initializer_expression = lf.looking_at_initializer_expression;
-        looking_at_matrix_or_assign_lhs = lf.looking_at_matrix_or_assign_lhs;
-        looking_for_object_index = lf.looking_for_object_index;
-        looking_at_indirect_ref = lf.looking_at_indirect_ref;
-        parsing_class_method = lf.parsing_class_method;
-        maybe_classdef_get_set_method = lf.maybe_classdef_get_set_method;
-        parsing_classdef = lf.parsing_classdef;
-        quote_is_transpose = lf.quote_is_transpose;
-        parser_end_of_input = lf.parser_end_of_input;
-        input_line_number = lf.input_line_number;
-        current_input_column = lf.current_input_column;
-        bracketflag = lf.bracketflag;
-        braceflag = lf.braceflag;
-        looping = lf.looping;
-        defining_func = lf.defining_func;
-        looking_at_function_handle = lf.looking_at_function_handle;
-        block_comment_nesting_level = lf.block_comment_nesting_level,
-        looking_at_object_index = lf.looking_at_object_index;
-        parsed_function_name = lf.parsed_function_name;
-        pending_local_variables = lf.pending_local_variables;
-        nesting_level = lf.nesting_level;
-      }
-
-    return *this;
-  }
-
   ~lexical_feedback (void) { }
 
   void init (void)
@@ -347,6 +279,14 @@
   // Is the closest nesting level a square bracket, squiggly brace or
   // a paren?
   bbp_nesting_level nesting_level;
+
+private:
+
+  // No copying!
+
+  lexical_feedback (const lexical_feedback&);
+
+  lexical_feedback& operator = (const lexical_feedback&);
 };
 
 class
@@ -370,7 +310,7 @@
 extern std::string
 grab_comment_block (stream_reader& reader, bool at_bol, bool& eof);
 
-// Flags that need to be shared between the lexer and parser.
-extern lexical_feedback lexer_flags;
+// The current state of the lexer.
+extern lexical_feedback *curr_lexer;
 
 #endif
--- a/libinterp/parse-tree/lex.ll	Tue Feb 26 00:45:43 2013 -0500
+++ b/libinterp/parse-tree/lex.ll	Tue Feb 26 01:10:08 2013 -0500
@@ -148,9 +148,9 @@
 #define TOK_RETURN(tok) \
   do \
     { \
-      lexer_flags.current_input_column += yyleng; \
-      lexer_flags.quote_is_transpose = false; \
-      lexer_flags.convert_spaces_to_comma = true; \
+      curr_lexer->current_input_column += yyleng; \
+      curr_lexer->quote_is_transpose = false; \
+      curr_lexer->convert_spaces_to_comma = true; \
       COUNT_TOK_AND_RETURN (tok); \
     } \
   while (0)
@@ -158,8 +158,8 @@
 #define TOK_PUSH_AND_RETURN(name, tok) \
   do \
     { \
-      yylval.tok_val = new token (name, lexer_flags.input_line_number, \
-                                  lexer_flags.current_input_column); \
+      yylval.tok_val = new token (name, curr_lexer->input_line_number, \
+                                  curr_lexer->current_input_column); \
       token_stack.push (yylval.tok_val); \
       TOK_RETURN (tok); \
     } \
@@ -168,14 +168,14 @@
 #define BIN_OP_RETURN_INTERNAL(tok, convert, bos, qit) \
   do \
     { \
-      yylval.tok_val = new token (lexer_flags.input_line_number, \
-                                  lexer_flags.current_input_column); \
+      yylval.tok_val = new token (curr_lexer->input_line_number, \
+                                  curr_lexer->current_input_column); \
       token_stack.push (yylval.tok_val); \
-      lexer_flags.current_input_column += yyleng; \
-      lexer_flags.quote_is_transpose = qit; \
-      lexer_flags.convert_spaces_to_comma = convert; \
-      lexer_flags.looking_for_object_index = false; \
-      lexer_flags.at_beginning_of_statement = bos; \
+      curr_lexer->current_input_column += yyleng; \
+      curr_lexer->quote_is_transpose = qit; \
+      curr_lexer->convert_spaces_to_comma = convert; \
+      curr_lexer->looking_for_object_index = false; \
+      curr_lexer->at_beginning_of_statement = bos; \
       COUNT_TOK_AND_RETURN (tok); \
     } \
   while (0)
@@ -212,7 +212,7 @@
   while (0)
 
 // The state of the lexer.
-lexical_feedback lexer_flags;
+lexical_feedback *curr_lexer = 0;
 
 // Stack to hold tokens so that we can delete them when the parser is
 // reset and avoid growing forever just because we are stashing some
@@ -315,13 +315,13 @@
     LEXER_DEBUG ("<COMMAND_START>{NL}");
 
     BEGIN (INITIAL);
-    lexer_flags.input_line_number++;
-    lexer_flags.current_input_column = 1;
-
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = true;
+    curr_lexer->input_line_number++;
+    curr_lexer->current_input_column = 1;
+
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = true;
 
     COUNT_TOK_AND_RETURN ('\n');
   }
@@ -329,8 +329,8 @@
 <COMMAND_START>[\;\,] {
     LEXER_DEBUG ("<COMMAND_START>[\\;\\,]");
 
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = true;
 
     BEGIN (INITIAL);
 
@@ -343,9 +343,9 @@
 <COMMAND_START>[\"\'] {
     LEXER_DEBUG ("<COMMAND_START>[\\\"\\']");
 
-    lexer_flags.at_beginning_of_statement = false;
-
-    lexer_flags.current_input_column++;
+    curr_lexer->at_beginning_of_statement = false;
+
+    curr_lexer->current_input_column++;
     int tok = handle_string (yytext[0]);
 
     COUNT_TOK_AND_RETURN (tok);
@@ -356,8 +356,8 @@
 
     std::string tok = strip_trailing_whitespace (yytext);
 
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
 
     TOK_PUSH_AND_RETURN (tok, SQ_STRING);
   }
@@ -382,10 +382,10 @@
     scan_for_comments (yytext);
     fixup_column_count (yytext);
 
-    lexer_flags.looking_at_object_index.pop_front ();
-
-    lexer_flags.looking_for_object_index = true;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->looking_at_object_index.pop_front ();
+
+    curr_lexer->looking_for_object_index = true;
+    curr_lexer->at_beginning_of_statement = false;
 
     int c = yytext[yyleng-1];
     bool cont_is_spc = (eat_continuation () != lexical_feedback::NO_WHITESPACE);
@@ -408,10 +408,10 @@
     scan_for_comments (yytext);
     fixup_column_count (yytext);
 
-    lexer_flags.looking_at_object_index.pop_front ();
-
-    lexer_flags.looking_for_object_index = true;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->looking_at_object_index.pop_front ();
+
+    curr_lexer->looking_for_object_index = true;
+    curr_lexer->at_beginning_of_statement = false;
 
     int c = yytext[yyleng-1];
     bool cont_is_spc = (eat_continuation () != lexical_feedback::NO_WHITESPACE);
@@ -433,16 +433,16 @@
 <MATRIX_START>{S}*\,{S}* {
     LEXER_DEBUG ("<MATRIX_START>{S}*\\,{S}*");
 
-    lexer_flags.current_input_column += yyleng;
+    curr_lexer->current_input_column += yyleng;
 
     int tmp = eat_continuation ();
 
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
-
-    if (! lexer_flags.looking_at_object_index.front ())
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
+
+    if (! curr_lexer->looking_at_object_index.front ())
       {
         if ((tmp & lexical_feedback::NEWLINE) == lexical_feedback::NEWLINE)
           {
@@ -465,21 +465,21 @@
 <MATRIX_START>{S}+ {
     LEXER_DEBUG ("<MATRIX_START>{S}+");
 
-    lexer_flags.current_input_column += yyleng;
-
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->current_input_column += yyleng;
+
+    curr_lexer->at_beginning_of_statement = false;
 
     int tmp = eat_continuation ();
 
-    if (! lexer_flags.looking_at_object_index.front ())
+    if (! curr_lexer->looking_at_object_index.front ())
       {
         bool bin_op = next_token_is_bin_op (true);
         bool postfix_un_op = next_token_is_postfix_unary_op (true);
         bool sep_op = next_token_is_sep_op ();
 
         if (! (postfix_un_op || bin_op || sep_op)
-            && lexer_flags.nesting_level.is_bracket_or_brace ()
-            && lexer_flags.convert_spaces_to_comma)
+            && curr_lexer->nesting_level.is_bracket_or_brace ()
+            && curr_lexer->convert_spaces_to_comma)
           {
             if ((tmp & lexical_feedback::NEWLINE) == lexical_feedback::NEWLINE)
               {
@@ -488,9 +488,9 @@
                 xunput (';', yytext);
               }
 
-            lexer_flags.quote_is_transpose = false;
-            lexer_flags.convert_spaces_to_comma = true;
-            lexer_flags.looking_for_object_index = false;
+            curr_lexer->quote_is_transpose = false;
+            curr_lexer->convert_spaces_to_comma = true;
+            curr_lexer->looking_for_object_index = false;
 
             maybe_warn_separator_insert (',');
 
@@ -514,10 +514,10 @@
     fixup_column_count (yytext);
     eat_whitespace ();
 
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
 
     COUNT_TOK_AND_RETURN (';');
   }
@@ -538,15 +538,15 @@
     fixup_column_count (yytext);
     eat_whitespace ();
 
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.at_beginning_of_statement = false;
-
-    if (lexer_flags.nesting_level.none ())
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->at_beginning_of_statement = false;
+
+    if (curr_lexer->nesting_level.none ())
       return LEXICAL_ERROR;
 
-    if (! lexer_flags.looking_at_object_index.front ()
-        && lexer_flags.nesting_level.is_bracket_or_brace ())
+    if (! curr_lexer->looking_at_object_index.front ()
+        && curr_lexer->nesting_level.is_bracket_or_brace ())
       {
         maybe_warn_separator_insert (';');
 
@@ -557,26 +557,26 @@
 \[{S}* {
     LEXER_DEBUG ("\\[{S}*");
 
-    lexer_flags.nesting_level.bracket ();
-
-    lexer_flags.looking_at_object_index.push_front (false);
-
-    lexer_flags.current_input_column += yyleng;
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
-
-    if (lexer_flags.defining_func
-        && ! lexer_flags.parsed_function_name.top ())
-      lexer_flags.looking_at_return_list = true;
+    curr_lexer->nesting_level.bracket ();
+
+    curr_lexer->looking_at_object_index.push_front (false);
+
+    curr_lexer->current_input_column += yyleng;
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
+
+    if (curr_lexer->defining_func
+        && ! curr_lexer->parsed_function_name.top ())
+      curr_lexer->looking_at_return_list = true;
     else
-      lexer_flags.looking_at_matrix_or_assign_lhs = true;
+      curr_lexer->looking_at_matrix_or_assign_lhs = true;
 
     promptflag--;
     eat_whitespace ();
 
-    lexer_flags.bracketflag++;
+    curr_lexer->bracketflag++;
     BEGIN (MATRIX_START);
     COUNT_TOK_AND_RETURN ('[');
   }
@@ -584,12 +584,12 @@
 \] {
     LEXER_DEBUG ("\\]");
 
-    lexer_flags.nesting_level.remove ();
-
-    lexer_flags.looking_at_object_index.pop_front ();
-
-    lexer_flags.looking_for_object_index = true;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->nesting_level.remove ();
+
+    curr_lexer->looking_at_object_index.pop_front ();
+
+    curr_lexer->looking_for_object_index = true;
+    curr_lexer->at_beginning_of_statement = false;
 
     TOK_RETURN (']');
   }
@@ -623,7 +623,7 @@
 %}
 
 {S}* {
-    lexer_flags.current_input_column += yyleng;
+    curr_lexer->current_input_column += yyleng;
   }
 
 %{
@@ -638,8 +638,8 @@
       gripe_matlab_incompatible_continuation ();
     scan_for_comments (yytext);
     promptflag--;
-    lexer_flags.input_line_number++;
-    lexer_flags.current_input_column = 1;
+    curr_lexer->input_line_number++;
+    curr_lexer->current_input_column = 1;
   }
 
 %{
@@ -649,14 +649,14 @@
 <<EOF>> {
     LEXER_DEBUG ("<<EOF>>");
 
-    if (lexer_flags.block_comment_nesting_level != 0)
+    if (curr_lexer->block_comment_nesting_level != 0)
       {
         warning ("block comment open at end of input");
 
         if ((reading_fcn_file || reading_script_file || reading_classdef_file)
             && ! curr_fcn_file_name.empty ())
           warning ("near line %d of file '%s.m'",
-                   lexer_flags.input_line_number, curr_fcn_file_name.c_str ());
+                   curr_lexer->input_line_number, curr_fcn_file_name.c_str ());
       }
 
     TOK_RETURN (END_OF_INPUT);
@@ -688,7 +688,7 @@
 
     if (id_tok >= 0)
       {
-        lexer_flags.looking_for_object_index = true;
+        curr_lexer->looking_for_object_index = true;
 
         COUNT_TOK_AND_RETURN (SUPERCLASSREF);
       }
@@ -706,7 +706,7 @@
 
     if (id_tok >= 0)
       {
-        lexer_flags.looking_for_object_index = true;
+        curr_lexer->looking_for_object_index = true;
 
         COUNT_TOK_AND_RETURN (METAQUERY);
       }
@@ -719,13 +719,13 @@
 "@" {
     LEXER_DEBUG ("@");
 
-    lexer_flags.current_input_column++;
-
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = false;
-    lexer_flags.looking_at_function_handle++;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->current_input_column++;
+
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = false;
+    curr_lexer->looking_at_function_handle++;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
 
     COUNT_TOK_AND_RETURN ('@');
 
@@ -740,23 +740,23 @@
 {NL} {
     LEXER_DEBUG ("{NL}");
 
-    lexer_flags.input_line_number++;
-    lexer_flags.current_input_column = 1;
-
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-
-    if (lexer_flags.nesting_level.none ())
+    curr_lexer->input_line_number++;
+    curr_lexer->current_input_column = 1;
+
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+
+    if (curr_lexer->nesting_level.none ())
       {
-        lexer_flags.at_beginning_of_statement = true;
+        curr_lexer->at_beginning_of_statement = true;
         COUNT_TOK_AND_RETURN ('\n');
       }
-    else if (lexer_flags.nesting_level.is_paren ())
+    else if (curr_lexer->nesting_level.is_paren ())
       {
-        lexer_flags.at_beginning_of_statement = false;
+        curr_lexer->at_beginning_of_statement = false;
         gripe_matlab_incompatible ("bare newline inside parentheses");
       }
-    else if (lexer_flags.nesting_level.is_bracket_or_brace ())
+    else if (curr_lexer->nesting_level.is_bracket_or_brace ())
       return LEXICAL_ERROR;
   }
 
@@ -768,10 +768,10 @@
 "'" {
     LEXER_DEBUG ("'");
 
-    lexer_flags.current_input_column++;
-    lexer_flags.convert_spaces_to_comma = true;
-
-    if (lexer_flags.quote_is_transpose)
+    curr_lexer->current_input_column++;
+    curr_lexer->convert_spaces_to_comma = true;
+
+    if (curr_lexer->quote_is_transpose)
       {
         do_comma_insert_check ();
         COUNT_TOK_AND_RETURN (QUOTE);
@@ -790,7 +790,7 @@
 \" {
     LEXER_DEBUG ("\"");
 
-    lexer_flags.current_input_column++;
+    curr_lexer->current_input_column++;
     int tok = handle_string ('"');
 
     COUNT_TOK_AND_RETURN (tok);
@@ -803,7 +803,7 @@
 {CCHAR} {
     LEXER_DEBUG ("{CCHAR}");
 
-    lexer_flags.looking_for_object_index = false;
+    curr_lexer->looking_for_object_index = false;
 
     xunput (yytext[0], yytext);
 
@@ -823,11 +823,11 @@
 ^{S}*{CCHAR}\{{S}*{NL} {
     LEXER_DEBUG ("^{S}*{CCHAR}\\{{S}*{NL}");
 
-    lexer_flags.looking_for_object_index = false;
-
-    lexer_flags.input_line_number++;
-    lexer_flags.current_input_column = 1;
-    lexer_flags.block_comment_nesting_level++;
+    curr_lexer->looking_for_object_index = false;
+
+    curr_lexer->input_line_number++;
+    curr_lexer->current_input_column = 1;
+    curr_lexer->block_comment_nesting_level++;
     promptflag--;
 
     bool eof = false;
@@ -865,7 +865,7 @@
 "/"     { LEXER_DEBUG ("/"); BIN_OP_RETURN ('/', false, false); }
 "\\"    { LEXER_DEBUG ("\\"); BIN_OP_RETURN (LEFTDIV, false, false); }
 ";"     { LEXER_DEBUG (";"); BIN_OP_RETURN (';', true, true); }
-","     { LEXER_DEBUG (","); BIN_OP_RETURN (',', true, ! lexer_flags.looking_at_object_index.front ()); }
+","     { LEXER_DEBUG (","); BIN_OP_RETURN (',', true, ! curr_lexer->looking_at_object_index.front ()); }
 "^"     { LEXER_DEBUG ("^"); BIN_OP_RETURN (POW, false, false); }
 "**"    { LEXER_DEBUG ("**"); XBIN_OP_RETURN (POW, false, false); }
 "="     { LEXER_DEBUG ("="); BIN_OP_RETURN ('=', true, false); }
@@ -891,14 +891,14 @@
     // is current (so that we can pop it off the stack when we find
     // the matching close paren).
 
-    lexer_flags.looking_at_object_index.push_front
-      (lexer_flags.looking_for_object_index);
-
-    lexer_flags.looking_at_indirect_ref = false;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
-
-    lexer_flags.nesting_level.paren ();
+    curr_lexer->looking_at_object_index.push_front
+      (curr_lexer->looking_for_object_index);
+
+    curr_lexer->looking_at_indirect_ref = false;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
+
+    curr_lexer->nesting_level.paren ();
     promptflag--;
 
     TOK_RETURN ('(');
@@ -907,20 +907,20 @@
 ")" {
     LEXER_DEBUG (")");
 
-    lexer_flags.nesting_level.remove ();
-    lexer_flags.current_input_column++;
-
-    lexer_flags.looking_at_object_index.pop_front ();
-
-    lexer_flags.quote_is_transpose = true;
-    lexer_flags.convert_spaces_to_comma
-      = (lexer_flags.nesting_level.is_bracket_or_brace ()
-         && ! lexer_flags.looking_at_anon_fcn_args);
-    lexer_flags.looking_for_object_index = true;
-    lexer_flags.at_beginning_of_statement = false;
-
-    if (lexer_flags.looking_at_anon_fcn_args)
-      lexer_flags.looking_at_anon_fcn_args = false;
+    curr_lexer->nesting_level.remove ();
+    curr_lexer->current_input_column++;
+
+    curr_lexer->looking_at_object_index.pop_front ();
+
+    curr_lexer->quote_is_transpose = true;
+    curr_lexer->convert_spaces_to_comma
+      = (curr_lexer->nesting_level.is_bracket_or_brace ()
+         && ! curr_lexer->looking_at_anon_fcn_args);
+    curr_lexer->looking_for_object_index = true;
+    curr_lexer->at_beginning_of_statement = false;
+
+    if (curr_lexer->looking_at_anon_fcn_args)
+      curr_lexer->looking_at_anon_fcn_args = false;
 
     do_comma_insert_check ();
 
@@ -930,8 +930,8 @@
 "." {
     LEXER_DEBUG (".");
 
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
 
     TOK_RETURN ('.');
   }
@@ -956,21 +956,21 @@
 \{{S}* {
     LEXER_DEBUG ("\\{{S}*");
 
-    lexer_flags.nesting_level.brace ();
-
-    lexer_flags.looking_at_object_index.push_front
-      (lexer_flags.looking_for_object_index);
-
-    lexer_flags.current_input_column += yyleng;
-    lexer_flags.quote_is_transpose = false;
-    lexer_flags.convert_spaces_to_comma = true;
-    lexer_flags.looking_for_object_index = false;
-    lexer_flags.at_beginning_of_statement = false;
+    curr_lexer->nesting_level.brace ();
+
+    curr_lexer->looking_at_object_index.push_front
+      (curr_lexer->looking_for_object_index);
+
+    curr_lexer->current_input_column += yyleng;
+    curr_lexer->quote_is_transpose = false;
+    curr_lexer->convert_spaces_to_comma = true;
+    curr_lexer->looking_for_object_index = false;
+    curr_lexer->at_beginning_of_statement = false;
 
     promptflag--;
     eat_whitespace ();
 
-    lexer_flags.braceflag++;
+    curr_lexer->braceflag++;
     BEGIN (MATRIX_START);
     COUNT_TOK_AND_RETURN ('{');
   }
@@ -978,12 +978,12 @@
 "}" {
     LEXER_DEBUG ("}");
 
-    lexer_flags.looking_at_object_index.pop_front ();
-
-    lexer_flags.looking_for_object_index = true;
-    lexer_flags.at_beginning_of_statement = false;
-
-    lexer_flags.nesting_level.remove ();
+    curr_lexer->looking_at_object_index.pop_front ();
+
+    curr_lexer->looking_for_object_index = true;
+    curr_lexer->at_beginning_of_statement = false;
+
+    curr_lexer->nesting_level.remove ();
 
     TOK_RETURN ('}');
   }
@@ -1001,11 +1001,11 @@
 
     if (c != EOF)
       {
-        lexer_flags.current_input_column++;
+        curr_lexer->current_input_column++;
 
         error ("invalid character '%s' (ASCII %d) near line %d, column %d",
                undo_string_escape (static_cast<char> (c)), c,
-               lexer_flags.input_line_number, lexer_flags.current_input_column);
+               curr_lexer->input_line_number, curr_lexer->current_input_column);
 
         return LEXICAL_ERROR;
       }
@@ -1032,8 +1032,8 @@
   if (spc_gobbled)
     xunput (' ', yytext);
 
-  lexer_flags.do_comma_insert = (! lexer_flags.looking_at_object_index.front ()
-                                 && lexer_flags.bracketflag && c == '[');
+  curr_lexer->do_comma_insert = (! curr_lexer->looking_at_object_index.front ()
+                                 && curr_lexer->bracketflag && c == '[');
 }
 
 // Fix things up for errors or interrupts.  The parser is never called
@@ -1074,9 +1074,6 @@
   // Clear the buffer for help text.
   while (! help_buf.empty ())
     help_buf.pop ();
-
-  // Reset other flags.
-  lexer_flags = lexical_feedback ();
 }
 
 static void
@@ -1258,7 +1255,7 @@
     }
 
   if (c == '\n')
-    lexer_flags.input_line_number++;
+    curr_lexer->input_line_number++;
 
   return c;
 }
@@ -1274,7 +1271,7 @@
     }
 
   if (c == '\n')
-    lexer_flags.input_line_number--;
+    curr_lexer->input_line_number--;
 
   yyunput (c, buf);
 }
@@ -1290,11 +1287,11 @@
     {
       if (c == '\n')
         {
-          lexer_flags.input_line_number++;
-          lexer_flags.current_input_column = 1;
+          curr_lexer->input_line_number++;
+          curr_lexer->current_input_column = 1;
         }
       else
-        lexer_flags.current_input_column++;
+        curr_lexer->current_input_column++;
     }
 }
 
@@ -1379,8 +1376,8 @@
 {
   bool retval = false;
 
-  for (std::list<bool>::const_iterator i = lexer_flags.looking_at_object_index.begin ();
-       i != lexer_flags.looking_at_object_index.end (); i++)
+  for (std::list<bool>::const_iterator i = curr_lexer->looking_at_object_index.begin ();
+       i != curr_lexer->looking_at_object_index.end (); i++)
     {
       if (*i)
         {
@@ -1397,8 +1394,8 @@
 static int
 is_keyword_token (const std::string& s)
 {
-  int l = lexer_flags.input_line_number;
-  int c = lexer_flags.current_input_column;
+  int l = curr_lexer->input_line_number;
+  int c = curr_lexer->current_input_column;
 
   int len = s.length ();
 
@@ -1417,7 +1414,7 @@
         case otherwise_kw:
         case return_kw:
         case unwind_protect_cleanup_kw:
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case static_kw:
@@ -1426,12 +1423,12 @@
               && ! curr_fcn_file_full_name.empty ())
             warning_with_id ("Octave:deprecated-keyword",
                              "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d of file '%s'",
-                             lexer_flags.input_line_number,
+                             curr_lexer->input_line_number,
                              curr_fcn_file_full_name.c_str ());
           else
             warning_with_id ("Octave:deprecated-keyword",
                              "the 'static' keyword is obsolete and will be removed from a future version of Octave; please use 'persistent' instead; near line %d",
-                             lexer_flags.input_line_number);
+                             curr_lexer->input_line_number);
           // fall through ...
 
         case persistent_kw:
@@ -1446,78 +1443,78 @@
         case end_kw:
           if (inside_any_object_index ()
               || (! reading_classdef_file
-                  && (lexer_flags.defining_func
-                      && ! (lexer_flags.looking_at_return_list
-                            || lexer_flags.parsed_function_name.top ()))))
+                  && (curr_lexer->defining_func
+                      && ! (curr_lexer->looking_at_return_list
+                            || curr_lexer->parsed_function_name.top ()))))
             return 0;
 
           yylval.tok_val = new token (token::simple_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case end_try_catch_kw:
           yylval.tok_val = new token (token::try_catch_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case end_unwind_protect_kw:
           yylval.tok_val = new token (token::unwind_protect_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endfor_kw:
           yylval.tok_val = new token (token::for_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endfunction_kw:
           yylval.tok_val = new token (token::function_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endif_kw:
           yylval.tok_val = new token (token::if_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endparfor_kw:
           yylval.tok_val = new token (token::parfor_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endswitch_kw:
           yylval.tok_val = new token (token::switch_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endwhile_kw:
           yylval.tok_val = new token (token::while_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endclassdef_kw:
           yylval.tok_val = new token (token::classdef_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endenumeration_kw:
           yylval.tok_val = new token (token::enumeration_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endevents_kw:
           yylval.tok_val = new token (token::events_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endmethods_kw:
           yylval.tok_val = new token (token::methods_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
         case endproperties_kw:
           yylval.tok_val = new token (token::properties_end, l, c);
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           break;
 
 
@@ -1525,18 +1522,18 @@
         case parfor_kw:
         case while_kw:
           promptflag--;
-          lexer_flags.looping++;
+          curr_lexer->looping++;
           break;
 
         case do_kw:
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           promptflag--;
-          lexer_flags.looping++;
+          curr_lexer->looping++;
           break;
 
         case try_kw:
         case unwind_protect_kw:
-          lexer_flags.at_beginning_of_statement = true;
+          curr_lexer->at_beginning_of_statement = true;
           promptflag--;
           break;
 
@@ -1549,7 +1546,7 @@
         case set_kw:
           // 'get' and 'set' are keywords in classdef method
           // declarations.
-          if (! lexer_flags.maybe_classdef_get_set_method)
+          if (! curr_lexer->maybe_classdef_get_set_method)
             return 0;
           break;
 
@@ -1559,7 +1556,7 @@
         case properties_kw:
           // 'properties', 'methods' and 'events' are keywords for
           // classdef blocks.
-          if (! lexer_flags.parsing_classdef)
+          if (! curr_lexer->parsing_classdef)
             return 0;
           // fall through ...
 
@@ -1571,12 +1568,12 @@
         case function_kw:
           promptflag--;
 
-          lexer_flags.defining_func++;
-          lexer_flags.parsed_function_name.push (false);
+          curr_lexer->defining_func++;
+          curr_lexer->parsed_function_name.push (false);
 
           if (! (reading_fcn_file || reading_script_file
                  || reading_classdef_file))
-            lexer_flags.input_line_number = 1;
+            curr_lexer->input_line_number = 1;
           break;
 
         case magic_file_kw:
@@ -1613,8 +1610,8 @@
 is_variable (const std::string& name)
 {
   return (symbol_table::is_variable (name)
-          || (lexer_flags.pending_local_variables.find (name)
-              != lexer_flags.pending_local_variables.end ()));
+          || (curr_lexer->pending_local_variables.find (name)
+              != curr_lexer->pending_local_variables.end ()));
 }
 
 static std::string
@@ -1631,7 +1628,7 @@
 
   while ((c = reader.getc ()) != EOF)
     {
-      lexer_flags.current_input_column++;
+      curr_lexer->current_input_column++;
 
       if (look_for_marker)
         {
@@ -1648,7 +1645,7 @@
 
               while ((c = reader.getc ()) != EOF && ! done)
                 {
-                  lexer_flags.current_input_column++;
+                  curr_lexer->current_input_column++;
 
                   switch (c)
                     {
@@ -1659,21 +1656,21 @@
 
                     case '\n':
                       {
-                        lexer_flags.current_input_column = 0;
+                        curr_lexer->current_input_column = 0;
                         at_bol = true;
                         done = true;
 
                         if (type == '{')
                           {
-                            lexer_flags.block_comment_nesting_level++;
+                            curr_lexer->block_comment_nesting_level++;
                             promptflag--;
                           }
                         else
                           {
-                            lexer_flags.block_comment_nesting_level--;
+                            curr_lexer->block_comment_nesting_level--;
                             promptflag++;
 
-                            if (lexer_flags.block_comment_nesting_level == 0)
+                            if (curr_lexer->block_comment_nesting_level == 0)
                               {
                                 buf += grab_comment_block (reader, true, eof);
 
@@ -1711,7 +1708,7 @@
 
           if (c == '\n')
             {
-              lexer_flags.current_input_column = 0;
+              curr_lexer->current_input_column = 0;
               at_bol = true;
             }
         }
@@ -1741,7 +1738,7 @@
 
   while ((c = reader.getc ()) != EOF)
     {
-      lexer_flags.current_input_column++;
+      curr_lexer->current_input_column++;
 
       if (begin_comment)
         {
@@ -1758,7 +1755,7 @@
 
               while ((c = reader.getc ()) != EOF && ! done)
                 {
-                  lexer_flags.current_input_column++;
+                  curr_lexer->current_input_column++;
 
                   switch (c)
                     {
@@ -1769,11 +1766,11 @@
 
                     case '\n':
                       {
-                        lexer_flags.current_input_column = 0;
+                        curr_lexer->current_input_column = 0;
                         at_bol = true;
                         done = true;
 
-                        lexer_flags.block_comment_nesting_level++;
+                        curr_lexer->block_comment_nesting_level++;
                         promptflag--;
 
                         buf += grab_block_comment (reader, eof);
@@ -1808,7 +1805,7 @@
           if (c == '\n')
             {
               at_bol = true;
-              lexer_flags.current_input_column = 0;
+              curr_lexer->current_input_column = 0;
               in_comment = false;
 
               // FIXME -- bailing out here prevents things like
@@ -1848,7 +1845,7 @@
               break;
 
             default:
-              lexer_flags.current_input_column--;
+              curr_lexer->current_input_column--;
               reader.ungetc (c);
               goto done;
             }
@@ -1905,7 +1902,7 @@
   if (lexer_debug_flag)
     std::cerr << "C: " << txt << std::endl;
 
-  if (help_txt.empty () && lexer_flags.nesting_level.none ())
+  if (help_txt.empty () && curr_lexer->nesting_level.none ())
     {
       if (! help_buf.empty ())
         help_buf.pop ();
@@ -1915,17 +1912,17 @@
 
   octave_comment_buffer::append (txt);
 
-  lexer_flags.current_input_column = 1;
-  lexer_flags.quote_is_transpose = false;
-  lexer_flags.convert_spaces_to_comma = true;
-  lexer_flags.at_beginning_of_statement = true;
+  curr_lexer->current_input_column = 1;
+  curr_lexer->quote_is_transpose = false;
+  curr_lexer->convert_spaces_to_comma = true;
+  curr_lexer->at_beginning_of_statement = true;
 
   if (YY_START == COMMAND_START)
     BEGIN (INITIAL);
 
-  if (lexer_flags.nesting_level.none ())
+  if (curr_lexer->nesting_level.none ())
     return '\n';
-  else if (lexer_flags.nesting_level.is_bracket_or_brace ())
+  else if (curr_lexer->nesting_level.is_bracket_or_brace ())
     return ';';
   else
     return 0;
@@ -2220,7 +2217,7 @@
 
   while ((c = text_yyinput ()) != EOF)
     {
-      lexer_flags.current_input_column++;
+      curr_lexer->current_input_column++;
 
       switch (c)
         {
@@ -2244,7 +2241,7 @@
               in_comment = false;
               beginning_of_comment = false;
             }
-          lexer_flags.current_input_column = 0;
+          curr_lexer->current_input_column = 0;
           break;
 
         case '#':
@@ -2309,7 +2306,7 @@
 
  done:
   xunput (c, yytext);
-  lexer_flags.current_input_column--;
+  curr_lexer->current_input_column--;
   return retval;
 }
 
@@ -2351,17 +2348,17 @@
 
   assert (nread == 1);
 
-  lexer_flags.quote_is_transpose = true;
-  lexer_flags.convert_spaces_to_comma = true;
-  lexer_flags.looking_for_object_index = false;
-  lexer_flags.at_beginning_of_statement = false;
-
-  yylval.tok_val = new token (value, yytext, lexer_flags.input_line_number,
-                              lexer_flags.current_input_column);
+  curr_lexer->quote_is_transpose = true;
+  curr_lexer->convert_spaces_to_comma = true;
+  curr_lexer->looking_for_object_index = false;
+  curr_lexer->at_beginning_of_statement = false;
+
+  yylval.tok_val = new token (value, yytext, curr_lexer->input_line_number,
+                              curr_lexer->current_input_column);
 
   token_stack.push (yylval.tok_val);
 
-  lexer_flags.current_input_column += yyleng;
+  curr_lexer->current_input_column += yyleng;
 
   do_comma_insert_check ();
 }
@@ -2430,7 +2427,7 @@
               comment_buf += static_cast<char> (c);
               octave_comment_buffer::append (comment_buf);
             }
-          lexer_flags.current_input_column = 0;
+          curr_lexer->current_input_column = 0;
           promptflag--;
           gripe_matlab_incompatible_continuation ();
           return true;
@@ -2510,15 +2507,15 @@
 {
   std::ostringstream buf;
 
-  int bos_line = lexer_flags.input_line_number;
-  int bos_col = lexer_flags.current_input_column;
+  int bos_line = curr_lexer->input_line_number;
+  int bos_col = curr_lexer->current_input_column;
 
   int c;
   int escape_pending = 0;
 
   while ((c = text_yyinput ()) != EOF)
     {
-      lexer_flags.current_input_column++;
+      curr_lexer->current_input_column++;
 
       if (c == '\\')
         {
@@ -2570,8 +2567,8 @@
                   else
                     s = do_string_escapes (buf.str ());
 
-                  lexer_flags.quote_is_transpose = true;
-                  lexer_flags.convert_spaces_to_comma = true;
+                  curr_lexer->quote_is_transpose = true;
+                  curr_lexer->convert_spaces_to_comma = true;
 
                   yylval.tok_val = new token (s, bos_line, bos_col);
                   token_stack.push (yylval.tok_val);
@@ -2581,8 +2578,8 @@
                   else if (delim == '\'')
                     gripe_single_quote_string ();
 
-                  lexer_flags.looking_for_object_index = true;
-                  lexer_flags.at_beginning_of_statement = false;
+                  curr_lexer->looking_for_object_index = true;
+                  curr_lexer->at_beginning_of_statement = false;
 
                   return delim == '"' ? DQ_STRING : SQ_STRING;
                 }
@@ -2696,32 +2693,32 @@
 {
   int retval = bracket_type;
 
-  if (! lexer_flags.nesting_level.none ())
+  if (! curr_lexer->nesting_level.none ())
     {
-      lexer_flags.nesting_level.remove ();
+      curr_lexer->nesting_level.remove ();
 
       if (bracket_type == ']')
-        lexer_flags.bracketflag--;
+        curr_lexer->bracketflag--;
       else if (bracket_type == '}')
-        lexer_flags.braceflag--;
+        curr_lexer->braceflag--;
       else
         panic_impossible ();
     }
 
-  if (lexer_flags.bracketflag == 0 && lexer_flags.braceflag == 0)
+  if (curr_lexer->bracketflag == 0 && curr_lexer->braceflag == 0)
     BEGIN (INITIAL);
 
   if (bracket_type == ']'
       && next_token_is_assign_op ()
-      && ! lexer_flags.looking_at_return_list)
+      && ! curr_lexer->looking_at_return_list)
     {
       retval = CLOSE_BRACE;
     }
-  else if ((lexer_flags.bracketflag || lexer_flags.braceflag)
-           && lexer_flags.convert_spaces_to_comma
-           && (lexer_flags.nesting_level.is_bracket ()
-               || (lexer_flags.nesting_level.is_brace ()
-                   && ! lexer_flags.looking_at_object_index.front ())))
+  else if ((curr_lexer->bracketflag || curr_lexer->braceflag)
+           && curr_lexer->convert_spaces_to_comma
+           && (curr_lexer->nesting_level.is_bracket ()
+               || (curr_lexer->nesting_level.is_brace ()
+                   && ! curr_lexer->looking_at_object_index.front ())))
     {
       bool index_op = next_token_is_index_op ();
 
@@ -2751,8 +2748,8 @@
         }
     }
 
-  lexer_flags.quote_is_transpose = true;
-  lexer_flags.convert_spaces_to_comma = true;
+  curr_lexer->quote_is_transpose = true;
+  curr_lexer->convert_spaces_to_comma = true;
 
   return retval;
 }
@@ -2760,9 +2757,9 @@
 static void
 maybe_unput_comma (int spc_gobbled)
 {
-  if (lexer_flags.nesting_level.is_bracket ()
-      || (lexer_flags.nesting_level.is_brace ()
-          && ! lexer_flags.looking_at_object_index.front ()))
+  if (curr_lexer->nesting_level.is_bracket ()
+      || (curr_lexer->nesting_level.is_brace ()
+          && ! curr_lexer->looking_at_object_index.front ()))
     {
       int bin_op = next_token_is_bin_op (spc_gobbled);
 
@@ -3090,12 +3087,12 @@
     = new token (meth.empty () ? 0 : &(symbol_table::insert (meth)),
                  cls.empty () ? 0 : &(symbol_table::insert (cls)),
                  pkg.empty () ? 0 : &(symbol_table::insert (pkg)),
-                 lexer_flags.input_line_number,
-                 lexer_flags.current_input_column);
+                 curr_lexer->input_line_number,
+                 curr_lexer->current_input_column);
   token_stack.push (yylval.tok_val);
 
-  lexer_flags.convert_spaces_to_comma = true;
-  lexer_flags.current_input_column += yyleng;
+  curr_lexer->convert_spaces_to_comma = true;
+  curr_lexer->current_input_column += yyleng;
 
   return SUPERCLASSREF;
 }
@@ -3125,13 +3122,13 @@
   yylval.tok_val
     = new token (cls.empty () ? 0 : &(symbol_table::insert (cls)),
                  pkg.empty () ? 0 : &(symbol_table::insert (pkg)),
-                 lexer_flags.input_line_number,
-                 lexer_flags.current_input_column);
+                 curr_lexer->input_line_number,
+                 curr_lexer->current_input_column);
 
   token_stack.push (yylval.tok_val);
 
-  lexer_flags.convert_spaces_to_comma = true;
-  lexer_flags.current_input_column += yyleng;
+  curr_lexer->convert_spaces_to_comma = true;
+  curr_lexer->current_input_column += yyleng;
 
   return METAQUERY;
 }
@@ -3143,7 +3140,7 @@
 static int
 handle_identifier (void)
 {
-  bool at_bos = lexer_flags.at_beginning_of_statement;
+  bool at_bos = curr_lexer->at_beginning_of_statement;
 
   std::string tok = strip_trailing_whitespace (yytext);
 
@@ -3158,30 +3155,30 @@
   // a string that is also a valid identifier.  But first, we have to
   // decide whether to insert a comma.
 
-  if (lexer_flags.looking_at_indirect_ref)
+  if (curr_lexer->looking_at_indirect_ref)
     {
       do_comma_insert_check ();
 
       maybe_unput_comma (spc_gobbled);
 
-      yylval.tok_val = new token (tok, lexer_flags.input_line_number,
-                                  lexer_flags.current_input_column);
+      yylval.tok_val = new token (tok, curr_lexer->input_line_number,
+                                  curr_lexer->current_input_column);
 
       token_stack.push (yylval.tok_val);
 
-      lexer_flags.quote_is_transpose = true;
-      lexer_flags.convert_spaces_to_comma = true;
-      lexer_flags.looking_for_object_index = true;
-
-      lexer_flags.current_input_column += yyleng;
+      curr_lexer->quote_is_transpose = true;
+      curr_lexer->convert_spaces_to_comma = true;
+      curr_lexer->looking_for_object_index = true;
+
+      curr_lexer->current_input_column += yyleng;
 
       return STRUCT_ELT;
     }
 
-  lexer_flags.at_beginning_of_statement = false;
+  curr_lexer->at_beginning_of_statement = false;
 
   // The is_keyword_token may reset
-  // lexer_flags.at_beginning_of_statement.  For example, if it sees
+  // curr_lexer->at_beginning_of_statement.  For example, if it sees
   // an else token, then the next token is at the beginning of a
   // statement.
 
@@ -3191,7 +3188,7 @@
   // is already set.  Otherwise, we won't be at the beginning of a
   // statement.
 
-  if (lexer_flags.looking_at_function_handle)
+  if (curr_lexer->looking_at_function_handle)
     {
       if (kw_token)
         {
@@ -3201,15 +3198,15 @@
         }
       else
         {
-          yylval.tok_val = new token (tok, lexer_flags.input_line_number,
-                                      lexer_flags.current_input_column);
+          yylval.tok_val = new token (tok, curr_lexer->input_line_number,
+                                      curr_lexer->current_input_column);
 
           token_stack.push (yylval.tok_val);
 
-          lexer_flags.current_input_column += yyleng;
-          lexer_flags.quote_is_transpose = false;
-          lexer_flags.convert_spaces_to_comma = true;
-          lexer_flags.looking_for_object_index = true;
+          curr_lexer->current_input_column += yyleng;
+          curr_lexer->quote_is_transpose = false;
+          curr_lexer->convert_spaces_to_comma = true;
+          curr_lexer->looking_for_object_index = true;
 
           return FCN_HANDLE;
         }
@@ -3222,10 +3219,10 @@
     {
       if (kw_token >= 0)
         {
-          lexer_flags.current_input_column += yyleng;
-          lexer_flags.quote_is_transpose = false;
-          lexer_flags.convert_spaces_to_comma = true;
-          lexer_flags.looking_for_object_index = false;
+          curr_lexer->current_input_column += yyleng;
+          curr_lexer->quote_is_transpose = false;
+          curr_lexer->convert_spaces_to_comma = true;
+          curr_lexer->looking_for_object_index = false;
         }
 
       return kw_token;
@@ -3265,16 +3262,16 @@
           BEGIN (COMMAND_START);
         }
       else if (next_tok_is_eq
-               || lexer_flags.looking_at_decl_list
-               || lexer_flags.looking_at_return_list
-               || (lexer_flags.looking_at_parameter_list
-                   && ! lexer_flags.looking_at_initializer_expression))
+               || curr_lexer->looking_at_decl_list
+               || curr_lexer->looking_at_return_list
+               || (curr_lexer->looking_at_parameter_list
+                   && ! curr_lexer->looking_at_initializer_expression))
         {
           symbol_table::force_variable (tok);
         }
-      else if (lexer_flags.looking_at_matrix_or_assign_lhs)
+      else if (curr_lexer->looking_at_matrix_or_assign_lhs)
         {
-          lexer_flags.pending_local_variables.insert (tok);
+          curr_lexer->pending_local_variables.insert (tok);
         }
     }
 
@@ -3285,29 +3282,29 @@
     tok = "__end__";
 
   yylval.tok_val = new token (&(symbol_table::insert (tok)),
-                              lexer_flags.input_line_number,
-                              lexer_flags.current_input_column);
+                              curr_lexer->input_line_number,
+                              curr_lexer->current_input_column);
 
   token_stack.push (yylval.tok_val);
 
   // After seeing an identifer, it is ok to convert spaces to a comma
   // (if needed).
 
-  lexer_flags.convert_spaces_to_comma = true;
+  curr_lexer->convert_spaces_to_comma = true;
 
   if (! (next_tok_is_eq || YY_START == COMMAND_START))
     {
-      lexer_flags.quote_is_transpose = true;
+      curr_lexer->quote_is_transpose = true;
 
       do_comma_insert_check ();
 
       maybe_unput_comma (spc_gobbled);
     }
 
-  lexer_flags.current_input_column += yyleng;
+  curr_lexer->current_input_column += yyleng;
 
   if (tok != "__end__")
-    lexer_flags.looking_for_object_index = true;
+    curr_lexer->looking_for_object_index = true;
 
   return NAME;
 }
@@ -3466,11 +3463,11 @@
   if (nm.empty ())
     warning_with_id ("Octave:separator-insert",
                      "potential auto-insertion of '%c' near line %d",
-                     sep, lexer_flags.input_line_number);
+                     sep, curr_lexer->input_line_number);
   else
     warning_with_id ("Octave:separator-insert",
                      "potential auto-insertion of '%c' near line %d of file %s",
-                     sep, lexer_flags.input_line_number, nm.c_str ());
+                     sep, curr_lexer->input_line_number, nm.c_str ());
 }
 
 static void
@@ -3481,11 +3478,11 @@
   if (nm.empty ())
     warning_with_id ("Octave:single-quote-string",
                      "single quote delimited string near line %d",
-                     lexer_flags.input_line_number);
+                     curr_lexer->input_line_number);
   else
     warning_with_id ("Octave:single-quote-string",
                      "single quote delimited string near line %d of file %s",
-                     lexer_flags.input_line_number, nm.c_str ());
+                     curr_lexer->input_line_number, nm.c_str ());
 }
 
 static void
@@ -3500,7 +3497,7 @@
   else
     warning_with_id ("Octave:matlab-incompatible",
                      "potential Matlab compatibility problem: %s near line %d offile %s",
-                     msg.c_str (), lexer_flags.input_line_number, nm.c_str ());
+                     msg.c_str (), curr_lexer->input_line_number, nm.c_str ());
 }
 
 static void
--- a/libinterp/parse-tree/oct-parse.yy	Tue Feb 26 00:45:43 2013 -0500
+++ b/libinterp/parse-tree/oct-parse.yy	Tue Feb 26 01:10:08 2013 -0500
@@ -556,7 +556,7 @@
                   { $$ = 0; }
                 | END_OF_INPUT
                   {
-                    lexer_flags.parser_end_of_input = 1;
+                    curr_lexer->parser_end_of_input = 1;
                     $$ = 0;
                   }
                 | simple_list
@@ -659,26 +659,26 @@
 matrix          : '[' ']'
                   {
                     $$ = new tree_constant (octave_null_matrix::instance);
-                    lexer_flags.looking_at_matrix_or_assign_lhs = false;
-                    lexer_flags.pending_local_variables.clear ();
+                    curr_lexer->looking_at_matrix_or_assign_lhs = false;
+                    curr_lexer->pending_local_variables.clear ();
                   }
                 | '[' ';' ']'
                   {
                     $$ = new tree_constant (octave_null_matrix::instance);
-                    lexer_flags.looking_at_matrix_or_assign_lhs = false;
-                    lexer_flags.pending_local_variables.clear ();
+                    curr_lexer->looking_at_matrix_or_assign_lhs = false;
+                    curr_lexer->pending_local_variables.clear ();
                   }
                 | '[' ',' ']'
                   {
                     $$ = new tree_constant (octave_null_matrix::instance);
-                    lexer_flags.looking_at_matrix_or_assign_lhs = false;
-                    lexer_flags.pending_local_variables.clear ();
+                    curr_lexer->looking_at_matrix_or_assign_lhs = false;
+                    curr_lexer->pending_local_variables.clear ();
                   }
                 | '[' matrix_rows ']'
                   {
                     $$ = finish_matrix ($2);
-                    lexer_flags.looking_at_matrix_or_assign_lhs = false;
-                    lexer_flags.pending_local_variables.clear ();
+                    curr_lexer->looking_at_matrix_or_assign_lhs = false;
+                    curr_lexer->pending_local_variables.clear ();
                   }
                 ;
 
@@ -730,13 +730,13 @@
 fcn_handle      : '@' FCN_HANDLE
                   {
                     $$ = make_fcn_handle ($2);
-                    lexer_flags.looking_at_function_handle--;
+                    curr_lexer->looking_at_function_handle--;
                   }
                 ;
 
 anon_fcn_handle : '@' param_list statement
                   {
-                    lexer_flags.quote_is_transpose = false;
+                    curr_lexer->quote_is_transpose = false;
                     $$ = make_anon_fcn_handle ($2, $3);
                   }
                 ;
@@ -796,7 +796,7 @@
                 ;
 
 indirect_ref_op : '.'
-                  { lexer_flags.looking_at_indirect_ref = true; }
+                  { curr_lexer->looking_at_indirect_ref = true; }
                 ;
 
 oper_expr       : primary_expr
@@ -909,14 +909,14 @@
                 | '[' arg_list opt_comma CLOSE_BRACE
                   {
                     $$ = $2;
-                    lexer_flags.looking_at_matrix_or_assign_lhs = false;
-                    for (std::set<std::string>::const_iterator p = lexer_flags.pending_local_variables.begin ();
-                         p != lexer_flags.pending_local_variables.end ();
+                    curr_lexer->looking_at_matrix_or_assign_lhs = false;
+                    for (std::set<std::string>::const_iterator p = curr_lexer->pending_local_variables.begin ();
+                         p != curr_lexer->pending_local_variables.end ();
                          p++)
                       {
                         symbol_table::force_variable (*p);
                       }
-                    lexer_flags.pending_local_variables.clear ();
+                    curr_lexer->pending_local_variables.clear ();
                   }
                 ;
 
@@ -988,17 +988,17 @@
 
 parsing_decl_list
                 : // empty
-                  { lexer_flags.looking_at_decl_list = true; }
+                  { curr_lexer->looking_at_decl_list = true; }
 
 declaration     : GLOBAL parsing_decl_list decl1
                   {
                     $$ = make_decl_command (GLOBAL, $1, $3);
-                    lexer_flags.looking_at_decl_list = false;
+                    curr_lexer->looking_at_decl_list = false;
                   }
                 | PERSISTENT parsing_decl_list decl1
                   {
                     $$ = make_decl_command (PERSISTENT, $1, $3);
-                    lexer_flags.looking_at_decl_list = false;
+                    curr_lexer->looking_at_decl_list = false;
                   }
                 ;
 
@@ -1012,13 +1012,13 @@
                 ;
 
 decl_param_init : // empty
-                { lexer_flags.looking_at_initializer_expression = true; }
+                { curr_lexer->looking_at_initializer_expression = true; }
 
 decl2           : identifier
                   { $$ = new tree_decl_elt ($1); }
                 | identifier '=' decl_param_init expression
                   {
-                    lexer_flags.looking_at_initializer_expression = false;
+                    curr_lexer->looking_at_initializer_expression = false;
                     $$ = new tree_decl_elt ($1, $4);
                   }
                 | magic_tilde
@@ -1243,28 +1243,28 @@
 
 param_list_beg  : '('
                   {
-                    lexer_flags.looking_at_parameter_list = true;
-
-                    if (lexer_flags.looking_at_function_handle)
+                    curr_lexer->looking_at_parameter_list = true;
+
+                    if (curr_lexer->looking_at_function_handle)
                       {
                         parser_symtab_context.push ();
                         symbol_table::set_scope (symbol_table::alloc_scope ());
-                        lexer_flags.looking_at_function_handle--;
-                        lexer_flags.looking_at_anon_fcn_args = true;
+                        curr_lexer->looking_at_function_handle--;
+                        curr_lexer->looking_at_anon_fcn_args = true;
                       }
                   }
                 ;
 
 param_list_end  : ')'
                   {
-                    lexer_flags.looking_at_parameter_list = false;
-                    lexer_flags.looking_for_object_index = false;
+                    curr_lexer->looking_at_parameter_list = false;
+                    curr_lexer->looking_for_object_index = false;
                   }
                 ;
 
 param_list      : param_list_beg param_list1 param_list_end
                   {
-                    lexer_flags.quote_is_transpose = false;
+                    curr_lexer->quote_is_transpose = false;
                     $$ = $2;
                   }
                 | param_list_beg error
@@ -1302,12 +1302,12 @@
 
 return_list     : '[' ']'
                   {
-                    lexer_flags.looking_at_return_list = false;
+                    curr_lexer->looking_at_return_list = false;
                     $$ = new tree_parameter_list ();
                   }
                 | return_list1
                   {
-                    lexer_flags.looking_at_return_list = false;
+                    curr_lexer->looking_at_return_list = false;
                     if ($1->validate (tree_parameter_list::out))
                       $$ = $1;
                     else
@@ -1315,7 +1315,7 @@
                   }
                 | '[' return_list1 ']'
                   {
-                    lexer_flags.looking_at_return_list = false;
+                    curr_lexer->looking_at_return_list = false;
                     if ($2->validate (tree_parameter_list::out))
                       $$ = $2;
                     else
@@ -1339,8 +1339,8 @@
 script_file     : SCRIPT_FILE opt_list END_OF_INPUT
                   {
                     tree_statement *end_of_script
-                      = make_end ("endscript", lexer_flags.input_line_number,
-                                  lexer_flags.current_input_column);
+                      = make_end ("endscript", curr_lexer->input_line_number,
+                                  curr_lexer->current_input_column);
 
                     make_script ($2, end_of_script);
 
@@ -1368,8 +1368,8 @@
                   {
                     $$ = $3;
 
-                    if (reading_classdef_file || lexer_flags.parsing_classdef)
-                      lexer_flags.maybe_classdef_get_set_method = true;
+                    if (reading_classdef_file || curr_lexer->parsing_classdef)
+                      curr_lexer->maybe_classdef_get_set_method = true;
                   }
                 ;
 
@@ -1389,21 +1389,21 @@
                   {
                     std::string id_name = $1->name ();
 
-                    lexer_flags.parsed_function_name.top () = true;
-                    lexer_flags.maybe_classdef_get_set_method = false;
+                    curr_lexer->parsed_function_name.top () = true;
+                    curr_lexer->maybe_classdef_get_set_method = false;
 
                     $$ = $1;
                   }
                 | GET '.' identifier
                   {
-                    lexer_flags.parsed_function_name.top () = true;
-                    lexer_flags.maybe_classdef_get_set_method = false;
+                    curr_lexer->parsed_function_name.top () = true;
+                    curr_lexer->maybe_classdef_get_set_method = false;
                     $$ = $3;
                   }
                 | SET '.' identifier
                   {
-                    lexer_flags.parsed_function_name.top () = true;
-                    lexer_flags.maybe_classdef_get_set_method = false;
+                    curr_lexer->parsed_function_name.top () = true;
+                    curr_lexer->maybe_classdef_get_set_method = false;
                     $$ = $3;
                   }
                 ;
@@ -1463,8 +1463,8 @@
                         YYABORT;
                       }
 
-                    $$ = make_end ("endfunction", lexer_flags.input_line_number,
-                                   lexer_flags.current_input_column);
+                    $$ = make_end ("endfunction", curr_lexer->input_line_number,
+                                   curr_lexer->current_input_column);
                   }
                 ;
 
@@ -1475,13 +1475,13 @@
 classdef_beg    : CLASSDEF stash_comment
                   {
                     $$ = 0;
-                    lexer_flags.parsing_classdef = true;
+                    curr_lexer->parsing_classdef = true;
                   }
                 ;
 
 classdef_end    : END
                   {
-                    lexer_flags.parsing_classdef = false;
+                    curr_lexer->parsing_classdef = false;
 
                     if (end_token_ok ($1, token::classdef_end))
                       $$ = make_end ("endclassdef", $1->line (), $1->column ());
@@ -1687,12 +1687,12 @@
 static void
 yyerror (const char *s)
 {
-  int err_col = lexer_flags.current_input_column - 1;
+  int err_col = curr_lexer->current_input_column - 1;
 
   std::ostringstream output_buf;
 
   if (reading_fcn_file || reading_script_file || reading_classdef_file)
-    output_buf << "parse error near line " << lexer_flags.input_line_number
+    output_buf << "parse error near line " << curr_lexer->input_line_number
                << " of file " << curr_fcn_file_full_name;
   else
     output_buf << "parse error:";
@@ -2124,8 +2124,8 @@
 make_anon_fcn_handle (tree_parameter_list *param_list, tree_statement *stmt)
 {
   // FIXME -- need to get these from the location of the @ symbol.
-  int l = lexer_flags.input_line_number;
-  int c = lexer_flags.current_input_column;
+  int l = curr_lexer->input_line_number;
+  int c = curr_lexer->current_input_column;
 
   tree_parameter_list *ret_list = 0;
 
@@ -2430,7 +2430,7 @@
     {
       octave_comment_list *tc = octave_comment_buffer::get_comment ();
 
-      lexer_flags.looping--;
+      curr_lexer->looping--;
 
       int l = while_tok->line ();
       int c = while_tok->column ();
@@ -2453,7 +2453,7 @@
 
   octave_comment_list *tc = octave_comment_buffer::get_comment ();
 
-  lexer_flags.looping--;
+  curr_lexer->looping--;
 
   int l = until_tok->line ();
   int c = until_tok->column ();
@@ -2479,7 +2479,7 @@
     {
       octave_comment_list *tc = octave_comment_buffer::get_comment ();
 
-      lexer_flags.looping--;
+      curr_lexer->looping--;
 
       int l = for_tok->line ();
       int c = for_tok->column ();
@@ -2876,7 +2876,7 @@
             fcn->stash_parent_fcn_scope (primary_fcn_scope);
         }
 
-      if (lexer_flags.parsing_class_method)
+      if (curr_lexer->parsing_class_method)
         {
           if (current_class_name == id_name)
             fcn->mark_as_class_constructor ();
@@ -2903,8 +2903,8 @@
     }
 
   fcn->stash_function_name (id_name);
-  fcn->stash_fcn_location (lexer_flags.input_line_number,
-                           lexer_flags.current_input_column);
+  fcn->stash_fcn_location (curr_lexer->input_line_number,
+                           curr_lexer->current_input_column);
 
   if (! help_buf.empty () && current_function_depth == 1
       && ! parsing_subfunctions)
@@ -3006,10 +3006,10 @@
   current_function_depth--;
   function_scopes.pop_back ();
 
-  lexer_flags.defining_func--;
-  lexer_flags.parsed_function_name.pop ();
-  lexer_flags.looking_at_return_list = false;
-  lexer_flags.looking_at_parameter_list = false;
+  curr_lexer->defining_func--;
+  curr_lexer->parsed_function_name.pop ();
+  curr_lexer->looking_at_return_list = false;
+  curr_lexer->looking_at_parameter_list = false;
 }
 
 // Make an index expression.
@@ -3066,7 +3066,7 @@
   else
     retval = new tree_index_expression (expr, elt, l, c);
 
-  lexer_flags.looking_at_indirect_ref = false;
+  curr_lexer->looking_at_indirect_ref = false;
 
   return retval;
 }
@@ -3092,7 +3092,7 @@
   else
     retval = new tree_index_expression (expr, elt, l, c);
 
-  lexer_flags.looking_at_indirect_ref = false;
+  curr_lexer->looking_at_indirect_ref = false;
 
   return retval;
 }
@@ -3313,7 +3313,7 @@
     }
 
   if (c == '\n')
-    lexer_flags.input_line_number++;
+    curr_lexer->input_line_number++;
 
   return c;
 }
@@ -3328,7 +3328,7 @@
   int ungetc (int c)
   {
     if (c == '\n')
-      lexer_flags.input_line_number--;
+      curr_lexer->input_line_number--;
 
     return ::ungetc (c, f);
   }
@@ -3354,11 +3354,11 @@
         {
         case ' ':
         case '\t':
-          lexer_flags.current_input_column++;
+          curr_lexer->current_input_column++;
           break;
 
         case '\n':
-          lexer_flags.current_input_column = 1;
+          curr_lexer->current_input_column = 1;
           break;
 
         default:
@@ -3499,9 +3499,10 @@
     {
       bool eof;
 
-      frame.protect_var (lexer_flags);
-
-      // Also resets lexer_flags.
+      frame.protect_var (curr_lexer);
+
+      curr_lexer = new lexical_feedback ();
+
       reset_parser ();
 
       std::string help_txt = gobble_leading_white_space (ffile, eof);
@@ -3581,7 +3582,7 @@
           else
             prep_lexer_for_function_file ();
 
-          lexer_flags.parsing_class_method = ! dispatch_type.empty ();
+          curr_lexer->parsing_class_method = ! dispatch_type.empty ();
 
           frame.protect_var (global_command);
 
@@ -3604,8 +3605,8 @@
       else
         {
           tree_statement *end_of_script
-            = make_end ("endscript", lexer_flags.input_line_number,
-                        lexer_flags.current_input_column);
+            = make_end ("endscript", curr_lexer->input_line_number,
+                        curr_lexer->current_input_column);
 
           make_script (0, end_of_script);
 
@@ -4304,7 +4305,7 @@
 
   unwind_protect frame;
 
-  frame.protect_var (lexer_flags);
+  frame.protect_var (curr_lexer);
 
   frame.protect_var (get_input_from_eval_string);
   frame.protect_var (line_editing);
@@ -4318,7 +4319,7 @@
   frame.protect_var (reading_script_file);
   frame.protect_var (reading_classdef_file);
 
-  lexer_flags = lexical_feedback ();
+  curr_lexer = new lexical_feedback ();
 
   get_input_from_eval_string = true;
   line_editing = false;
@@ -4417,7 +4418,7 @@
                   || tree_continue_command::continuing)
                 break;
             }
-          else if (lexer_flags.parser_end_of_input)
+          else if (curr_lexer->parser_end_of_input)
             break;
         }
     }