1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING.  If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if ! defined (octave_parse_h)
27 #define octave_parse_h 1
28 
29 #include "octave-config.h"
30 
31 #include <cstdio>
32 
33 #include <deque>
34 #include <map>
35 #include <memory>
36 #include <set>
37 #include <string>
38 
39 #include "input.h"
40 #include "lex.h"
41 #include "pt-misc.h"
42 #include "symscope.h"
43 #include "token.h"
44 
45 class octave_function;
46 class octave_user_function;
47 
48 namespace octave
49 {
50   class comment_list;
51   class tree;
52   class tree_anon_fcn_handle;
53   class tree_argument_list;
54   class tree_array_list;
55   class tree_cell;
56   class tree_classdef;
57   class tree_classdef_attribute_list;
58   class tree_classdef_body;
59   class tree_classdef_enum_block;
60   class tree_classdef_enum_list;
61   class tree_classdef_events_block;
62   class tree_classdef_events_list;
63   class tree_classdef_methods_block;
64   class tree_classdef_methods_list;
65   class tree_classdef_properties_block;
66   class tree_classdef_property_list;
67   class tree_classdef_superclass_list;
68   class tree_colon_expression;
69   class tree_command;
70   class tree_constant;
71   class tree_decl_command;
72   class tree_decl_init_list;
73   class tree_expression;
74   class tree_fcn_handle;
75   class tree_function_def;
76   class tree_identifier;
77   class tree_if_clause;
78   class tree_if_command;
79   class tree_if_command_list;
80   class tree_index_expression;
81   class tree_matrix;
82   class tree_matrix;
83   class tree_parameter_list;
84   class tree_statement;
85   class tree_statement_list;
86   class tree_statement_listtree_statement;
87   class tree_switch_case;
88   class tree_switch_case_list;
89   class tree_switch_command;
90 }
91 
92 #include "ovl.h"
93 
94 // Nonzero means print parser debugging info (-d).
95 extern int octave_debug;
96 
97 namespace octave
98 {
99   class base_parser
100   {
101   private:
102 
103     class parent_scope_info
104     {
105     public:
106 
107       typedef std::pair<symbol_scope, std::string> value_type;
108 
109       typedef std::deque<value_type>::iterator iterator;
110       typedef std::deque<value_type>::const_iterator const_iterator;
111 
112       typedef std::deque<value_type>::reverse_iterator reverse_iterator;
113       typedef std::deque<value_type>::const_reverse_iterator const_reverse_iterator;
114 
115       parent_scope_info (void) = delete;
116 
parent_scope_info(base_parser & parser)117       parent_scope_info (base_parser& parser)
118         : m_parser (parser), m_info (), m_all_names ()
119       { }
120 
121       // No copying!
122 
123       parent_scope_info (const parent_scope_info&) = delete;
124 
125       parent_scope_info& operator = (const parent_scope_info&) = delete;
126 
127       ~parent_scope_info (void) = default;
128 
129       std::size_t size (void) const;
130 
131       void push (const value_type& elt);
132 
133       void push (const symbol_scope& id);
134 
135       void pop (void);
136 
137       bool name_ok (const std::string& name);
138 
139       bool name_current_scope (const std::string& name);
140 
141       symbol_scope parent_scope (void) const;
142 
143       std::string parent_name (void) const;
144 
145       void clear (void);
146 
147     private:
148 
149       base_parser& m_parser;
150       std::deque<value_type> m_info;
151       std::set<std::string> m_all_names;
152     };
153 
154   public:
155 
156     base_parser (base_lexer& lxr);
157 
158     // No copying!
159 
160     base_parser (const base_parser&) = delete;
161 
162     base_parser& operator = (const base_parser&) = delete;
163 
164     virtual ~base_parser (void);
165 
get_lexer(void)166     base_lexer& get_lexer (void) const { return m_lexer; }
167 
at_end_of_input(void)168     bool at_end_of_input (void) const { return m_lexer.m_end_of_input; }
169 
170     void reset (void);
171 
classdef_object(const std::shared_ptr<tree_classdef> & obj)172     void classdef_object (const std::shared_ptr<tree_classdef>& obj)
173     {
174       m_classdef_object = obj;
175     }
176 
classdef_object(void)177     std::shared_ptr<tree_classdef> classdef_object (void) const
178     {
179       return m_classdef_object;
180     }
181 
182     void statement_list (std::shared_ptr<tree_statement_list>& lst);
183 
statement_list(void)184     std::shared_ptr<tree_statement_list> statement_list (void) const
185     {
186       return m_stmt_list;
187     }
188 
parsing_subfunctions(bool flag)189     void parsing_subfunctions (bool flag)
190     {
191       m_parsing_subfunctions = flag;
192     }
193 
parsing_subfunctions(void)194     bool parsing_subfunctions (void) const
195     {
196       return m_parsing_subfunctions;
197     }
198 
parsing_local_functions(bool flag)199     void parsing_local_functions (bool flag)
200     {
201       m_parsing_local_functions = flag;
202     }
203 
parsing_local_functions(void)204     bool parsing_local_functions (void) const
205     {
206       return m_parsing_local_functions;
207     }
208 
curr_fcn_depth(void)209     int curr_fcn_depth (void) const
210     {
211       return m_curr_fcn_depth;
212     }
213 
endfunction_found(bool flag)214     void endfunction_found (bool flag)
215     {
216       m_endfunction_found = flag;
217     }
218 
endfunction_found(void)219     bool endfunction_found (void) const
220     {
221       return m_endfunction_found;
222     }
223 
224     // Error messages for mismatched end tokens.
225     void end_token_error (token *tok, token::end_tok_type expected);
226 
227     // Check to see that end tokens are properly matched.
228     bool end_token_ok (token *tok, token::end_tok_type expected);
229 
230     // Handle pushing symbol table for new function scope.
231     bool push_fcn_symtab (void);
232 
233     // Build a constant.
234     tree_constant * make_constant (int op, token *tok_val);
235 
236     // Build a function handle.
237     tree_fcn_handle * make_fcn_handle (token *tok_val);
238 
239     // Build an anonymous function handle.
240     tree_anon_fcn_handle *
241     make_anon_fcn_handle (tree_parameter_list *param_list,
242                           tree_expression * expr, const filepos& at_pos);
243 
244     // Build a colon expression.
245     tree_expression *
246     make_colon_expression (tree_expression *base, tree_expression *limit,
247                            tree_expression *incr = nullptr);
248 
249     // Build a binary expression.
250     tree_expression *
251     make_binary_op (int op, tree_expression *op1, token *tok_val,
252                     tree_expression *op2);
253 
254     // Build a boolean expression.
255     tree_expression *
256     make_boolean_op (int op, tree_expression *op1, token *tok_val,
257                      tree_expression *op2);
258 
259     // Build a prefix expression.
260     tree_expression *
261     make_prefix_op (int op, tree_expression *op1, token *tok_val);
262 
263     // Build a postfix expression.
264     tree_expression *
265     make_postfix_op (int op, tree_expression *op1, token *tok_val);
266 
267     // Build an unwind-protect command.
268     tree_command *
269     make_unwind_command (token *unwind_tok, tree_statement_list *body,
270                          tree_statement_list *cleanup, token *end_tok,
271                          comment_list *lc, comment_list *mc);
272 
273     // Build a try-catch command.
274     tree_command *
275     make_try_command (token *try_tok, tree_statement_list *body,
276                       char catch_sep, tree_statement_list *cleanup,
277                       token *end_tok, comment_list *lc,
278                       comment_list *mc);
279 
280     // Build a while command.
281     tree_command *
282     make_while_command (token *while_tok, tree_expression *expr,
283                         tree_statement_list *body, token *end_tok,
284                         comment_list *lc);
285 
286     // Build a do-until command.
287     tree_command *
288     make_do_until_command (token *until_tok, tree_statement_list *body,
289                            tree_expression *expr, comment_list *lc);
290 
291     // Build a for command.
292     tree_command *
293     make_for_command (int tok_id, token *for_tok, tree_argument_list *lhs,
294                       tree_expression *expr, tree_expression *maxproc,
295                       tree_statement_list *body, token *end_tok,
296                       comment_list *lc);
297 
298     // Build a break command.
299     tree_command * make_break_command (token *break_tok);
300 
301     // Build a continue command.
302     tree_command * make_continue_command (token *continue_tok);
303 
304     // Build a return command.
305     tree_command * make_return_command (token *return_tok);
306 
307     // Start an if command.
308     tree_if_command_list *
309     start_if_command (tree_expression *expr, tree_statement_list *list);
310 
311     // Finish an if command.
312     tree_if_command *
313     finish_if_command (token *if_tok, tree_if_command_list *list,
314                        token *end_tok, comment_list *lc);
315 
316     // Build an elseif clause.
317     tree_if_clause *
318     make_elseif_clause (token *elseif_tok, tree_expression *expr,
319                         tree_statement_list *list, comment_list *lc);
320 
321     // Finish a switch command.
322     tree_switch_command *
323     finish_switch_command (token *switch_tok, tree_expression *expr,
324                            tree_switch_case_list *list, token *end_tok,
325                            comment_list *lc);
326 
327     // Build a switch case.
328     tree_switch_case *
329     make_switch_case (token *case_tok, tree_expression *expr,
330                       tree_statement_list *list, comment_list *lc);
331 
332     // Build an assignment to a variable.
333     tree_expression *
334     make_assign_op (int op, tree_argument_list *lhs, token *eq_tok,
335                     tree_expression *rhs);
336 
337     // Define a script.
338     void make_script (tree_statement_list *cmds, tree_statement *end_script);
339 
340     // Handle identifier that is recognized as a function name.
341     tree_identifier *
342     make_fcn_name (tree_identifier *id);
343 
344     // Define a function.
345     tree_function_def *
346     make_function (token *fcn_tok, tree_parameter_list *ret_list,
347                    tree_identifier *id, tree_parameter_list *param_list,
348                    tree_statement_list *body, tree_statement *end_fcn_stmt,
349                    comment_list *lc);
350 
351     // Begin defining a function.
352     octave_user_function *
353     start_function (tree_identifier *id, tree_parameter_list *param_list,
354                     tree_statement_list *body, tree_statement *end_function);
355 
356     // Create a no-op statement for end_function.
357     tree_statement * make_end (const std::string& type, bool eof,
358                                const filepos& beg_pos, const filepos& end_pos);
359 
360     // Do most of the work for defining a function.
361     octave_user_function *
362     frob_function (tree_identifier *id, octave_user_function *fcn);
363 
364     // Finish defining a function.
365     tree_function_def *
366     finish_function (tree_parameter_list *ret_list,
367                      octave_user_function *fcn, comment_list *lc,
368                      int l, int c);
369 
370     // Reset state after parsing function.
371     void
372     recover_from_parsing_function (void);
373 
374     tree_classdef *
375     make_classdef (token *tok_val, tree_classdef_attribute_list *a,
376                    tree_identifier *id, tree_classdef_superclass_list *sc,
377                    tree_classdef_body *body, token *end_tok,
378                    comment_list *lc, comment_list *tc);
379 
380     tree_classdef_properties_block *
381     make_classdef_properties_block (token *tok_val,
382                                     tree_classdef_attribute_list *a,
383                                     tree_classdef_property_list *plist,
384                                     token *end_tok, comment_list *lc,
385                                     comment_list *tc);
386 
387     tree_classdef_methods_block *
388     make_classdef_methods_block (token *tok_val,
389                                  tree_classdef_attribute_list *a,
390                                  tree_classdef_methods_list *mlist,
391                                  token *end_tok, comment_list *lc,
392                                  comment_list *tc);
393 
394     tree_classdef_events_block *
395     make_classdef_events_block (token *tok_val,
396                                 tree_classdef_attribute_list *a,
397                                 tree_classdef_events_list *elist,
398                                 token *end_tok, comment_list *lc,
399                                 comment_list *tc);
400 
401     tree_classdef_enum_block *
402     make_classdef_enum_block (token *tok_val,
403                               tree_classdef_attribute_list *a,
404                               tree_classdef_enum_list *elist,
405                               token *end_tok, comment_list *lc,
406                               comment_list *tc);
407 
408     octave_user_function *
409     start_classdef_external_method (tree_identifier *id,
410                                     tree_parameter_list *pl);
411 
412     tree_function_def *
413     finish_classdef_external_method (octave_user_function *fcn,
414                                      tree_parameter_list *ret_list,
415                                      comment_list *cl);
416 
417     void
418     finish_classdef_file (tree_classdef *cls,
419                           tree_statement_list *local_fcns);
420 
421     // Make an index expression.
422     tree_index_expression *
423     make_index_expression (tree_expression *expr,
424                            tree_argument_list *args, char type);
425 
426     // Make an indirect reference expression.
427     tree_index_expression *
428     make_indirect_ref (tree_expression *expr, const std::string&);
429 
430     // Make an indirect reference expression with dynamic field name.
431     tree_index_expression *
432     make_indirect_ref (tree_expression *expr, tree_expression *field);
433 
434     // Make a declaration command.
435     tree_decl_command *
436     make_decl_command (int tok, token *tok_val, tree_decl_init_list *lst);
437 
438     // Validate an function parameter list.
439     bool validate_param_list (tree_parameter_list *lst,
440                               tree_parameter_list::in_or_out type);
441     // Validate matrix or cell
442     bool validate_array_list (tree_expression *e);
443 
444     // Validate matrix object used in "[lhs] = ..." assignments.
445     tree_argument_list * validate_matrix_for_assignment (tree_expression *e);
446 
447     // Finish building an array_list (common action for finish_matrix
448     // and finish_cell).
449     tree_expression * finish_array_list (tree_array_list *a, token *open_delim,
450                                          token *close_delim);
451 
452     // Finish building a matrix list.
453     tree_expression * finish_matrix (tree_matrix *m, token *open_delim,
454                                      token *close_delim);
455 
456     // Finish building a cell list.
457     tree_expression * finish_cell (tree_cell *c, token *open_delim,
458                                    token *close_delim);
459 
460     // Set the print flag for a statement based on the separator type.
461     tree_statement_list *
462     set_stmt_print_flag (tree_statement_list *, char, bool);
463 
464     // Finish building a statement.
465     template <typename T>
466     tree_statement * make_statement (T *arg);
467 
468     // Create a statement list.
469     tree_statement_list * make_statement_list (tree_statement *stmt);
470 
471     // Append a statement to an existing statement list.
472     tree_statement_list *
473     append_statement_list (tree_statement_list *list, char sep,
474                            tree_statement *stmt, bool warn_missing_semi);
475 
476     // Don't allow parsing command syntax.  If the parser/lexer is
477     // reset, this setting is also reset to the default (allow command
478     // syntax).
479     void disallow_command_syntax (void);
480 
481     // Generic error messages.
482     void bison_error (const std::string& s);
483     void bison_error (const std::string& s, const filepos& pos);
484     void bison_error (const std::string& s, int line, int column);
485 
486     friend octave_value
487     parse_fcn_file (interpreter& interp, const std::string& full_file,
488                     const std::string& file, const std::string& dir_name,
489                     const std::string& dispatch_type,
490                     const std::string& package_name, bool require_file,
491                     bool force_script, bool autoload, bool relative_lookup);
492 
493     // Thih interface allows push or pull parsers to be used
494     // equivalently, provided that the push parser also owns its input
495     // method (see below).  Alternatively, the push parser interface may
496     // use a separate run method and completely separate input from
497     // lexical analysis and parsing.
498 
499     virtual int run (void) = 0;
500 
501   protected:
502 
503     // Contains error message if Bison-generated parser returns non-zero
504     // status.
505     std::string m_parse_error_msg;
506 
507     // Have we found an explicit end to a function?
508     bool m_endfunction_found;
509 
510     // TRUE means we are in the process of autoloading a function.
511     bool m_autoloading;
512 
513     // TRUE means the current function file was found in a relative path
514     // element.
515     bool m_fcn_file_from_relative_lookup;
516 
517     // FALSE if we are still at the primary function.  Subfunctions can
518     // only be declared inside function files.
519     bool m_parsing_subfunctions;
520 
521     // TRUE if we are parsing local functions defined at after a
522     // classdef block.  Local functions can only be declared inside
523     // classdef files.
524     bool m_parsing_local_functions;
525 
526     // Maximum function depth detected.  Used to determine whether
527     // we have nested functions or just implicitly ended subfunctions.
528     int m_max_fcn_depth;
529 
530     // = 0 currently outside any function.
531     // = 1 inside the primary function or a subfunction.
532     // > 1 means we are looking at a function definition that seems to be
533     //     inside a function.  Note that the function still might not be a
534     //     nested function.
535     int m_curr_fcn_depth;
536 
537     // Scope where we install all subfunctions and nested functions.  Only
538     // used while reading function files.
539     symbol_scope m_primary_fcn_scope;
540 
541     // Name of the current class when we are parsing class methods or
542     // constructors.
543     std::string m_curr_class_name;
544 
545     // Name of the current package when we are parsing an element contained
546     // in a package directory (+-directory).
547     std::string m_curr_package_name;
548 
549     // Nested function scopes and names currently being parsed.
550     parent_scope_info m_function_scopes;
551 
552     // Pointer to the primary user function or user script function.
553     octave_value m_primary_fcn;
554 
555     // List of subfunction names, initially in the order they are
556     // installed in the symbol table, then ordered as they appear in the
557     // file.  Eventually stashed in the primary function object.
558     std::list<std::string> m_subfunction_names;
559 
560     // Pointer to the classdef object we just parsed, if any.
561     std::shared_ptr<tree_classdef> m_classdef_object;
562 
563     // Result of parsing input.
564     std::shared_ptr <tree_statement_list> m_stmt_list;
565 
566     // State of the lexer.
567     base_lexer& m_lexer;
568 
569     // Internal state of the Bison parser.
570     void *m_parser_state;
571 
572   private:
573 
574     // Maybe print a warning if an assignment expression is used as the
575     // test in a logical expression.
576     void maybe_warn_assign_as_truth_value (tree_expression *expr);
577 
578     // Maybe print a warning about switch labels that aren't constants.
579     void maybe_warn_variable_switch_label (tree_expression *expr);
580 
581     // Maybe print a warning.
582     void maybe_warn_missing_semi (tree_statement_list *);
583   };
584 
585   // Publish externally used friend functions.
586 
587   extern OCTAVE_API octave_value
588   parse_fcn_file (interpreter& interp, const std::string& full_file,
589                   const std::string& file, const std::string& dir_name,
590                   const std::string& dispatch_type,
591                   const std::string& package_name, bool require_file,
592                   bool force_script, bool autoload, bool relative_lookup);
593 
594   class parser : public base_parser
595   {
596   public:
597 
parser(interpreter & interp)598     parser (interpreter& interp)
599       : base_parser (*(new lexer (interp)))
600     { }
601 
parser(FILE * file,interpreter & interp)602     parser (FILE *file, interpreter& interp)
603       : base_parser (*(new lexer (file, interp)))
604     { }
605 
parser(const std::string & eval_string,interpreter & interp)606     parser (const std::string& eval_string, interpreter& interp)
607       : base_parser (*(new lexer (eval_string, interp)))
608     { }
609 
610     // The lexer must be allocated with new.  The parser object
611     // takes ownership of and deletes the lexer object in its
612     // destructor.
613 
parser(lexer * lxr)614     parser (lexer *lxr)
615       : base_parser (*lxr)
616     { }
617 
618     // No copying!
619 
620     parser (const parser&) = delete;
621 
622     parser& operator = (const parser&) = delete;
623 
624     ~parser (void) = default;
625 
626     int run (void);
627   };
628 
629   class push_parser : public base_parser
630   {
631   public:
632 
push_parser(interpreter & interp)633     push_parser (interpreter& interp)
634       : base_parser (*(new push_lexer (interp))),
635         m_interpreter (interp), m_reader ()
636     { }
637 
638     // The parser assumes ownership of READER, which must be created
639     // with new.
640 
push_parser(interpreter & interp,input_reader * reader)641     push_parser (interpreter& interp, input_reader *reader)
642       : base_parser (*(new push_lexer (interp))),
643         m_interpreter (interp), m_reader (reader)
644     { }
645 
646     // No copying!
647 
648     push_parser (const push_parser&) = delete;
649 
650     push_parser& operator = (const push_parser&) = delete;
651 
652     ~push_parser (void) = default;
653 
654     // Use the push parser in the same way as the pull parser.  The
655     // parser arranges for input through the M_READER object.  See, for
656     // example, interpreter::main_loop.
657 
658     int run (void);
659 
660     // Parse INPUT.  M_READER is not used.  The user is responsible for
661     // collecting input.
662 
663     int run (const std::string& input, bool eof);
664 
665   private:
666 
667     interpreter& m_interpreter;
668 
669     std::shared_ptr<input_reader> m_reader;
670   };
671 
672   extern OCTINTERP_API std::string
673   get_help_from_file (const std::string& nm, bool& symbol_found,
674                       std::string& file);
675 
676   extern OCTINTERP_API std::string
677   get_help_from_file (const std::string& nm, bool& symbol_found);
678 
679   extern OCTINTERP_API octave_value
680   load_fcn_from_file (const std::string& file_name,
681                       const std::string& dir_name = "",
682                       const std::string& dispatch_type = "",
683                       const std::string& package_name = "",
684                       const std::string& fcn_name = "",
685                       bool autoload = false);
686 
687   extern OCTINTERP_API void
688   source_file (const std::string& file_name,
689                const std::string& context = "",
690                bool verbose = false, bool require_file = true);
691 
692   extern OCTINTERP_API octave_value_list
693   feval (const char *name,
694          const octave_value_list& args = octave_value_list (),
695          int nargout = 0);
696 
697   extern OCTINTERP_API octave_value_list
698   feval (const std::string& name,
699          const octave_value_list& args = octave_value_list (),
700          int nargout = 0);
701 
702   extern OCTINTERP_API octave_value_list
703   feval (octave_function *fcn,
704          const octave_value_list& args = octave_value_list (),
705          int nargout = 0);
706 
707   extern OCTINTERP_API octave_value_list
708   feval (const octave_value& val,
709          const octave_value_list& args = octave_value_list (),
710          int nargout = 0);
711 
712   extern OCTINTERP_API octave_value_list
713   feval (const octave_value_list& args, int nargout = 0);
714 
715   OCTAVE_DEPRECATED (5, "use 'octave::interpreter::eval_string' instead")
716   extern OCTINTERP_API octave_value_list
717   eval_string (const std::string&, bool silent, int& parse_status, int nargout);
718 
719   OCTAVE_DEPRECATED (5, "use 'octave::interpreter::eval_string' instead")
720   extern OCTINTERP_API octave_value
721   eval_string (const std::string&, bool silent, int& parse_status);
722 
723   extern OCTINTERP_API void
724   cleanup_statement_list (tree_statement_list **lst);
725 }
726 
727 #endif
728