changeset 30140:a001811a68e6

use parser functions to build parse tree objects in grammar rule actions This change aims to eliminate and simplify code in the grammar rule actions to reduce clutter and aid in understanding the parser and language grammar. * parse.h, oct-parse.yy (base_parser::make_constant): Eliminate OP argument, which is also stored in the TOK_VAL argument. (append_cell_row, append_matrix_row, append_parameter_list, make_argument_list, make_black_hole, make_cell, make_classdef_attribute, make_classdef_attribute_list, make_classdef_body, make_classdef_enum, make_classdef_enum_list, make_classdef_event, make_classdef_events_list, make_classdef_methods_list, make_classdef_property, make_classdef_property_list, make_classdef_superclass, make_classdef_superclass_list, make_decl_elt, make_decl_init_list, make_default_switch_case, make_else_clause, make_identifier, make_matrix, make_metaclass_query, make_not_classdef_attribute, make_parameter_list, make_superclass_ref, make_switch_case_list): New base_parser methods. Use them to replace blocks of code and direct calls to new in grammar actions.
author John W. Eaton <jwe@octave.org>
date Wed, 08 Sep 2021 17:35:39 -0400
parents c789e728d57a
children 58f043641a78
files libinterp/parse-tree/oct-parse.yy libinterp/parse-tree/parse.h
diffstat 2 files changed, 430 insertions(+), 123 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/parse-tree/oct-parse.yy	Wed Sep 08 11:14:44 2021 -0400
+++ b/libinterp/parse-tree/oct-parse.yy	Wed Sep 08 17:35:39 2021 -0400
@@ -490,7 +490,7 @@
 fcn_list1       : function
                   {
                     octave::tree_statement *stmt = parser.make_statement ($1);
-                    $$ = new octave::tree_statement_list (stmt);
+                    $$ = parser.make_statement_list (stmt);
                   }
                 | fcn_list1 opt_sep function
                   {
@@ -528,7 +528,7 @@
                 ;
 
 word_list       : string
-                  { $$ = new octave::tree_argument_list ($1); }
+                  { $$ = parser.make_argument_list ($1); }
                 | word_list string
                   {
                     $1->append ($2);
@@ -541,52 +541,26 @@
 // ===========
 
 identifier      : NAME
-                  {
-                    // Find the token in the symbol table.
-                    octave::symbol_scope scope
-                      = lexer.m_symtab_context.curr_scope ();
-
-                    std::string nm = $1->text ();
-
-                    octave::symbol_record sr
-                      = (scope
-                         ? scope.insert (nm) : octave::symbol_record (nm));
-
-
-                    $$ = new octave::tree_identifier (sr, $1->line (),
-                                                      $1->column ());
-                  }
+                  { $$ = parser.make_identifier ($1); }
                 ;
 
 superclass_identifier
                 : SUPERCLASSREF
-                  {
-                    std::string meth = $1->superclass_method_name ();
-                    std::string cls = $1->superclass_class_name ();
-
-                    $$ = new octave::tree_superclass_ref (meth, cls,
-                                                          $1->line (),
-                                                          $1->column ());
-                  }
+                  { $$ = parser.make_superclass_ref ($1); }
                 ;
 
 meta_identifier : METAQUERY
-                  {
-                    std::string cls = $1->text ();
-
-                    $$ = new octave::tree_metaclass_query (cls, $1->line (),
-                                                           $1->column ());
-                  }
+                  { $$ = parser.make_metaclass_query ($1); }
                 ;
 
 string          : DQ_STRING
-                  { $$ = parser.make_constant (DQ_STRING, $1); }
+                  { $$ = parser.make_constant ($1); }
                 | SQ_STRING
-                  { $$ = parser.make_constant (SQ_STRING, $1); }
+                  { $$ = parser.make_constant ($1); }
                 ;
 
 constant        : NUMBER
-                  { $$ = parser.make_constant (NUMBER, $1); }
+                  { $$ = parser.make_constant ($1); }
                 | string
                   { $$ = $1; }
                 ;
@@ -596,20 +570,12 @@
                 ;
 
 matrix_rows     : cell_or_matrix_row
-                  { $$ = $1 ? new octave::tree_matrix ($1) : nullptr; }
+                  { $$ = parser.make_matrix ($1); }
                 | matrix_rows ';' cell_or_matrix_row
                   {
                     OCTAVE_YYUSE ($2);
 
-                    if ($1)
-                      {
-                        if ($3)
-                          $1->append ($3);
-
-                        $$ = $1;
-                      }
-                    else
-                      $$ = $3 ? new octave::tree_matrix ($3) : nullptr;
+                    $$ = parser.append_matrix_row ($1, $3);
                   }
                 ;
 
@@ -618,20 +584,12 @@
                 ;
 
 cell_rows       : cell_or_matrix_row
-                  { $$ = $1 ? new octave::tree_cell ($1) : nullptr; }
+                  { $$ = parser.make_cell ($1); }
                 | cell_rows ';' cell_or_matrix_row
                   {
                     OCTAVE_YYUSE ($2);
 
-                    if ($1)
-                      {
-                        if ($3)
-                          $1->append ($3);
-
-                        $$ = $1;
-                      }
-                    else
-                      $$ = $3 ? new octave::tree_cell ($3) : nullptr;
+                    $$ = parser.append_cell_row ($1, $3);
                   }
                 ;
 
@@ -734,28 +692,23 @@
                 ;
 
 magic_colon     : ':'
-                  {
-                    OCTAVE_YYUSE ($1);
-
-                    octave_value tmp (octave_value::magic_colon_t);
-                    $$ = new octave::tree_constant (tmp);
-                  }
+                  { $$ = parser.make_constant ($1); }
                 ;
 
 magic_tilde     : EXPR_NOT
                   {
                     OCTAVE_YYUSE ($1);
 
-                    $$ = new octave::tree_black_hole ();
+                    $$ = parser.make_black_hole ();
                   }
                 ;
 
 arg_list        : expression
-                  { $$ = new octave::tree_argument_list ($1); }
+                  { $$ = parser.make_argument_list ($1); }
                 | magic_colon
-                  { $$ = new octave::tree_argument_list ($1); }
+                  { $$ = parser.make_argument_list ($1); }
                 | magic_tilde
-                  { $$ = new octave::tree_argument_list ($1); }
+                  { $$ = parser.make_argument_list ($1); }
                 | arg_list ',' magic_colon
                   {
                     OCTAVE_YYUSE ($2);
@@ -1126,7 +1079,7 @@
                 ;
 
 decl_init_list   : decl_elt
-                  { $$ = new octave::tree_decl_init_list ($1); }
+                  { $$ = parser.make_decl_init_list ($1); }
                 | decl_init_list decl_elt
                   {
                     $1->append ($2);
@@ -1135,13 +1088,9 @@
                 ;
 
 decl_elt        : identifier
-                  { $$ = new octave::tree_decl_elt ($1); }
+                  { $$ = parser.make_decl_elt ($1); }
                 | identifier '=' expression
-                  {
-                    OCTAVE_YYUSE ($2);
-
-                    $$ = new octave::tree_decl_elt ($1, $3);
-                  }
+                  { $$ = parser.make_decl_elt ($1, $2, $3); }
                 ;
 
 // ====================
@@ -1205,10 +1154,9 @@
 
 else_clause     : ELSE stash_comment opt_sep opt_list
                   {
-                    OCTAVE_YYUSE ($1);
                     OCTAVE_YYUSE ($3);
 
-                    $$ = new octave::tree_if_clause ($4, $2);
+                    $$ = parser.make_else_clause ($1, $2, $4);
                   }
                 ;
 
@@ -1231,7 +1179,7 @@
 case_list       : // empty
                   { $$ = nullptr; }
                 | default_case
-                  { $$ = new octave::tree_switch_case_list ($1); }
+                  { $$ = parser.make_switch_case_list ($1); }
                 | case_list1
                   { $$ = $1; }
                 | case_list1 default_case
@@ -1242,7 +1190,7 @@
                 ;
 
 case_list1      : switch_case
-                  { $$ = new octave::tree_switch_case_list ($1); }
+                  { $$ = parser.make_switch_case_list ($1); }
                 | case_list1 switch_case
                   {
                     $1->append ($2);
@@ -1261,10 +1209,9 @@
 
 default_case    : OTHERWISE stash_comment opt_sep opt_list
                   {
-                    OCTAVE_YYUSE ($1);
                     OCTAVE_YYUSE ($3);
 
-                    $$ = new octave::tree_switch_case ($4, $2);
+                    $$ = parser.make_default_switch_case ($1, $2, $4);
                   }
                 ;
 
@@ -1494,7 +1441,7 @@
                 ;
 
 param_list1     : // empty
-                  { $$ = new octave::tree_parameter_list (octave::tree_parameter_list::in); }
+                  { $$ = parser.make_parameter_list (octave::tree_parameter_list::in); }
                 | param_list2
                   {
                     $1->mark_as_formal_parameters ();
@@ -1513,7 +1460,7 @@
                 ;
 
 param_list2     : param_list_elt
-                  { $$ = new octave::tree_parameter_list (octave::tree_parameter_list::in, $1); }
+                  { $$ = parser.make_parameter_list (octave::tree_parameter_list::in, $1); }
                 | param_list2 ',' param_list_elt
                   {
                     OCTAVE_YYUSE ($2);
@@ -1526,7 +1473,7 @@
 param_list_elt  : decl_elt
                   { $$ = $1; }
                 | magic_tilde
-                  { $$ = new octave::tree_decl_elt ($1); }
+                  { $$ = parser.make_decl_elt ($1); }
                 ;
 
 // ===================================
@@ -1540,14 +1487,14 @@
 
                     lexer.m_looking_at_return_list = false;
 
-                    $$ = new octave::tree_parameter_list (octave::tree_parameter_list::out);
+                    $$ = parser.make_parameter_list (octave::tree_parameter_list::out);
                   }
                 | identifier
                   {
                     lexer.m_looking_at_return_list = false;
 
                     octave::tree_parameter_list *tmp
-                      = new octave::tree_parameter_list (octave::tree_parameter_list::out, $1);
+                      = parser.make_parameter_list (octave::tree_parameter_list::out, $1);
 
                     // Even though this parameter list can contain only
                     // a single identifier, we still need to validate it
@@ -1583,14 +1530,13 @@
 
 return_list1    : identifier
                   {
-                    $$ = new octave::tree_parameter_list (octave::tree_parameter_list::out, new octave::tree_decl_elt ($1));
+                    $$ = parser.make_parameter_list (octave::tree_parameter_list::out, $1);
                   }
                 | return_list1 ',' identifier
                   {
                     OCTAVE_YYUSE ($2);
 
-                    $1->append (new octave::tree_decl_elt ($3));
-                    $$ = $1;
+                    $$ = parser.append_parameter_list ($1, $3);
                   }
                 ;
 
@@ -2002,7 +1948,7 @@
                 ;
 
 attr_list1      : attr
-                  { $$ = new octave::tree_classdef_attribute_list ($1); }
+                  { $$ = parser.make_classdef_attribute_list ($1); }
                 | attr_list1 ',' attr
                   {
                     OCTAVE_YYUSE ($2);
@@ -2013,18 +1959,18 @@
                 ;
 
 attr            : identifier
-                  { $$ = new octave::tree_classdef_attribute ($1); }
+                  { $$ = parser.make_classdef_attribute ($1); }
                 | identifier '=' expression
                   {
                     OCTAVE_YYUSE ($2);
 
-                    $$ = new octave::tree_classdef_attribute ($1, $3);
+                    $$ = parser.make_classdef_attribute ($1, $3);
                   }
                 | EXPR_NOT identifier
                   {
                     OCTAVE_YYUSE ($1);
 
-                    $$ = new octave::tree_classdef_attribute ($2, false);
+                    $$ = parser.make_not_classdef_attribute ($2);
                   }
                 ;
 
@@ -2051,7 +1997,7 @@
                   {
                     OCTAVE_YYUSE ($1);
 
-                    $$ = new octave::tree_classdef_superclass_list ($2);
+                    $$ = parser.make_classdef_superclass_list ($2);
                   }
                 | superclass_list1 EXPR_AND superclass
                   {
@@ -2063,7 +2009,7 @@
                 ;
 
 superclass      : FQ_IDENT
-                  { $$ = new octave::tree_classdef_superclass ($1->text ()); }
+                  { $$ = parser.make_classdef_superclass ($1); }
                 ;
 
 class_body      : // empty
@@ -2081,13 +2027,13 @@
                 ;
 
 class_body1     : properties_block
-                  { $$ = new octave::tree_classdef_body ($1); }
+                  { $$ = parser.make_classdef_body ($1); }
                 | methods_block
-                  { $$ = new octave::tree_classdef_body ($1); }
+                  { $$ = parser.make_classdef_body ($1); }
                 | events_block
-                  { $$ = new octave::tree_classdef_body ($1); }
+                  { $$ = parser.make_classdef_body ($1); }
                 | enum_block
-                  { $$ = new octave::tree_classdef_body ($1); }
+                  { $$ = parser.make_classdef_body ($1); }
                 | class_body1 opt_sep properties_block
                   {
                     OCTAVE_YYUSE ($2);
@@ -2159,7 +2105,7 @@
 
 property_list1
                 : class_property
-                  { $$ = new octave::tree_classdef_property_list ($1); }
+                  { $$ = parser.make_classdef_property_list ($1); }
                 | property_list1 sep class_property
                   {
                     OCTAVE_YYUSE ($2);
@@ -2193,20 +2139,7 @@
                 ;
 
 class_property  : stash_comment identifier arg_validation
-                  {
-                    // FIXME: Maybe this should be in a separate
-                    // base_parser::make_classdef_property function?
-
-                    octave::tree_arg_validation *av = $3;
-
-                    av->arg_name ($2);
-
-                    if (av->size_spec () || av->class_name ()
-                        || av->validation_fcns ())
-                      warning ("size, class, and validation function specifications are not yet supported for classdef properties; INCORRECT RESULTS ARE POSSIBLE!");
-
-                    $$ = new octave::tree_classdef_property (av, $1);
-                  }
+                  { $$ = parser.make_classdef_property ($1, $2, $3); }
                 ;
 
 methods_block   : methods_beg stash_comment opt_sep attr_list methods_list END
@@ -2284,13 +2217,7 @@
                 ;
 
 methods_list1   : method
-                  {
-                    octave_value fcn;
-                    if ($1)
-                      fcn = $1->function ();
-                    delete $1;
-                    $$ = new octave::tree_classdef_methods_list (fcn);
-                  }
+                  { $$ = parser.make_classdef_methods_list ($1); }
                 | methods_list1 opt_sep method
                   {
                     OCTAVE_YYUSE ($2);
@@ -2344,7 +2271,7 @@
                 ;
 
 events_list1    : class_event
-                  { $$ = new octave::tree_classdef_events_list ($1); }
+                  { $$ = parser.make_classdef_events_list ($1); }
                 | events_list1 opt_sep class_event
                   {
                     OCTAVE_YYUSE ($2);
@@ -2355,7 +2282,7 @@
                 ;
 
 class_event     : stash_comment identifier
-                  { $$ = new octave::tree_classdef_event ($2, $1); }
+                  { $$ = parser.make_classdef_event ($1, $2); }
                 ;
 
 enum_block      : enumeration_beg stash_comment opt_sep attr_list enum_list END
@@ -2397,7 +2324,7 @@
                 ;
 
 enum_list1      : class_enum
-                  { $$ = new octave::tree_classdef_enum_list ($1); }
+                  { $$ = parser.make_classdef_enum_list ($1); }
                 | enum_list1 opt_sep class_enum
                   {
                     OCTAVE_YYUSE ($2);
@@ -2412,7 +2339,7 @@
                     OCTAVE_YYUSE ($3);
                     OCTAVE_YYUSE ($5);
 
-                    $$ = new octave::tree_classdef_enum ($2, $4, $1);
+                    $$ = parser.make_classdef_enum ($2, $4, $1);
                   }
                 ;
 
@@ -2981,15 +2908,24 @@
   // Make a constant.
 
   tree_constant *
-  base_parser::make_constant (int op, token *tok_val)
+  base_parser::make_constant (token *tok_val)
   {
     int l = tok_val->line ();
     int c = tok_val->column ();
 
+    int op = tok_val->token_value ();
+
     tree_constant *retval = nullptr;
 
     switch (op)
       {
+      case ':':
+        {
+          octave_value tmp (octave_value::magic_colon_t);
+          retval = new tree_constant (tmp);
+        }
+        break;
+
       case NUMBER:
         {
           retval = new tree_constant (tok_val->number (), l, c);
@@ -3032,6 +2968,12 @@
     return retval;
   }
 
+  tree_black_hole *
+  base_parser::make_black_hole (void)
+  {
+    return new tree_black_hole ();
+  }
+
   // Make a function handle.
 
   tree_fcn_handle *
@@ -3743,6 +3685,13 @@
     return new tree_if_clause (expr, list, lc, l, c);
   }
 
+  tree_if_clause *
+  base_parser::make_else_clause (token */*else_tok*/, comment_list *lc,
+                                 tree_statement_list *list)
+  {
+    return new tree_if_clause (list, lc);
+  }
+
   // Finish a switch command.
 
   tree_switch_command *
@@ -3785,6 +3734,12 @@
     return retval;
   }
 
+  tree_switch_case_list *
+  base_parser::make_switch_case_list (tree_switch_case *switch_case)
+  {
+    return new tree_switch_case_list (switch_case);
+  }
+
   // Build a switch case.
 
   tree_switch_case *
@@ -3801,6 +3756,16 @@
     return new tree_switch_case (expr, list, lc, l, c);
   }
 
+  tree_switch_case *
+  base_parser::make_default_switch_case (token *default_tok, comment_list *lc,
+                                         tree_statement_list *list)
+  {
+    int l = default_tok->line ();
+    int c = default_tok->column ();
+
+    return new tree_switch_case (list, lc, l, c);
+  }
+
   // Build an assignment to a variable.
 
   tree_expression *
@@ -4506,6 +4471,24 @@
     return retval;
   }
 
+  tree_classdef_property_list *
+  base_parser::make_classdef_property_list (tree_classdef_property *prop)
+  {
+    return new tree_classdef_property_list (prop);
+  }
+
+  tree_classdef_property *
+  base_parser::make_classdef_property (comment_list *lc, tree_identifier *id,
+                                       tree_arg_validation *av)
+  {
+    av->arg_name (id);
+
+    if (av->size_spec () || av->class_name () || av->validation_fcns ())
+      warning ("size, class, and validation function specifications are not yet supported for classdef properties; INCORRECT RESULTS ARE POSSIBLE!");
+
+    return new tree_classdef_property (av, lc);
+  }
+
   // LC contains comments appearing before the methods keyword.
   // If this methods block appears first in the list of classdef
   // elements, this comment list will be used for the help text for the
@@ -4585,6 +4568,18 @@
     return retval;
   }
 
+  tree_classdef_events_list *
+  base_parser::make_classdef_events_list (tree_classdef_event *e)
+  {
+    return new tree_classdef_events_list (e);
+  }
+
+  tree_classdef_event *
+  base_parser::make_classdef_event (comment_list *lc, tree_identifier *id)
+  {
+    return new tree_classdef_event (id, lc);
+  }
+
   // LC contains comments appearing before the enumeration keyword.
   // If this enumeration block appears first in the list of classdef
   // elements, this comment list will be used for the help text for the
@@ -4628,6 +4623,76 @@
     return retval;
   }
 
+  tree_classdef_enum_list *
+  base_parser::make_classdef_enum_list (tree_classdef_enum *e)
+  {
+    return new tree_classdef_enum_list (e);
+  }
+
+  tree_classdef_enum *
+  base_parser::make_classdef_enum (tree_identifier *id, tree_expression *expr,
+                                   comment_list *lc)
+  {
+    return new tree_classdef_enum (id, expr, lc);
+  }
+
+  tree_classdef_superclass_list *
+  base_parser::make_classdef_superclass_list (tree_classdef_superclass *sc)
+  {
+    return new tree_classdef_superclass_list (sc);
+  }
+
+  tree_classdef_superclass *
+  base_parser::make_classdef_superclass (token *fqident)
+  {
+    return new tree_classdef_superclass (fqident->text ());
+  }
+
+  tree_classdef_attribute_list *
+  base_parser::make_classdef_attribute_list (tree_classdef_attribute *attr)
+  {
+    return new tree_classdef_attribute_list (attr);
+  }
+
+  tree_classdef_attribute *
+  base_parser::make_classdef_attribute (tree_identifier *id,
+                                        tree_expression *expr)
+  {
+    return (expr
+            ? new tree_classdef_attribute (id, expr)
+            : new tree_classdef_attribute (id));
+  }
+
+  tree_classdef_attribute *
+  base_parser::make_not_classdef_attribute (tree_identifier *id)
+  {
+    return new tree_classdef_attribute (id, false);
+  }
+
+  tree_classdef_body *
+  base_parser::make_classdef_body (tree_classdef_properties_block *pb)
+  {
+    return new tree_classdef_body (pb);
+  }
+
+  tree_classdef_body *
+  base_parser::make_classdef_body (tree_classdef_methods_block *mb)
+  {
+    return new tree_classdef_body (mb);
+  }
+
+  tree_classdef_body *
+  base_parser::make_classdef_body (tree_classdef_events_block *evb)
+  {
+    return new tree_classdef_body (evb);
+  }
+
+  tree_classdef_body *
+  base_parser::make_classdef_body  (tree_classdef_enum_block *enb)
+  {
+    return new tree_classdef_body (enb);
+  }
+
   octave_user_function*
   base_parser::start_classdef_external_method (tree_identifier *id,
                                                tree_parameter_list *pl)
@@ -4696,6 +4761,19 @@
     return new tree_function_def (fcn, l, c);
   }
 
+  tree_classdef_methods_list *
+  base_parser::make_classdef_methods_list (tree_function_def *fcn_def)
+  {
+    octave_value fcn;
+
+    if (fcn_def)
+      fcn = fcn_def->function ();
+
+    delete fcn_def;
+
+    return new tree_classdef_methods_list (fcn);
+  }
+
   bool
   base_parser::finish_classdef_file (tree_classdef *cls,
                                      tree_statement_list *local_fcns)
@@ -4910,6 +4988,19 @@
     return retval;
   }
 
+  tree_decl_init_list *
+  base_parser::make_decl_init_list (tree_decl_elt *elt)
+  {
+    return new tree_decl_init_list (elt);
+  }
+
+  tree_decl_elt *
+  base_parser::make_decl_elt (tree_identifier *id, token */*eq_op*/,
+                              tree_expression *expr)
+  {
+    return expr ? new tree_decl_elt (id, expr) : new tree_decl_elt (id);
+  }
+
   bool
   base_parser::validate_param_list (tree_parameter_list *lst,
                                     tree_parameter_list::in_or_out type)
@@ -5137,6 +5228,24 @@
                                  close_delim->line (), close_delim->column ()));
   }
 
+  tree_matrix *
+  base_parser::make_matrix (tree_argument_list *row)
+  {
+    return row ? new tree_matrix (row) : nullptr;
+  }
+
+  tree_matrix *
+  base_parser::append_matrix_row (tree_matrix *matrix, tree_argument_list *row)
+  {
+    if (! matrix)
+      return make_matrix (row);
+
+    if (row)
+      matrix->append (row);
+
+    return matrix;
+  }
+
   // Finish building a cell list.
 
   tree_expression *
@@ -5149,6 +5258,64 @@
                                  close_delim->line (), close_delim->column ()));
   }
 
+  tree_cell *
+  base_parser::make_cell (tree_argument_list *row)
+  {
+    return row ? new tree_cell (row) : nullptr;
+  }
+
+  tree_cell *
+  base_parser::append_cell_row (tree_cell *cell, tree_argument_list *row)
+  {
+    if (! cell)
+      return make_cell (row);
+
+    if (row)
+      cell->append (row);
+
+    return cell;
+  }
+
+  tree_identifier *
+  base_parser::make_identifier (token *ident)
+  {
+    // Find the token in the symbol table.
+    symbol_scope scope = m_lexer.m_symtab_context.curr_scope ();
+
+    std::string nm = ident->text ();
+
+    symbol_record sr = (scope ? scope.insert (nm) : symbol_record (nm));
+
+
+    int l = ident->line ();
+    int c = ident->column ();
+
+    return new tree_identifier (sr, l, c);
+  }
+
+  tree_superclass_ref *
+  base_parser::make_superclass_ref (token *superclassref)
+  {
+    std::string meth = superclassref->superclass_method_name ();
+    std::string cls = superclassref->superclass_class_name ();
+
+    int l = superclassref->line ();
+    int c = superclassref->column ();
+
+    return new tree_superclass_ref (meth, cls, l, c);
+  }
+
+  tree_metaclass_query *
+  base_parser::make_metaclass_query (token *metaquery)
+  {
+    std::string cls = metaquery->text ();
+
+    int l = metaquery->line ();
+    int c = metaquery->column ();
+
+    return new tree_metaclass_query (cls, l, c);
+  }
+
   tree_statement_list *
   base_parser::set_stmt_print_flag (tree_statement_list *list,
                                     char sep, bool warn_missing_semi)
@@ -5214,6 +5381,40 @@
     return list;
   }
 
