Mercurial > hg > octave-lyh
comparison src/oct-parse.yy @ 15037:56b8eb7c9c04 classdef
improvements in parsing classdef
* liboctave/base-list.h (octave_base_list::octave_base_list (void),
octave_base_list::octave_base_list (const std::list<elt_type>&),
octave_base_list::operator = (const octave_base_list&),
octave_base_list::~octave_base_list (void)):
Now public.
* pt-classdef.h, pt-classdef.cc: New files.
* src/Makefile.am (PT_INCLUDES): Add pt-classdef.h to the list.
(PT_SRC): Add pt-classdef.cc to the list.
* pt-all.h: Include pt-classdef.h.
* ov.cc: Include ov-classdef.h.
* ov-classdef.cc: Include pt-classdef.h.
(cdef_class:make_meta_class): New method.
(F__meta_get_class__): Delete.
(F__superclass_reference__, F__meta_class_query__):
New functions.
* pt-id.h: Include oct-lvalue.h.
* pt-walk.h (tree_walker::visit_classdef (tree_classdef&),
tree_walker::visit_classdef_attribute (tree_classdef_attribute&),
tree_walker::visit_classdef_attribute_list (tree_classdef_attribute_list&),
tree_walker::visit_classdef_superclass (tree_classdef_superclass&),
tree_walker::visit_classdef_superclass_list (tree_classdef_superclass_list&),
tree_walker::visit_classdef_property (tree_classdef_property&),
tree_walker::visit_classdef_property_list (tree_classdef_property_list&),
tree_walker::visit_classdef_properties_block (tree_classdef_properties_block&),
tree_walker::visit_classdef_methods_list (tree_classdef_methods_list&),
tree_walker::visit_classdef_methods_block (tree_classdef_methods_block&),
tree_walker::visit_classdef_event (tree_classdef_event&),
tree_walker::visit_classdef_events_list (tree_classdef_events_list&),
tree_walker::visit_classdef_events_block (tree_classdef_events_block&),
tree_walker::visit_classdef_enum (tree_classdef_enum&),
tree_walker::visit_classdef_enum_list (tree_classdef_enum_list&),
tree_walker::visit_classdef_enum_block (tree_classdef_enum_block&),
tree_walker::visit_classdef_body (tree_classdef_body&)):
New virtual functions.
* token.h, token.cc (token::sc::mr, token::sc::cr, token::sc::pr,
token::mc::mr, token::mc::pr): Delete.
(token::sc::method_name, token::sc::package_name, token::sc::class_name,
token::mc::package_name, token::mc::class_name): New member variables.
(token::method_rec, token::class_rec, token::package_rec,
token::meta_class_rec, token::meta_package_rec): Delete.
(token::superclass_method_name, token::superclass_package_name,
token::superclass_class_name, token::meta_package_name,
token::meta_class_name): New methods.
(token::token (symbol_table::symbol_record*, int, int),
token::token (symbol_table::symbol_record*, symbol_table::symbol_record*, int, int),
token::token (symbol_table::symbol_record*, symbol_table::symbol_record*, symbol_table::symbol_record*, int, int)):
Delete.
(token::token (const std::string&, const std::string&, int, int),
token::token (const std::string&, const std::string&, const std::string&, int, int)):
New constructors.
(token::scls_rec_token, token::meta_rec_token): Delete enum values.
(token::scls_name_token, token::meta_rec_token): New enum values.
(token::~token): Delete sc and mc struct memebers.
* lex.ll, lex.h (lexical_feedback::parsing_classdef_get_method,
lexical_feedback::parsing_classdef_set_method)): New data members.
(lexical_feedback::lexical_feedback, lexical_feedback::init):
Initialize new data members.
(prep_lexer_for_classdef_file): New function.
(CLASSDEF_FILE_BEGIN): New exclusive start state.
(handle_superclass_identifier, handle_meta_identifier): Split
identifier here and create token with character strings.
(display_token): Handle CLASSDEF_FILE.
(display_state): Handle CLASSDEF_FILE_BEGIN.
* oct-parse.yy: Include ov-classdef.h and pt-funcall.h.
(classdef_object): New static variable.
(make_superclass_ref, make_meta_class_query, make_classdef,
make_classdef_properties_block, make_classdef_methods_block,
make_classdef_events_block, make_classdef_enum_block)): New functions.
(dummy_type): Delete unused nonterminal type.
(tok_type, tree_funcall_type, tree_function_def_type,
tree_classdef_type, tree_classdef_attribute_type,
tree_classdef_attribute_list_type, tree_classdef_superclass_type,
tree_classdef_superclass_list_type, tree_classdef_body_type,
tree_classdef_property_type, tree_classdef_property_list_type,
tree_classdef_properties_block_type, tree_classdef_methods_list_type,
tree_classdef_methods_block_type, tree_classdef_event_type,
tree_classdef_events_list_type, tree_classdef_events_block_type,
tree_classdef_enum_type, tree_classdef_enum_list_type,
tree_classdef_enum_block_type):
New types for nonterminals.
(CLASSDEF): Declare to have a tok_val token value.
(CLASSDEF_FILE): New token.
(classdef_end, properties_beg, methods_beg, events_beg, enum_beg,
classdef1): Delete nonterminals.
(property_list): Rename from properties_list.
(attr, class_event, class_enum, class_property, property_list,
properties_block, methods_list, methods_block, opt_attr_list,
attr_list, events_list, events_blcok, enum_list, enum_block,
class_body, classdef): Declare with specific types. Create parse tree
objects for these nonterminals.
(classdef_file): New nonterminal.
(parse_fcn_file): Handle classdef files. Don't treat classdef files
as scripts.
(command): Don't handle classdef here.
(input): Accept classdef_file here.
(fcn_name): If GET, set lexer_flags.parsing_classdef_get_method.
If SET, set lexer_flags.parsing_classdef_set_method.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 27 Jul 2012 17:10:25 -0400 |
parents | 460a3c6d8bf1 |
children |
comparison
equal
deleted
inserted
replaced
15036:aa1f9e479c6e | 15037:56b8eb7c9c04 |
---|---|
60 #include "input.h" | 60 #include "input.h" |
61 #include "lex.h" | 61 #include "lex.h" |
62 #include "load-path.h" | 62 #include "load-path.h" |
63 #include "oct-hist.h" | 63 #include "oct-hist.h" |
64 #include "oct-map.h" | 64 #include "oct-map.h" |
65 #include "ov-classdef.h" | |
65 #include "ov-fcn-handle.h" | 66 #include "ov-fcn-handle.h" |
66 #include "ov-usr-fcn.h" | 67 #include "ov-usr-fcn.h" |
67 #include "ov-null-mat.h" | 68 #include "ov-null-mat.h" |
68 #include "toplev.h" | 69 #include "toplev.h" |
69 #include "pager.h" | 70 #include "pager.h" |
70 #include "parse.h" | 71 #include "parse.h" |
71 #include "parse-private.h" | 72 #include "parse-private.h" |
72 #include "pt-all.h" | 73 #include "pt-all.h" |
73 #include "pt-eval.h" | 74 #include "pt-eval.h" |
75 #include "pt-funcall.h" | |
74 #include "symtab.h" | 76 #include "symtab.h" |
75 #include "token.h" | 77 #include "token.h" |
76 #include "unwind-prot.h" | 78 #include "unwind-prot.h" |
77 #include "utils.h" | 79 #include "utils.h" |
78 #include "variables.h" | 80 #include "variables.h" |
150 | 152 |
151 // Scope where we install all subfunctions and nested functions. Only | 153 // Scope where we install all subfunctions and nested functions. Only |
152 // used while reading function files. | 154 // used while reading function files. |
153 static symbol_table::scope_id primary_fcn_scope; | 155 static symbol_table::scope_id primary_fcn_scope; |
154 | 156 |
157 // Pointer to the classdef object we just parsed, if any. | |
158 static tree_classdef *classdef_object = 0; | |
159 | |
155 // List of autoloads (function -> file mapping). | 160 // List of autoloads (function -> file mapping). |
156 static std::map<std::string, std::string> autoload_map; | 161 static std::map<std::string, std::string> autoload_map; |
157 | 162 |
158 // Forward declarations for some functions defined at the bottom of | 163 // Forward declarations for some functions defined at the bottom of |
159 // the file. | 164 // the file. |
353 | 358 |
354 // Append a statement to an existing statement list. | 359 // Append a statement to an existing statement list. |
355 static tree_statement_list * | 360 static tree_statement_list * |
356 append_statement_list (tree_statement_list *list, char sep, | 361 append_statement_list (tree_statement_list *list, char sep, |
357 tree_statement *stmt, bool warn_missing_semi); | 362 tree_statement *stmt, bool warn_missing_semi); |
363 | |
364 static tree_funcall * | |
365 make_superclass_ref (const std::string& method_nm, | |
366 const std::string& package_nm, | |
367 const std::string& class_nm, | |
368 int l, int c); | |
369 | |
370 static tree_funcall * | |
371 make_meta_class_query (const std::string& package_nm, | |
372 const std::string& class_nm, | |
373 int l, int c); | |
374 | |
375 static tree_classdef * | |
376 make_classdef (token *tok_val, tree_classdef_attribute_list *a, | |
377 tree_identifier *id, tree_classdef_superclass_list *sc, | |
378 tree_classdef_body *body, token *end_tok, | |
379 octave_comment_list *lc); | |
380 | |
381 static tree_classdef_properties_block * | |
382 make_classdef_properties_block (token *tok_val, | |
383 tree_classdef_attribute_list *a, | |
384 tree_classdef_property_list *plist, | |
385 token *end_tok, octave_comment_list *lc); | |
386 | |
387 static 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, octave_comment_list *lc); | |
392 | |
393 static tree_classdef_events_block * | |
394 make_classdef_events_block (token *tok_val, | |
395 tree_classdef_attribute_list *a, | |
396 tree_classdef_events_list *elist, | |
397 token *end_tok, octave_comment_list *lc); | |
398 | |
399 static tree_classdef_enum_block * | |
400 make_classdef_enum_block (token *tok_val, | |
401 tree_classdef_attribute_list *a, | |
402 tree_classdef_enum_list *elist, | |
403 token *end_tok, octave_comment_list *lc); | |
358 | 404 |
359 // Finish building a statement. | 405 // Finish building a statement. |
360 template <class T> | 406 template <class T> |
361 static tree_statement * | 407 static tree_statement * |
362 make_statement (T *arg) | 408 make_statement (T *arg) |
398 // Comment strings that we need to deal with mid-rule. | 444 // Comment strings that we need to deal with mid-rule. |
399 octave_comment_list *comment_type; | 445 octave_comment_list *comment_type; |
400 | 446 |
401 // Types for the nonterminals we generate. | 447 // Types for the nonterminals we generate. |
402 char sep_type; | 448 char sep_type; |
449 token *tok_type; | |
403 tree *tree_type; | 450 tree *tree_type; |
404 tree_matrix *tree_matrix_type; | 451 tree_matrix *tree_matrix_type; |
405 tree_cell *tree_cell_type; | 452 tree_cell *tree_cell_type; |
406 tree_expression *tree_expression_type; | 453 tree_expression *tree_expression_type; |
407 tree_constant *tree_constant_type; | 454 tree_constant *tree_constant_type; |
408 tree_fcn_handle *tree_fcn_handle_type; | 455 tree_fcn_handle *tree_fcn_handle_type; |
456 tree_funcall *tree_funcall_type; | |
457 tree_function_def *tree_function_def_type; | |
409 tree_anon_fcn_handle *tree_anon_fcn_handle_type; | 458 tree_anon_fcn_handle *tree_anon_fcn_handle_type; |
410 tree_identifier *tree_identifier_type; | 459 tree_identifier *tree_identifier_type; |
411 tree_index_expression *tree_index_expression_type; | 460 tree_index_expression *tree_index_expression_type; |
412 tree_colon_expression *tree_colon_expression_type; | 461 tree_colon_expression *tree_colon_expression_type; |
413 tree_argument_list *tree_argument_list_type; | 462 tree_argument_list *tree_argument_list_type; |
423 tree_decl_init_list *tree_decl_init_list_type; | 472 tree_decl_init_list *tree_decl_init_list_type; |
424 tree_decl_command *tree_decl_command_type; | 473 tree_decl_command *tree_decl_command_type; |
425 tree_statement *tree_statement_type; | 474 tree_statement *tree_statement_type; |
426 tree_statement_list *tree_statement_list_type; | 475 tree_statement_list *tree_statement_list_type; |
427 octave_user_function *octave_user_function_type; | 476 octave_user_function *octave_user_function_type; |
428 void *dummy_type; | 477 |
478 tree_classdef *tree_classdef_type; | |
479 tree_classdef_attribute* tree_classdef_attribute_type; | |
480 tree_classdef_attribute_list* tree_classdef_attribute_list_type; | |
481 tree_classdef_superclass* tree_classdef_superclass_type; | |
482 tree_classdef_superclass_list* tree_classdef_superclass_list_type; | |
483 tree_classdef_body* tree_classdef_body_type; | |
484 tree_classdef_property* tree_classdef_property_type; | |
485 tree_classdef_property_list* tree_classdef_property_list_type; | |
486 tree_classdef_properties_block* tree_classdef_properties_block_type; | |
487 tree_classdef_methods_list* tree_classdef_methods_list_type; | |
488 tree_classdef_methods_block* tree_classdef_methods_block_type; | |
489 tree_classdef_event* tree_classdef_event_type; | |
490 tree_classdef_events_list* tree_classdef_events_list_type; | |
491 tree_classdef_events_block* tree_classdef_events_block_type; | |
492 tree_classdef_enum* tree_classdef_enum_type; | |
493 tree_classdef_enum_list* tree_classdef_enum_list_type; | |
494 tree_classdef_enum_block* tree_classdef_enum_block_type; | |
429 } | 495 } |
430 | 496 |
431 // Tokens with line and column information. | 497 // Tokens with line and column information. |
432 %token <tok_val> '=' ':' '-' '+' '*' '/' | 498 %token <tok_val> '=' ':' '-' '+' '*' '/' |
433 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ | 499 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ |
450 %token <tok_val> BREAK CONTINUE FUNC_RET | 516 %token <tok_val> BREAK CONTINUE FUNC_RET |
451 %token <tok_val> UNWIND CLEANUP | 517 %token <tok_val> UNWIND CLEANUP |
452 %token <tok_val> TRY CATCH | 518 %token <tok_val> TRY CATCH |
453 %token <tok_val> GLOBAL PERSISTENT | 519 %token <tok_val> GLOBAL PERSISTENT |
454 %token <tok_val> FCN_HANDLE | 520 %token <tok_val> FCN_HANDLE |
521 %token <tok_val> CLASSDEF | |
455 %token <tok_val> PROPERTIES METHODS EVENTS ENUMERATION | 522 %token <tok_val> PROPERTIES METHODS EVENTS ENUMERATION |
456 %token <tok_val> METAQUERY | 523 %token <tok_val> METAQUERY |
457 %token <tok_val> SUPERCLASSREF | 524 %token <tok_val> SUPERCLASSREF |
458 %token <tok_val> GET SET | 525 %token <tok_val> GET SET |
459 | 526 |
460 // Other tokens. | 527 // Other tokens. |
461 %token END_OF_INPUT LEXICAL_ERROR | 528 %token END_OF_INPUT LEXICAL_ERROR |
462 %token FCN SCRIPT_FILE FUNCTION_FILE CLASSDEF | 529 %token FCN SCRIPT_FILE CLASSDEF_FILE FUNCTION_FILE |
463 // %token VARARGIN VARARGOUT | 530 // %token VARARGIN VARARGOUT |
464 %token CLOSE_BRACE | 531 %token CLOSE_BRACE |
465 | 532 |
466 // Nonterminals we construct. | 533 // Nonterminals we construct. |
467 %type <comment_type> stash_comment function_beg classdef_beg | 534 %type <comment_type> stash_comment function_beg |
468 %type <comment_type> properties_beg methods_beg events_beg enum_beg | 535 %type <tok_type> classdef_beg |
469 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep opt_comma | 536 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep opt_comma |
470 %type <tree_type> input | 537 %type <tree_type> input |
471 %type <tree_constant_type> string constant magic_colon | 538 %type <tree_constant_type> string constant magic_colon |
472 %type <tree_anon_fcn_handle_type> anon_fcn_handle | 539 %type <tree_anon_fcn_handle_type> anon_fcn_handle |
473 %type <tree_fcn_handle_type> fcn_handle | 540 %type <tree_fcn_handle_type> fcn_handle |
475 %type <tree_cell_type> cell_rows cell_rows1 | 542 %type <tree_cell_type> cell_rows cell_rows1 |
476 %type <tree_expression_type> matrix cell | 543 %type <tree_expression_type> matrix cell |
477 %type <tree_expression_type> primary_expr oper_expr | 544 %type <tree_expression_type> primary_expr oper_expr |
478 %type <tree_expression_type> simple_expr colon_expr assign_expr expression | 545 %type <tree_expression_type> simple_expr colon_expr assign_expr expression |
479 %type <tree_identifier_type> identifier fcn_name magic_tilde | 546 %type <tree_identifier_type> identifier fcn_name magic_tilde |
480 %type <tree_identifier_type> superclass_identifier meta_identifier | 547 %type <tree_funcall_type> superclass_identifier meta_identifier |
481 %type <octave_user_function_type> function1 function2 classdef1 | 548 %type <octave_user_function_type> function1 function2 |
482 %type <tree_index_expression_type> word_list_cmd | 549 %type <tree_index_expression_type> word_list_cmd |
483 %type <tree_colon_expression_type> colon_expr1 | 550 %type <tree_colon_expression_type> colon_expr1 |
484 %type <tree_argument_list_type> arg_list word_list assign_lhs | 551 %type <tree_argument_list_type> arg_list word_list assign_lhs |
485 %type <tree_argument_list_type> cell_or_matrix_row | 552 %type <tree_argument_list_type> cell_or_matrix_row |
486 %type <tree_parameter_list_type> param_list param_list1 param_list2 | 553 %type <tree_parameter_list_type> param_list param_list1 param_list2 |
487 %type <tree_parameter_list_type> return_list return_list1 | 554 %type <tree_parameter_list_type> return_list return_list1 |
488 %type <tree_parameter_list_type> superclasses opt_superclasses | |
489 %type <tree_command_type> command select_command loop_command | 555 %type <tree_command_type> command select_command loop_command |
490 %type <tree_command_type> jump_command except_command function | 556 %type <tree_command_type> jump_command except_command |
491 %type <tree_command_type> script_file classdef | 557 %type <tree_function_def_type> function |
558 %type <tree_classdef_type> classdef | |
559 %type <tree_command_type> script_file classdef_file | |
492 %type <tree_command_type> function_file function_list | 560 %type <tree_command_type> function_file function_list |
493 %type <tree_if_command_type> if_command | 561 %type <tree_if_command_type> if_command |
494 %type <tree_if_clause_type> elseif_clause else_clause | 562 %type <tree_if_clause_type> elseif_clause else_clause |
495 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list | 563 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list |
496 %type <tree_switch_command_type> switch_command | 564 %type <tree_switch_command_type> switch_command |
497 %type <tree_switch_case_type> switch_case default_case | 565 %type <tree_switch_case_type> switch_case default_case |
498 %type <tree_switch_case_list_type> case_list1 case_list | 566 %type <tree_switch_case_list_type> case_list1 case_list |
499 %type <tree_decl_elt_type> decl2 | 567 %type <tree_decl_elt_type> decl2 |
500 %type <tree_decl_init_list_type> decl1 | 568 %type <tree_decl_init_list_type> decl1 |
501 %type <tree_decl_command_type> declaration | 569 %type <tree_decl_command_type> declaration |
502 %type <tree_statement_type> statement function_end classdef_end | 570 %type <tree_statement_type> statement function_end |
503 %type <tree_statement_list_type> simple_list simple_list1 list list1 | 571 %type <tree_statement_list_type> simple_list simple_list1 list list1 |
504 %type <tree_statement_list_type> opt_list input1 | 572 %type <tree_statement_list_type> opt_list input1 |
505 // These types need to be specified. | 573 |
506 %type <dummy_type> attr | 574 %type <tree_classdef_attribute_type> attr |
507 %type <dummy_type> class_event | 575 %type <tree_classdef_attribute_list_type> attr_list opt_attr_list |
508 %type <dummy_type> class_enum | 576 %type <tree_classdef_superclass_type> superclass |
509 %type <dummy_type> class_property | 577 %type <tree_classdef_superclass_list_type> superclass_list opt_superclass_list |
510 %type <dummy_type> properties_list | 578 %type <tree_classdef_body_type> class_body |
511 %type <dummy_type> properties_block | 579 %type <tree_classdef_property_type> class_property |
512 %type <dummy_type> methods_list | 580 %type <tree_classdef_property_list_type> property_list |
513 %type <dummy_type> methods_block | 581 %type <tree_classdef_properties_block_type> properties_block |
514 %type <dummy_type> opt_attr_list | 582 %type <tree_classdef_methods_list_type> methods_list |
515 %type <dummy_type> attr_list | 583 %type <tree_classdef_methods_block_type> methods_block |
516 %type <dummy_type> events_list | 584 %type <tree_classdef_event_type> class_event |
517 %type <dummy_type> events_block | 585 %type <tree_classdef_events_list_type> events_list |
518 %type <dummy_type> enum_list | 586 %type <tree_classdef_events_block_type> events_block |
519 %type <dummy_type> enum_block | 587 %type <tree_classdef_enum_type> class_enum |
520 %type <dummy_type> class_body | 588 %type <tree_classdef_enum_list_type> enum_list |
589 %type <tree_classdef_enum_block_type> enum_block | |
521 | 590 |
522 // Precedence and associativity. | 591 // Precedence and associativity. |
523 %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ | 592 %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ |
524 %left EXPR_OR_OR | 593 %left EXPR_OR_OR |
525 %left EXPR_AND_AND | 594 %left EXPR_AND_AND |
550 promptflag = 1; | 619 promptflag = 1; |
551 YYACCEPT; | 620 YYACCEPT; |
552 } | 621 } |
553 | function_file | 622 | function_file |
554 { YYACCEPT; } | 623 { YYACCEPT; } |
624 | classdef_file | |
625 { YYACCEPT; } | |
555 | simple_list parse_error | 626 | simple_list parse_error |
556 { ABORT_PARSE; } | 627 { ABORT_PARSE; } |
557 | parse_error | 628 | parse_error |
558 { ABORT_PARSE; } | 629 { ABORT_PARSE; } |
559 ; | 630 ; |
639 } | 710 } |
640 ; | 711 ; |
641 | 712 |
642 superclass_identifier | 713 superclass_identifier |
643 : SUPERCLASSREF | 714 : SUPERCLASSREF |
644 { $$ = new tree_identifier ($1->line (), $1->column ()); } | 715 { |
716 std::string method_nm = $1->superclass_method_name (); | |
717 std::string package_nm = $1->superclass_package_name (); | |
718 std::string class_nm = $1->superclass_class_name (); | |
719 | |
720 $$ = make_superclass_ref (method_nm, package_nm, class_nm, | |
721 $1->line (), $1->column ()); | |
722 } | |
645 ; | 723 ; |
646 | 724 |
647 meta_identifier : METAQUERY | 725 meta_identifier : METAQUERY |
648 { $$ = new tree_identifier ($1->line (), $1->column ()); } | 726 { |
727 std::string package_nm = $1->meta_package_name (); | |
728 std::string class_nm = $1->meta_class_name (); | |
729 | |
730 $$ = make_meta_class_query (package_nm, class_nm, | |
731 $1->line (), $1->column ()); | |
732 } | |
649 ; | 733 ; |
650 | 734 |
651 string : DQ_STRING | 735 string : DQ_STRING |
652 { $$ = make_constant (DQ_STRING, $1); } | 736 { $$ = make_constant (DQ_STRING, $1); } |
653 | SQ_STRING | 737 | SQ_STRING |
982 { $$ = $1; } | 1066 { $$ = $1; } |
983 | function | 1067 | function |
984 { $$ = $1; } | 1068 { $$ = $1; } |
985 | script_file | 1069 | script_file |
986 { $$ = $1; } | 1070 { $$ = $1; } |
987 | classdef | |
988 { $$ = $1; } | |
989 ; | 1071 ; |
990 | 1072 |
991 // ===================== | 1073 // ===================== |
992 // Declaration statemnts | 1074 // Declaration statemnts |
993 // ===================== | 1075 // ===================== |
1402 } | 1484 } |
1403 | GET '.' identifier | 1485 | GET '.' identifier |
1404 { | 1486 { |
1405 lexer_flags.parsed_function_name.top () = true; | 1487 lexer_flags.parsed_function_name.top () = true; |
1406 lexer_flags.maybe_classdef_get_set_method = false; | 1488 lexer_flags.maybe_classdef_get_set_method = false; |
1489 lexer_flags.parsing_classdef_get_method = true; | |
1407 $$ = $3; | 1490 $$ = $3; |
1408 } | 1491 } |
1409 | SET '.' identifier | 1492 | SET '.' identifier |
1410 { | 1493 { |
1411 lexer_flags.parsed_function_name.top () = true; | 1494 lexer_flags.parsed_function_name.top () = true; |
1412 lexer_flags.maybe_classdef_get_set_method = false; | 1495 lexer_flags.maybe_classdef_get_set_method = false; |
1496 lexer_flags.parsing_classdef_set_method = true; | |
1413 $$ = $3; | 1497 $$ = $3; |
1414 } | 1498 } |
1415 ; | 1499 ; |
1416 | 1500 |
1417 function1 : fcn_name function2 | 1501 function1 : fcn_name function2 |
1472 $$ = make_end ("endfunction", input_line_number, | 1556 $$ = make_end ("endfunction", input_line_number, |
1473 current_input_column); | 1557 current_input_column); |
1474 } | 1558 } |
1475 ; | 1559 ; |
1476 | 1560 |
1561 // ============= | |
1562 // Classdef file | |
1563 // ============= | |
1564 | |
1565 classdef_file : CLASSDEF_FILE classdef opt_sep END_OF_INPUT | |
1566 { | |
1567 classdef_object = $2; | |
1568 $$ = 0; | |
1569 } | |
1570 ; | |
1571 | |
1477 // ======== | 1572 // ======== |
1478 // Classdef | 1573 // Classdef |
1479 // ======== | 1574 // ======== |
1480 | 1575 |
1481 classdef_beg : CLASSDEF stash_comment | 1576 classdef_beg : CLASSDEF |
1482 { | 1577 { |
1483 $$ = 0; | 1578 if (! reading_classdef_file) |
1579 { | |
1580 yyerror ("classdef must appear inside a file containing only a class definition"); | |
1581 YYABORT; | |
1582 } | |
1583 | |
1484 lexer_flags.parsing_classdef = true; | 1584 lexer_flags.parsing_classdef = true; |
1485 } | 1585 $$ = $1; |
1486 ; | 1586 } |
1487 | 1587 ; |
1488 classdef_end : END | 1588 |
1589 classdef : classdef_beg stash_comment opt_attr_list identifier opt_superclass_list opt_sep class_body opt_sep END | |
1489 { | 1590 { |
1490 lexer_flags.parsing_classdef = false; | 1591 lexer_flags.parsing_classdef = false; |
1491 | 1592 $$ = make_classdef ($1, $3, $4, $5, $7, $9, $2); |
1492 if (end_token_ok ($1, token::classdef_end)) | 1593 } |
1493 $$ = make_end ("endclassdef", $1->line (), $1->column ()); | |
1494 else | |
1495 ABORT_PARSE; | |
1496 } | |
1497 ; | |
1498 | |
1499 classdef1 : classdef_beg opt_attr_list identifier opt_superclasses | |
1500 { $$ = 0; } | |
1501 ; | |
1502 | |
1503 classdef : classdef1 opt_sep class_body opt_sep stash_comment classdef_end | |
1504 { $$ = 0; } | |
1505 ; | 1594 ; |
1506 | 1595 |
1507 opt_attr_list : // empty | 1596 opt_attr_list : // empty |
1508 { $$ = 0; } | 1597 { $$ = 0; } |
1509 | '(' attr_list ')' | 1598 | '(' attr_list ')' |
1510 { $$ = 0; } | 1599 { $$ = $2; } |
1511 ; | 1600 ; |
1512 | 1601 |
1513 attr_list : attr | 1602 attr_list : attr |
1514 { $$ = 0; } | 1603 { $$ = new tree_classdef_attribute_list ($1); } |
1515 | attr_list ',' attr | 1604 | attr_list ',' attr |
1516 { $$ = 0; } | 1605 { |
1606 $1->append ($3); | |
1607 $$ = $1; | |
1608 } | |
1517 ; | 1609 ; |
1518 | 1610 |
1519 attr : identifier | 1611 attr : identifier |
1520 { $$ = 0; } | 1612 { $$ = new tree_classdef_attribute ($1); } |
1521 | identifier '=' decl_param_init expression | 1613 | identifier '=' decl_param_init expression |
1522 { $$ = 0; } | 1614 { |
1615 lexer_flags.looking_at_initializer_expression = false; | |
1616 $$ = new tree_classdef_attribute ($1, $4); | |
1617 } | |
1523 | EXPR_NOT identifier | 1618 | EXPR_NOT identifier |
1524 { $$ = 0; } | 1619 { $$ = new tree_classdef_attribute ($2, false); } |
1525 ; | 1620 ; |
1526 | 1621 |
1527 opt_superclasses | 1622 opt_superclass_list |
1528 : // empty | 1623 : // empty |
1529 { $$ = 0; } | 1624 { $$ = 0; } |
1530 | superclasses | 1625 | superclass_list |
1531 { $$ = 0; } | 1626 { $$ = $1; } |
1532 ; | 1627 ; |
1533 | 1628 |
1534 superclasses : EXPR_LT identifier '.' identifier | 1629 superclass_list : EXPR_LT superclass |
1535 { $$ = 0; } | 1630 { $$ = new tree_classdef_superclass_list ($2); } |
1536 | EXPR_LT identifier | 1631 | superclass_list EXPR_AND superclass |
1537 { $$ = 0; } | 1632 { |
1538 | superclasses EXPR_AND identifier '.' identifier | 1633 $1->append ($3); |
1539 { $$ = 0; } | 1634 $$ = $1; |
1540 | superclasses EXPR_AND identifier | 1635 } |
1541 { $$ = 0; } | 1636 ; |
1637 | |
1638 superclass : identifier | |
1639 { $$ = new tree_classdef_superclass ($1); } | |
1640 | identifier '.' identifier | |
1641 { $$ = new tree_classdef_superclass ($3, $1); } | |
1542 ; | 1642 ; |
1543 | 1643 |
1544 class_body : properties_block | 1644 class_body : properties_block |
1545 { $$ = 0; } | 1645 { $$ = new tree_classdef_body ($1); } |
1546 | methods_block | 1646 | methods_block |
1547 { $$ = 0; } | 1647 { $$ = new tree_classdef_body ($1); } |
1548 | events_block | 1648 | events_block |
1549 { $$ = 0; } | 1649 { $$ = new tree_classdef_body ($1); } |
1550 | enum_block | 1650 | enum_block |
1551 { $$ = 0; } | 1651 { $$ = new tree_classdef_body ($1); } |
1552 | class_body opt_sep properties_block | 1652 | class_body opt_sep properties_block |
1553 { $$ = 0; } | 1653 { |
1654 $1->append ($3); | |
1655 $$ = $1; | |
1656 } | |
1554 | class_body opt_sep methods_block | 1657 | class_body opt_sep methods_block |
1555 { $$ = 0; } | 1658 { |
1659 $1->append ($3); | |
1660 $$ = $1; | |
1661 } | |
1556 | class_body opt_sep events_block | 1662 | class_body opt_sep events_block |
1557 { $$ = 0; } | 1663 { |
1664 $1->append ($3); | |
1665 $$ = $1; | |
1666 } | |
1558 | class_body opt_sep enum_block | 1667 | class_body opt_sep enum_block |
1559 { $$ = 0; } | 1668 { |
1560 ; | 1669 $1->append ($3); |
1561 | 1670 $$ = $1; |
1562 properties_beg : PROPERTIES stash_comment | 1671 } |
1563 { $$ = 0; } | |
1564 ; | 1672 ; |
1565 | 1673 |
1566 properties_block | 1674 properties_block |
1567 : properties_beg opt_attr_list opt_sep properties_list opt_sep END | 1675 : PROPERTIES stash_comment opt_attr_list opt_sep property_list opt_sep END |
1568 { $$ = 0; } | 1676 { |
1569 ; | 1677 if (! ($$ = make_classdef_properties_block ($1, $3, $5, $7, $2))) |
1570 | 1678 ABORT_PARSE; |
1571 properties_list | 1679 } |
1680 ; | |
1681 | |
1682 property_list | |
1572 : class_property | 1683 : class_property |
1573 { $$ = 0; } | 1684 { $$ = new tree_classdef_property_list ($1); } |
1574 | properties_list opt_sep class_property | 1685 | property_list opt_sep class_property |
1575 { $$ = 0; } | 1686 { |
1687 $1->append ($3); | |
1688 $$ = $1; | |
1689 } | |
1576 ; | 1690 ; |
1577 | 1691 |
1578 class_property : identifier | 1692 class_property : identifier |
1579 { $$ = 0; } | 1693 { $$ = new tree_classdef_property ($1); } |
1580 | identifier '=' decl_param_init expression ';' | 1694 | identifier '=' decl_param_init expression ';' |
1581 { $$ = 0; } | 1695 { |
1582 ; | 1696 lexer_flags.looking_at_initializer_expression = false; |
1583 | 1697 $$ = new tree_classdef_property ($1, $4); |
1584 methods_beg : METHODS stash_comment | 1698 } |
1585 { $$ = 0; } | 1699 ; |
1586 ; | 1700 |
1587 | 1701 methods_block : METHODS stash_comment opt_attr_list opt_sep methods_list opt_sep END |
1588 methods_block : methods_beg opt_attr_list opt_sep methods_list opt_sep END | 1702 { |
1589 { $$ = 0; } | 1703 if (! ($$ = make_classdef_methods_block ($1, $3, $5, $7, $2))) |
1704 ABORT_PARSE; | |
1705 } | |
1590 ; | 1706 ; |
1591 | 1707 |
1592 methods_list : function | 1708 methods_list : function |
1593 { $$ = 0; } | 1709 { |
1710 octave_value fcn; | |
1711 if ($1) | |
1712 fcn = $1->function (); | |
1713 delete $1; | |
1714 $$ = new tree_classdef_methods_list (fcn); | |
1715 } | |
1594 | methods_list opt_sep function | 1716 | methods_list opt_sep function |
1595 { $$ = 0; } | 1717 { |
1596 ; | 1718 octave_value fcn; |
1597 | 1719 if ($3) |
1598 events_beg : EVENTS stash_comment | 1720 fcn = $3->function (); |
1599 { $$ = 0; } | 1721 delete $3; |
1600 ; | 1722 |
1601 | 1723 $1->append (fcn); |
1602 events_block : events_beg opt_attr_list opt_sep events_list opt_sep END | 1724 $$ = $1; |
1603 { $$ = 0; } | 1725 } |
1726 ; | |
1727 | |
1728 events_block : EVENTS stash_comment opt_attr_list opt_sep events_list opt_sep END | |
1729 { | |
1730 if (! ($$ = make_classdef_events_block ($1, $3, $5, $7, $2))) | |
1731 ABORT_PARSE; | |
1732 } | |
1604 ; | 1733 ; |
1605 | 1734 |
1606 events_list : class_event | 1735 events_list : class_event |
1607 { $$ = 0; } | 1736 { $$ = new tree_classdef_events_list ($1); } |
1608 | events_list opt_sep class_event | 1737 | events_list opt_sep class_event |
1609 { $$ = 0; } | 1738 { |
1739 $1->append ($3); | |
1740 $$ = $1; | |
1741 } | |
1610 ; | 1742 ; |
1611 | 1743 |
1612 class_event : identifier | 1744 class_event : identifier |
1613 { $$ = 0; } | 1745 { $$ = new tree_classdef_event ($1); } |
1614 ; | 1746 ; |
1615 | 1747 |
1616 enum_beg : ENUMERATION stash_comment | 1748 enum_block : ENUMERATION stash_comment opt_attr_list opt_sep enum_list opt_sep END |
1617 { $$ = 0; } | 1749 { |
1618 ; | 1750 if (! ($$ = make_classdef_enum_block ($1, $3, $5, $7, $2))) |
1619 | 1751 ABORT_PARSE; |
1620 enum_block : enum_beg opt_attr_list opt_sep enum_list opt_sep END | 1752 } |
1621 { $$ = 0; } | |
1622 ; | 1753 ; |
1623 | 1754 |
1624 enum_list : class_enum | 1755 enum_list : class_enum |
1625 { $$ = 0; } | 1756 { $$ = new tree_classdef_enum_list ($1); } |
1626 | enum_list opt_sep class_enum | 1757 | enum_list opt_sep class_enum |
1627 { $$ = 0; } | 1758 { |
1759 $1->append ($3); | |
1760 $$ = $1; | |
1761 } | |
1628 ; | 1762 ; |
1629 | 1763 |
1630 class_enum : identifier '(' expression ')' | 1764 class_enum : identifier '(' expression ')' |
1631 { $$ = 0; } | 1765 { $$ = new tree_classdef_enum ($1, $3); } |
1632 ; | 1766 ; |
1633 | 1767 |
1634 // ============= | 1768 // ============= |
1635 // Miscellaneous | 1769 // Miscellaneous |
1636 // ============= | 1770 // ============= |
3266 list->append (stmt); | 3400 list->append (stmt); |
3267 | 3401 |
3268 return list; | 3402 return list; |
3269 } | 3403 } |
3270 | 3404 |
3405 static tree_funcall * | |
3406 make_superclass_ref (const std::string& method_nm, | |
3407 const std::string& package_nm, | |
3408 const std::string& class_nm, | |
3409 int l, int c) | |
3410 { | |
3411 octave_value_list args; | |
3412 | |
3413 args(2) = class_nm; | |
3414 args(1) = package_nm; | |
3415 args(0) = method_nm; | |
3416 | |
3417 octave_value fcn | |
3418 = symbol_table::find_built_in_function ("__superclass_reference__"); | |
3419 | |
3420 return new tree_funcall (fcn, args); | |
3421 } | |
3422 | |
3423 static tree_funcall * | |
3424 make_meta_class_query (const std::string& package_nm, | |
3425 const std::string& class_nm, | |
3426 int l, int c) | |
3427 { | |
3428 octave_value_list args; | |
3429 | |
3430 args(1) = class_nm; | |
3431 args(0) = package_nm; | |
3432 | |
3433 octave_value fcn | |
3434 = symbol_table::find_built_in_function ("__meta_class_query__"); | |
3435 | |
3436 return new tree_funcall (fcn, args); | |
3437 } | |
3438 | |
3439 // A CLASSDEF block defines a class that has a constructor and other | |
3440 // methods, but it is not an executable command. Parsing the block | |
3441 // makes some changes in the symbol table (inserting the constructor | |
3442 // and methods, and adding to the list of known objects) and creates | |
3443 // a parse tree containing meta information about the class. | |
3444 | |
3445 static tree_classdef * | |
3446 make_classdef (token *tok_val, tree_classdef_attribute_list *a, | |
3447 tree_identifier *id, tree_classdef_superclass_list *sc, | |
3448 tree_classdef_body *body, token *end_tok, | |
3449 octave_comment_list *lc) | |
3450 { | |
3451 tree_classdef *retval = 0; | |
3452 | |
3453 if (end_token_ok (end_tok, token::classdef_end)) | |
3454 { | |
3455 octave_comment_list *tc = octave_comment_buffer::get_comment (); | |
3456 | |
3457 int l = tok_val->line (); | |
3458 int c = tok_val->column (); | |
3459 | |
3460 retval = new tree_classdef (a, id, sc, body, lc, tc, l, c); | |
3461 } | |
3462 | |
3463 return retval; | |
3464 } | |
3465 | |
3466 static tree_classdef_properties_block * | |
3467 make_classdef_properties_block (token *tok_val, | |
3468 tree_classdef_attribute_list *a, | |
3469 tree_classdef_property_list *plist, | |
3470 token *end_tok, octave_comment_list *lc) | |
3471 { | |
3472 tree_classdef_properties_block *retval = 0; | |
3473 | |
3474 if (end_token_ok (end_tok, token::properties_end)) | |
3475 { | |
3476 octave_comment_list *tc = octave_comment_buffer::get_comment (); | |
3477 | |
3478 int l = tok_val->line (); | |
3479 int c = tok_val->column (); | |
3480 | |
3481 retval = new tree_classdef_properties_block (a, plist, lc, tc, l, c); | |
3482 } | |
3483 | |
3484 return retval; | |
3485 } | |
3486 | |
3487 static tree_classdef_methods_block * | |
3488 make_classdef_methods_block (token *tok_val, | |
3489 tree_classdef_attribute_list *a, | |
3490 tree_classdef_methods_list *mlist, | |
3491 token *end_tok, octave_comment_list *lc) | |
3492 { | |
3493 tree_classdef_methods_block *retval = 0; | |
3494 | |
3495 if (end_token_ok (end_tok, token::methods_end)) | |
3496 { | |
3497 octave_comment_list *tc = octave_comment_buffer::get_comment (); | |
3498 | |
3499 int l = tok_val->line (); | |
3500 int c = tok_val->column (); | |
3501 | |
3502 retval = new tree_classdef_methods_block (a, mlist, lc, tc, l, c); | |
3503 } | |
3504 | |
3505 return retval; | |
3506 } | |
3507 | |
3508 static tree_classdef_events_block * | |
3509 make_classdef_events_block (token *tok_val, | |
3510 tree_classdef_attribute_list *a, | |
3511 tree_classdef_events_list *elist, | |
3512 token *end_tok, octave_comment_list *lc) | |
3513 { | |
3514 tree_classdef_events_block *retval = 0; | |
3515 | |
3516 if (end_token_ok (end_tok, token::events_end)) | |
3517 { | |
3518 octave_comment_list *tc = octave_comment_buffer::get_comment (); | |
3519 | |
3520 int l = tok_val->line (); | |
3521 int c = tok_val->column (); | |
3522 | |
3523 retval = new tree_classdef_events_block (a, elist, lc, tc, l, c); | |
3524 } | |
3525 | |
3526 return retval; | |
3527 } | |
3528 | |
3529 static tree_classdef_enum_block * | |
3530 make_classdef_enum_block (token *tok_val, | |
3531 tree_classdef_attribute_list *a, | |
3532 tree_classdef_enum_list *elist, | |
3533 token *end_tok, octave_comment_list *lc) | |
3534 { | |
3535 tree_classdef_enum_block *retval = 0; | |
3536 | |
3537 if (end_token_ok (end_tok, token::enumeration_end)) | |
3538 { | |
3539 octave_comment_list *tc = octave_comment_buffer::get_comment (); | |
3540 | |
3541 int l = tok_val->line (); | |
3542 int c = tok_val->column (); | |
3543 | |
3544 retval = new tree_classdef_enum_block (a, elist, lc, tc, l, c); | |
3545 } | |
3546 | |
3547 return retval; | |
3548 } | |
3549 | |
3271 static void | 3550 static void |
3272 safe_fclose (FILE *f) | 3551 safe_fclose (FILE *f) |
3273 { | 3552 { |
3274 // FIXME -- comments at the end of an input file are | 3553 // FIXME -- comments at the end of an input file are |
3275 // discarded (otherwise, they would be appended to the next | 3554 // discarded (otherwise, they would be appended to the next |
3544 | 3823 |
3545 Vecho_executing_commands = ECHO_OFF; | 3824 Vecho_executing_commands = ECHO_OFF; |
3546 | 3825 |
3547 reading_classdef_file = true; | 3826 reading_classdef_file = true; |
3548 reading_fcn_file = false; | 3827 reading_fcn_file = false; |
3549 // FIXME -- Should classdef files be handled as | 3828 reading_script_file = false; |
3550 // scripts or separately? Currently, without setting up | |
3551 // for reading script files, parsing classdef files | |
3552 // fails. | |
3553 reading_script_file = true; | |
3554 } | 3829 } |
3555 else | 3830 else |
3556 { | 3831 { |
3557 file_type = "script"; | 3832 file_type = "script"; |
3558 | 3833 |
3571 | 3846 |
3572 switch_to_buffer (new_buf); | 3847 switch_to_buffer (new_buf); |
3573 | 3848 |
3574 frame.protect_var (primary_fcn_ptr); | 3849 frame.protect_var (primary_fcn_ptr); |
3575 primary_fcn_ptr = 0; | 3850 primary_fcn_ptr = 0; |
3851 | |
3852 frame.protect_var (classdef_object); | |
3853 classdef_object = 0; | |
3576 | 3854 |
3577 reset_parser (); | 3855 reset_parser (); |
3578 | 3856 |
3579 // Do this with an unwind-protect cleanup function so that | 3857 // Do this with an unwind-protect cleanup function so that |
3580 // the forced variables will be unmarked in the event of an | 3858 // the forced variables will be unmarked in the event of an |
3585 if (! help_txt.empty ()) | 3863 if (! help_txt.empty ()) |
3586 help_buf.push (help_txt); | 3864 help_buf.push (help_txt); |
3587 | 3865 |
3588 if (reading_script_file) | 3866 if (reading_script_file) |
3589 prep_lexer_for_script_file (); | 3867 prep_lexer_for_script_file (); |
3868 else if (reading_classdef_file) | |
3869 prep_lexer_for_classdef_file (); | |
3590 else | 3870 else |
3591 prep_lexer_for_function_file (); | 3871 prep_lexer_for_function_file (); |
3592 | 3872 |
3593 lexer_flags.parsing_class_method = ! dispatch_type.empty (); | 3873 lexer_flags.parsing_class_method = ! dispatch_type.empty (); |
3594 | 3874 |
3604 | 3884 |
3605 frame.add_fcn (cleanup_statement_list, &global_command); | 3885 frame.add_fcn (cleanup_statement_list, &global_command); |
3606 | 3886 |
3607 fcn_ptr = primary_fcn_ptr; | 3887 fcn_ptr = primary_fcn_ptr; |
3608 | 3888 |
3609 if (status != 0) | 3889 if (status == 0) |
3610 error ("parse error while reading %s file %s", | 3890 { |
3611 file_type.c_str (), ff.c_str ()); | 3891 if (reading_classdef_file && classdef_object) |
3892 { | |
3893 // Convert parse tree for classdef object to | |
3894 // meta.class info (and stash it in the symbol | |
3895 // table?). Return pointer to constructor? | |
3896 | |
3897 octave_value meta_class = classdef_object->make_meta_class (); | |
3898 } | |
3899 } | |
3900 else | |
3901 { | |
3902 error ("parse error while reading %s file %s", | |
3903 file_type.c_str(), ff.c_str ()); | |
3904 } | |
3612 } | 3905 } |
3613 else | 3906 else |
3614 { | 3907 { |
3615 tree_statement *end_of_script | 3908 tree_statement *end_of_script |
3616 = make_end ("endscript", input_line_number, current_input_column); | 3909 = make_end ("endscript", input_line_number, current_input_column); |