changeset 26712:17e7d310def8

revamp parsing of superclass identifiers in classdef decls This change is part of the fix for bug #47680. * lex.h, lex.ll (lexical_feedback::parsing_classdef_decl, lexical_feedback::parsing_classdef_superclass): New data members. (lexical_feedback::lexical_feedback): Initialize them. (lexical_feedback::reset): Reset them. (base_lexer::enable_fq_identifier): Delete. (base_lexer::handle_op_internal): Maybe FQ_IDENT_START start state when parsing classdef declaration. (base_lexer::display_start_state): Handle FQ_IDENT_START. Report INPUT_FILE_START for that state instead of INPUT_FILE_BEGIN. * oct-parse.yy (superclass_list): Eliminate mid-rule actions. (opt_superclass_list): Reset m_parsing_classdef_decl and m_parsing_classdef_superclass lexical feedback flags. (classdef_beg): Set m_parsing_classdef_decl lexical feedback flag.
author John W. Eaton <jwe@octave.org>
date Sat, 09 Feb 2019 16:14:01 +0000
parents 606605d0cd31
children d6dd07dce2d2
files libinterp/parse-tree/lex.h libinterp/parse-tree/lex.ll libinterp/parse-tree/oct-parse.yy
diffstat 3 files changed, 52 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/lex.h	Sat Feb 09 15:14:24 2019 +0000
+++ b/libinterp/parse-tree/lex.h	Sat Feb 09 16:14:01 2019 +0000
@@ -271,6 +271,8 @@
         m_looking_at_indirect_ref (false),
         m_parsing_class_method (false),
         m_parsing_classdef (false),
+        m_parsing_classdef_decl (false),
+        m_parsing_classdef_superclass (false),
         m_maybe_classdef_get_set_method (false),
         m_parsing_classdef_get_method (false),
         m_parsing_classdef_set_method (false),
@@ -386,6 +388,15 @@
     // true means we are parsing a classdef file
     bool m_parsing_classdef;
 
+    // true means we are parsing the initial classdef declaration
+    // portion of classdef file, from the "classdef" token through the
+    // optional list of superclasses.
+    bool m_parsing_classdef_decl;
+
+    // true means we are parsing the superclass part of a classdef
+    // declaration.
+    bool m_parsing_classdef_superclass;
+
     // true means we are parsing a class method declaration line in a
     // classdef file and can accept a property get or set method name.
     // for example, "get.propertyname" is recognized as a function name.
@@ -751,8 +762,6 @@
 
     int show_token (int tok);
 
-    void enable_fq_identifier (void);
-
   protected:
 
     std::stack<int> start_state_stack;
--- a/libinterp/parse-tree/lex.ll	Sat Feb 09 15:14:24 2019 +0000
+++ b/libinterp/parse-tree/lex.ll	Sat Feb 09 16:14:01 2019 +0000
@@ -2105,6 +2105,8 @@
     m_looking_at_indirect_ref = false;
     m_parsing_class_method = false;
     m_parsing_classdef = false;
+    m_parsing_classdef_decl = false;
+    m_parsing_classdef_superclass = false;
     m_maybe_classdef_get_set_method = false;
     m_parsing_classdef_get_method = false;
     m_parsing_classdef_set_method = false;
@@ -3487,7 +3489,7 @@
         break;
 
       case INPUT_FILE_START:
-        std::cerr << "INPUT_FILE_BEGIN" << std::endl;
+        std::cerr << "INPUT_FILE_START" << std::endl;
         break;
 
       case BLOCK_COMMENT_START:
@@ -3506,6 +3508,10 @@
         std::cerr << "SQ_STRING_START" << std::endl;
         break;
 
+      case FQ_IDENT_START:
+        std::cerr << "FQ_IDENT_START" << std::endl;
+        break;
+
       default:
         std::cerr << "UNKNOWN START STATE!" << std::endl;
         break;
@@ -3578,6 +3584,25 @@
     m_looking_for_object_index = false;
     m_at_beginning_of_statement = bos;
 
+    switch (tok)
+      {
+      case EXPR_LT:
+        if (m_parsing_classdef_decl)
+          {
+            m_parsing_classdef_superclass = true;
+            push_start_state (FQ_IDENT_START);
+          }
+        break;
+
+      case EXPR_AND:
+        if (m_parsing_classdef_superclass)
+          push_start_state (FQ_IDENT_START);
+        break;
+
+      default:
+        break;
+      }
+
     return count_token_internal (tok);
   }
 
@@ -3639,12 +3664,6 @@
     return tok;
   }
 
-  void
-  base_lexer::enable_fq_identifier (void)
-  {
-    push_start_state (FQ_IDENT_START);
-  }
-
   int
   lexer::fill_flex_buffer (char *buf, unsigned max_size)
   {
--- a/libinterp/parse-tree/oct-parse.yy	Sat Feb 09 15:14:24 2019 +0000
+++ b/libinterp/parse-tree/oct-parse.yy	Sat Feb 09 16:14:01 2019 +0000
@@ -1658,6 +1658,7 @@
                     // Create invalid parent scope.
                     lexer.m_symtab_context.push (octave::symbol_scope ());
                     lexer.m_parsing_classdef = true;
+                    lexer.m_parsing_classdef_decl = true;
                     $$ = $1;
                   }
                 ;
@@ -1724,28 +1725,30 @@
 
 opt_superclass_list
                 : // empty
-                  { $$ = nullptr; }
+                  {
+                    lexer.m_parsing_classdef_decl = false;
+                    lexer.m_parsing_classdef_superclass = false;
+                    $$ = nullptr;
+                  }
                 | superclass_list
-                  { $$ = $1; }
+                  {
+                    lexer.m_parsing_classdef_decl = false;
+                    lexer.m_parsing_classdef_superclass = false;
+                    $$ = $1;
+                  }
                 ;
 
-superclass_list : EXPR_LT
+superclass_list : EXPR_LT superclass
                   {
                     YYUSE ($1);
 
-                    lexer.enable_fq_identifier ();
+                    $$ = new octave::tree_classdef_superclass_list ($2);
                   }
-                  superclass
-                  { $$ = new octave::tree_classdef_superclass_list ($3); }
-                | superclass_list EXPR_AND
+                | superclass_list EXPR_AND superclass
                   {
                     YYUSE ($2);
 
-                    lexer.enable_fq_identifier ();
-                  }
-                  superclass
-                  {
-                    $1->append ($4);
+                    $1->append ($3);
                     $$ = $1;
                   }
                 ;