+  tree_argument_list *
+  base_parser::make_argument_list (tree_expression *expr)
+  {
+    return new tree_argument_list (expr);
+  }
+
+  tree_parameter_list *
+  base_parser::make_parameter_list (tree_parameter_list::in_or_out io)
+  {
+    return new tree_parameter_list (io);
+  }
+
+  tree_parameter_list *
+  base_parser::make_parameter_list (tree_parameter_list::in_or_out io,
+                                    tree_decl_elt *t)
+  {
+    return new tree_parameter_list (io, t);
+  }
+
+  tree_parameter_list *
+  base_parser::make_parameter_list (tree_parameter_list::in_or_out io,
+                                    tree_identifier *id)
+  {
+    return new tree_parameter_list (io, id);
+  }
+
+  tree_parameter_list *
+  base_parser::append_parameter_list (tree_parameter_list *list,
+                                      tree_identifier *id)
+  {
+    list->append (new tree_decl_elt (id));
+    return list;
+  }
+
   void
   base_parser::disallow_command_syntax (void)
   {
--- a/libinterp/parse-tree/parse.h	Wed Sep 08 11:14:44 2021 -0400
+++ b/libinterp/parse-tree/parse.h	Wed Sep 08 17:35:39 2021 -0400
@@ -241,7 +241,19 @@
     OCTINTERP_API bool push_fcn_symtab (void);
 
     // Build a constant.
-    OCTINTERP_API tree_constant * make_constant (int op, token *tok_val);
+    OCTINTERP_API tree_constant * make_constant (token *tok_val);
+
+    OCTINTERP_API tree_black_hole * make_black_hole (void);
+
+    OCTINTERP_API tree_matrix * make_matrix (tree_argument_list *row);
+
+    OCTINTERP_API tree_matrix *
+    append_matrix_row (tree_matrix *matrix, tree_argument_list *row);
+
+    OCTINTERP_API tree_cell * make_cell (tree_argument_list *row);
+
+    OCTINTERP_API tree_cell *
+    append_cell_row (tree_cell *cell, tree_argument_list *row);
 
     // Build a function handle.
     OCTINTERP_API tree_fcn_handle * make_fcn_handle (token *tok_val);
@@ -334,17 +346,28 @@
     make_elseif_clause (token *elseif_tok, tree_expression *expr,
                         tree_statement_list *list, comment_list *lc);
 
+    OCTINTERP_API tree_if_clause *
+    make_else_clause (token *else_tok, comment_list *lc,
+                      tree_statement_list *list);
+
     // Finish a switch command.
     OCTINTERP_API tree_switch_command *
     finish_switch_command (token *switch_tok, tree_expression *expr,
                            tree_switch_case_list *list, token *end_tok,
                            comment_list *lc);
 
+    OCTINTERP_API tree_switch_case_list *
+    make_switch_case_list (tree_switch_case *switch_case);
+
     // Build a switch case.
     OCTINTERP_API tree_switch_case *
     make_switch_case (token *case_tok, tree_expression *expr,
                       tree_statement_list *list, comment_list *lc);
 
+    OCTINTERP_API tree_switch_case *
+    make_default_switch_case (token *default_tok, comment_list *lc,
+                              tree_statement_list *list);
+
     // Build an assignment to a variable.
     OCTINTERP_API tree_expression *
     make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
@@ -436,6 +459,13 @@
                                     token *end_tok, comment_list *lc,
                                     comment_list *tc);
 
