octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

line number tracking in the parser


From: John W. Eaton
Subject: line number tracking in the parser
Date: Fri, 9 Jan 2009 06:21:14 -0500

I just checked in the following changes that I think will improve the
handling of input_line_number in the parser so that line numbers that
are reported in error messages will be more accurate.  I would also
expect setting breakpoints with the debugger to work better...

jwe

diff --git a/src/ChangeLog b/src/ChangeLog
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,24 @@
+2009-01-09  John W. Eaton  <address@hidden>
+
+       * input.cc (get_user_input (void)): Don't increment input_line_number.
+       * lex.l (xunput): New function.  Use it in place of yyunput
+       anywhere a newline character may be put back on the input stream.
+       Increment input_line_number in all rules that consume newlines
+       characters.
+       (text_yyinput): Increment input_line_number
+       (fixup_column_count): Increment input_line_number.
+       (prep_for_function): Set input_line_number to 1, not 0.
+       (reset_parser): Set input_line_number to current_command_number,
+       not current_command_number-1.
+       (flex_stream_reader::ungetc): Call xunput, not yyunput.
+       * parse.y (input_line_number): Initialize to 1, not 0.
+       (text_getc): Increment input_line_number correctly.
+       (stdio_stream_reader::ungetc): Decrement input_line_number if
+       putting back a newline character.
+       (parse_fcn_file): Set input_line_number to 1, not 0.
+       (eval_string): Unwind-protect input_line_number and
+       current_input_column.
+
 2009-01-08  Jaroslav Hajek  <address@hidden>
 
        * ov-cell.cc (octave_cell::subsasgn): Erase duplicate lhs value 
diff --git a/src/input.cc b/src/input.cc
--- a/src/input.cc
+++ b/src/input.cc
@@ -329,9 +329,6 @@
     retval = octave_gets ();
 
   current_input_line = retval;
-
-  if (! get_input_from_eval_string)
-    input_line_number++;
 
   return retval;
 }
diff --git a/src/lex.l b/src/lex.l
--- a/src/lex.l
+++ b/src/lex.l
@@ -257,6 +257,7 @@
 // file.
 
 static int text_yyinput (void);
+static void xunput (char c, char *buf);
 static void fixup_column_count (char *s);
 static void do_comma_insert_check (void);
 static int is_keyword_token (const std::string& s);
@@ -308,19 +309,19 @@
 
 <SCRIPT_FILE_BEGIN>. {
     BEGIN (INITIAL);
-    yyunput (yytext[0], yytext);
+    xunput (yytext[0], yytext);
     COUNT_TOK_AND_RETURN (SCRIPT);
   }
 
 <NESTED_FUNCTION_END>. {
     BEGIN (NESTED_FUNCTION_BEGIN);
-    yyunput (yytext[0], yytext);
+    xunput (yytext[0], yytext);
     COUNT_TOK_AND_RETURN (';');
   }
 
 <NESTED_FUNCTION_BEGIN>. {
     BEGIN (INITIAL);
-    yyunput (yytext[0], yytext);
+    xunput (yytext[0], yytext);
     prep_for_nested_function ();
     COUNT_TOK_AND_RETURN (FCN);
   }
@@ -333,6 +334,7 @@
 
 <COMMAND_START>{NL} {
     BEGIN (INITIAL);
+    input_line_number++;
     current_input_column = 1;
     lexer_flags.quote_is_transpose = false;
     lexer_flags.convert_spaces_to_comma = true;
@@ -574,6 +576,7 @@
       gripe_matlab_incompatible_continuation ();
     scan_for_comments (yytext);
     promptflag--;
+    input_line_number++;
     current_input_column = 1;
   }
 
