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