+    OCTINTERP_API tree_classdef_property_list *
+    make_classdef_property_list (tree_classdef_property *prop);
+
+    OCTINTERP_API tree_classdef_property *
+    make_classdef_property (comment_list *lc, tree_identifier *id,
+                            tree_arg_validation *av);
+
     OCTINTERP_API tree_classdef_methods_block *
     make_classdef_methods_block (token *tok_val,
                                  tree_classdef_attribute_list *a,
@@ -450,6 +480,12 @@
                                 token *end_tok, comment_list *lc,
                                 comment_list *tc);
 
+    OCTINTERP_API tree_classdef_events_list *
+    make_classdef_events_list (tree_classdef_event *e);
+
+    OCTINTERP_API tree_classdef_event *
+    make_classdef_event (comment_list *lc, tree_identifier *id);
+
     OCTINTERP_API tree_classdef_enum_block *
     make_classdef_enum_block (token *tok_val,
                               tree_classdef_attribute_list *a,
@@ -457,6 +493,41 @@
                               token *end_tok, comment_list *lc,
                               comment_list *tc);
 
+    OCTINTERP_API tree_classdef_enum_list *
+    make_classdef_enum_list (tree_classdef_enum *e);
+
+    OCTINTERP_API tree_classdef_enum *
+    make_classdef_enum (tree_identifier *id, tree_expression *expr,
+                        comment_list *lc);
+
+    OCTINTERP_API tree_classdef_superclass_list *
+    make_classdef_superclass_list (tree_classdef_superclass *sc);
+
+    OCTINTERP_API tree_classdef_superclass *
+    make_classdef_superclass (token *fqident);
+
+    OCTINTERP_API tree_classdef_attribute_list *
+    make_classdef_attribute_list (tree_classdef_attribute *attr);
+
+    OCTINTERP_API tree_classdef_attribute *
+    make_classdef_attribute (tree_identifier *id,
+                             tree_expression *expr = nullptr);
+
+    OCTINTERP_API tree_classdef_attribute *
+    make_not_classdef_attribute (tree_identifier *id);
+
+    OCTINTERP_API tree_classdef_body *
+    make_classdef_body (tree_classdef_properties_block *pb);
+
+    OCTINTERP_API tree_classdef_body *
+    make_classdef_body (tree_classdef_methods_block *mb);
+
+    OCTINTERP_API tree_classdef_body *
+    make_classdef_body (tree_classdef_events_block *evb);
+
+    OCTINTERP_API tree_classdef_body *
+    make_classdef_body  (tree_classdef_enum_block *enb);
+
     OCTINTERP_API octave_user_function *
     start_classdef_external_method (tree_identifier *id,
                                     tree_parameter_list *pl);