@@ -626,6 +629,7 @@
 %}
 
 {NL} {
+    input_line_number++;
     current_input_column = 1;
     lexer_flags.quote_is_transpose = false;
     lexer_flags.convert_spaces_to_comma = true;
@@ -674,7 +678,7 @@
 %} 
 
 {CCHAR} {
-    yyunput (yytext[0], yytext);
+    xunput (yytext[0], yytext);
 
     bool eof = false;
     int tok = process_comment (false, eof);
@@ -690,6 +694,7 @@
 %}
 
 ^{S}*{CCHAR}\{{S}*{NL} {
+    input_line_number++;
     current_input_column = 1;
     block_comment_nesting_level++;
     promptflag--;
@@ -807,7 +812,7 @@
 . {
     // EOF happens here if we are parsing nested functions.
 
-    yyunput (yytext[0], yytext);
+    xunput (yytext[0], yytext);
 
     int c = text_yyinput ();
 
@@ -839,7 +844,7 @@
 
   int c = text_yyinput ();
 
-  yyunput (c, yytext);
+  xunput (c, yytext);
 
   if (spc_gobbled)
     yyunput (' ', yytext);
@@ -886,7 +891,7 @@
   if (! (reading_script_file || reading_fcn_file))
     {
       current_input_column = 1;
-      input_line_number = command_editor::current_command_number () - 1;
+      input_line_number = command_editor::current_command_number ();
     }
 
   // Only ask for input from stdin if we are expecting interactive
@@ -924,7 +929,19 @@
        }
     }
 
+  if (c == '\n')
+    input_line_number++;
+
   return c;
+}
+
+static void
+xunput (char c, char *buf)
+{
+  if (c == '\n')
+    input_line_number--;
+
+  yyunput (c, buf);
 }
 
 // If we read some newlines, we need figure out what column we're
@@ -937,7 +954,10 @@
   while ((c = *s++) != '\0')
     {
       if (c == '\n')
-         current_input_column = 1;
+        {
+          input_line_number++;
+          current_input_column = 1;
+        }
       else
        current_input_column++;
     }
@@ -1461,7 +1481,7 @@
   flex_stream_reader (char *buf_arg) : stream_reader (), buf (buf_arg) { }
 
   int getc (void) { return ::text_yyinput (); }
-  int ungetc (int c) { ::yyunput (c, buf); return 0; }
+  int ungetc (int c) { ::xunput (c, buf); return 0; }
   
 private:
   char *buf;
@@ -1557,7 +1577,7 @@
 
   retval = match_any (c, ",;\n]");
 
-  yyunput (c, yytext);
+  xunput (c, yytext);
 
   return retval;
 }
@@ -1580,22 +1600,22 @@
     {
       int c1 = text_yyinput ();
       un_op = (c1 == '\'');
-      yyunput (c1, yytext);
+      xunput (c1, yytext);
     }
   else if (c0 == '+')
     {
       int c1 = text_yyinput ();
       un_op = (c1 == '+');
-      yyunput (c1, yytext);
+      xunput (c1, yytext);
     }
   else if (c0 == '-')
     {
       int c1 = text_yyinput ();
       un_op = (c1 == '-');
-      yyunput (c1, yytext);
+      xunput (c1, yytext);
     }
 
-  yyunput (c0, yytext);
+  xunput (c0, yytext);
 
   return un_op;
 }
@@ -1644,7 +1664,7 @@
            break;
          }
 
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -1668,7 +1688,7 @@
          // A structure element reference is a binary op.
          bin_op = true;
 
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -1698,7 +1718,7 @@
        if (c1 == '=')
          bin_op = true;
 
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -1706,7 +1726,7 @@
       break;
     }
 
-  yyunput (c0, yytext);
+  xunput (c0, yytext);
 
   return bin_op;
 }
@@ -1897,7 +1917,7 @@
     octave_comment_buffer::append (comment_buf);
 
  done:
-  yyunput (c, yytext);
+  xunput (c, yytext);
   current_input_column--;
   return retval;
 }
@@ -2034,7 +2054,7 @@
        }
     }
 
-  yyunput (c, yytext);
+  xunput (c, yytext);
   return false;
 
 cleanup:
@@ -2043,7 +2063,7 @@
 
   int len = s.length ();
   while (len--)
-    yyunput (s[len], yytext);
+    xunput (s[len], yytext);
 
   return false;
 }
@@ -2063,12 +2083,12 @@
        return true;
       else
        {
-         yyunput (c2, yytext);
-         yyunput (c1, yytext);
+         xunput (c2, yytext);
+         xunput (c1, yytext);
        }
     }
   else
-    yyunput (c1, yytext);
+    xunput (c1, yytext);
 
   return false;
 }
@@ -2089,7 +2109,7 @@
       || (c == '\\' && have_continuation ()))
     retval = eat_whitespace ();
   else
-    yyunput (c, yytext);
+    xunput (c, yytext);
 
   return retval;
 }