@@ -466,6 +537,9 @@
                                      tree_parameter_list *ret_list,
                                      comment_list *cl);
 
+    OCTINTERP_API tree_classdef_methods_list *
+    make_classdef_methods_list (tree_function_def *fcn_def);
+
     OCTINTERP_API bool
     finish_classdef_file (tree_classdef *cls,
                           tree_statement_list *local_fcns);
@@ -487,6 +561,13 @@
     OCTINTERP_API tree_decl_command *
     make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst);
 
+    OCTINTERP_API tree_decl_init_list *
+    make_decl_init_list (tree_decl_elt *elt);
+
+    OCTINTERP_API tree_decl_elt *
+    make_decl_elt (tree_identifier *id, token *eq_op = nullptr,
+                   tree_expression *expr = nullptr);
+
     // Validate an function parameter list.
     OCTINTERP_API bool
     validate_param_list (tree_parameter_list *lst,
@@ -512,6 +593,15 @@
     OCTINTERP_API tree_expression *
     finish_cell (tree_cell *c, token *open_delim, token *close_delim);
 
+    OCTINTERP_API tree_identifier *
+    make_identifier (token *ident);
+
+    OCTINTERP_API tree_superclass_ref *
+    make_superclass_ref (token *superclassref);
+
+    OCTINTERP_API tree_metaclass_query *
+    make_metaclass_query (token *metaquery);
+
     // Set the print flag for a statement based on the separator type.
     OCTINTERP_API tree_statement_list *
     set_stmt_print_flag (tree_statement_list *, char, bool);
@@ -529,6 +619,22 @@
     append_statement_list (tree_statement_list *list, char sep,
                            tree_statement *stmt, bool warn_missing_semi);
 
+    OCTINTERP_API tree_argument_list *
+    make_argument_list (tree_expression *expr);
+
+    OCTINTERP_API tree_parameter_list *
+    make_parameter_list (tree_parameter_list::in_or_out io);
+
+    OCTINTERP_API tree_parameter_list *
+    make_parameter_list (tree_parameter_list::in_or_out io, tree_decl_elt *t);
+
+    OCTINTERP_API tree_parameter_list *
+    make_parameter_list (tree_parameter_list::in_or_out io,
+                         tree_identifier *id);
+
+    OCTINTERP_API tree_parameter_list *
+    append_parameter_list (tree_parameter_list *list, tree_identifier *id);
+
     // Don't allow parsing command syntax.  If the parser/lexer is
     // reset, this setting is also reset to the default (allow command
     // syntax).