@@ -2154,7 +2174,7 @@
              else
                {
                  std::string s;  
-                 yyunput (c, yytext);
+                 xunput (c, yytext);
 
                  if (lexer_flags.doing_rawcommand || delim == '\'')
                    s = buf.str ();
@@ -2204,7 +2224,7 @@
     case '=':
       {
        int c1 = text_yyinput ();
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
        if (c1 != '=')
          retval = true;
       }
@@ -2219,7 +2239,7 @@
     case '|':
       {
        int c1 = text_yyinput ();
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
        if (c1 == '=')
          retval = true;
       }
@@ -2231,11 +2251,11 @@
        if (match_any (c1, "+-*/\\"))
          {
            int c2 = text_yyinput ();
-           yyunput (c2, yytext);
+           xunput (c2, yytext);
            if (c2 == '=')
              retval = true;
          }
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -2245,11 +2265,11 @@
        if (c1 == '>')
          {
            int c2 = text_yyinput ();
-           yyunput (c2, yytext);
+           xunput (c2, yytext);
            if (c2 == '=')
              retval = true;
          }
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -2259,11 +2279,11 @@
        if (c1 == '<')
          {
            int c2 = text_yyinput ();
-           yyunput (c2, yytext);
+           xunput (c2, yytext);
            if (c2 == '=')
              retval = true;
          }
-       yyunput (c1, yytext);
+       xunput (c1, yytext);
       }
       break;
 
@@ -2271,7 +2291,7 @@
       break;
     }
 
-  yyunput (c0, yytext);
+  xunput (c0, yytext);
 
   return retval;
 }
@@ -2280,7 +2300,7 @@
 next_token_is_index_op (void)
 {
   int c = text_yyinput ();
-  yyunput (c, yytext);
+  xunput (c, yytext);
   return c == '(' || c == '{';
 }
 
@@ -2364,8 +2384,8 @@
       int c1 = text_yyinput ();
       int c2 = text_yyinput ();
 
-      yyunput (c2, yytext);
-      yyunput (c1, yytext);
+      xunput (c2, yytext);
+      xunput (c1, yytext);
 
       int sep_op = next_token_is_sep_op ();
 
@@ -2478,13 +2498,13 @@
   if (c1 == '=')
     {
       int c2 = text_yyinput ();
-      yyunput (c2, yytext);
+      xunput (c2, yytext);
 
       if (c2 != '=')
        next_tok_is_eq = true;
     }
 
-  yyunput (c1, yytext);
+  xunput (c1, yytext);
 
   // Kluge alert.
   //
diff --git a/src/parse.y b/src/parse.y
--- a/src/parse.y
+++ b/src/parse.y
@@ -77,7 +77,7 @@
 #include "variables.h"
 
 // The current input line number.
-int input_line_number = 0;
+int input_line_number = 1;
 
 // The column of the current token.
 int current_input_column = 1;
@@ -2895,15 +2895,14 @@
     {
       c = getc (f);
 
-      if (c == '\n')
-        input_line_number++;
-      else
+      if (c != '\n')
        {
          ungetc (c, f);
          c = '\n';
        }
     }
-  else if (c == '\n')
+
+  if (c == '\n')
     input_line_number++;
 
   return c;
@@ -2916,7 +2915,13 @@
   stdio_stream_reader (FILE *f_arg) : stream_reader (), f (f_arg) { }
 
   int getc (void) { return ::text_getc (f); }
-  int ungetc (int c) { return ::ungetc (c, f); }
+  int ungetc (int c)
+  {
+    if (c == '\n')
+      input_line_number--;
+
+    return ::ungetc (c, f);
+  }
   
 private:
   FILE *f;
@@ -3051,7 +3056,7 @@
   unwind_protect_str (parent_function_name);
   unwind_protect_str (current_class_name);
 
-  input_line_number = 0;
+  input_line_number = 1;
   current_input_column = 1;
   end_tokens_expected = 0;
   reading_fcn_file = true;
@@ -3738,12 +3743,16 @@
 
   unwind_protect::begin_frame ("eval_string");
 
+  unwind_protect_int (input_line_number);
+  unwind_protect_int (current_input_column);
   unwind_protect_bool (get_input_from_eval_string);
   unwind_protect_bool (input_from_eval_string_pending);
   unwind_protect_bool (parser_end_of_input);
   unwind_protect_bool (line_editing);
   unwind_protect_str (current_eval_string);
 
+  input_line_number = 1;
+  current_input_column = 1;
   get_input_from_eval_string = true;
   input_from_eval_string_pending = true;
   parser_end_of_input = false;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]