comparison src/parse.y @ 9476:d9b25c5b8ee5

handle classdef syntax in lexer and parser
author Ryan Rusaw
date Thu, 30 Jul 2009 16:26:39 -0400
parents 25ed2d6aacf6
children 4562a9a730ae
comparison
equal deleted inserted replaced
9475:983de84e4bf3 9476:d9b25c5b8ee5
408 tree_decl_init_list *tree_decl_init_list_type; 408 tree_decl_init_list *tree_decl_init_list_type;
409 tree_decl_command *tree_decl_command_type; 409 tree_decl_command *tree_decl_command_type;
410 tree_statement *tree_statement_type; 410 tree_statement *tree_statement_type;
411 tree_statement_list *tree_statement_list_type; 411 tree_statement_list *tree_statement_list_type;
412 octave_user_function *octave_user_function_type; 412 octave_user_function *octave_user_function_type;
413 void *dummy_type;
413 } 414 }
414 415
415 // Tokens with line and column information. 416 // Tokens with line and column information.
416 %token <tok_val> '=' ':' '-' '+' '*' '/' 417 %token <tok_val> '=' ':' '-' '+' '*' '/'
417 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ 418 %token <tok_val> ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ
434 %token <tok_val> BREAK CONTINUE FUNC_RET 435 %token <tok_val> BREAK CONTINUE FUNC_RET
435 %token <tok_val> UNWIND CLEANUP 436 %token <tok_val> UNWIND CLEANUP
436 %token <tok_val> TRY CATCH 437 %token <tok_val> TRY CATCH
437 %token <tok_val> GLOBAL STATIC 438 %token <tok_val> GLOBAL STATIC
438 %token <tok_val> FCN_HANDLE 439 %token <tok_val> FCN_HANDLE
440 %token <tok_val> PROPERTIES
441 %token <tok_val> METHODS
442 %token <tok_val> EVENTS
443 %token <tok_val> METAQUERY
444 %token <tok_val> SUPERCLASSREF
445 %token <tok_val> GET SET
439 446
440 // Other tokens. 447 // Other tokens.
441 %token END_OF_INPUT LEXICAL_ERROR 448 %token END_OF_INPUT LEXICAL_ERROR
442 %token FCN SCRIPT_FILE FUNCTION_FILE 449 %token FCN SCRIPT_FILE FUNCTION_FILE CLASSDEF
443 // %token VARARGIN VARARGOUT 450 // %token VARARGIN VARARGOUT
444 %token CLOSE_BRACE 451 %token CLOSE_BRACE
445 452
446 // Nonterminals we construct. 453 // Nonterminals we construct.
447 %type <comment_type> stash_comment function_beg 454 %type <comment_type> stash_comment function_beg classdef_beg
455 %type <comment_type> properties_beg methods_beg events_beg
448 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep 456 %type <sep_type> sep_no_nl opt_sep_no_nl sep opt_sep
449 %type <tree_type> input 457 %type <tree_type> input
450 %type <tree_constant_type> string constant magic_colon 458 %type <tree_constant_type> string constant magic_colon
451 %type <tree_anon_fcn_handle_type> anon_fcn_handle 459 %type <tree_anon_fcn_handle_type> anon_fcn_handle
452 %type <tree_fcn_handle_type> fcn_handle 460 %type <tree_fcn_handle_type> fcn_handle
454 %type <tree_cell_type> cell_rows cell_rows1 462 %type <tree_cell_type> cell_rows cell_rows1
455 %type <tree_expression_type> matrix cell 463 %type <tree_expression_type> matrix cell
456 %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr 464 %type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr
457 %type <tree_expression_type> simple_expr colon_expr assign_expr expression 465 %type <tree_expression_type> simple_expr colon_expr assign_expr expression
458 %type <tree_identifier_type> identifier fcn_name 466 %type <tree_identifier_type> identifier fcn_name
459 %type <octave_user_function_type> function1 function2 467 %type <tree_identifier_type> superclass_identifier meta_identifier
468 %type <octave_user_function_type> function1 function2 classdef1
460 %type <tree_index_expression_type> word_list_cmd 469 %type <tree_index_expression_type> word_list_cmd
461 %type <tree_colon_expression_type> colon_expr1 470 %type <tree_colon_expression_type> colon_expr1
462 %type <tree_argument_list_type> arg_list word_list assign_lhs 471 %type <tree_argument_list_type> arg_list word_list assign_lhs
463 %type <tree_argument_list_type> cell_or_matrix_row 472 %type <tree_argument_list_type> cell_or_matrix_row
464 %type <tree_parameter_list_type> param_list param_list1 param_list2 473 %type <tree_parameter_list_type> param_list param_list1 param_list2
465 %type <tree_parameter_list_type> return_list return_list1 474 %type <tree_parameter_list_type> return_list return_list1
475 %type <tree_parameter_list_type> superclasses opt_superclasses
466 %type <tree_command_type> command select_command loop_command 476 %type <tree_command_type> command select_command loop_command
467 %type <tree_command_type> jump_command except_command function script_file 477 %type <tree_command_type> jump_command except_command function
478 %type <tree_command_type> script_file classdef
468 %type <tree_command_type> function_file function_list 479 %type <tree_command_type> function_file function_list
469 %type <tree_if_command_type> if_command 480 %type <tree_if_command_type> if_command
470 %type <tree_if_clause_type> elseif_clause else_clause 481 %type <tree_if_clause_type> elseif_clause else_clause
471 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list 482 %type <tree_if_command_list_type> if_cmd_list1 if_cmd_list
472 %type <tree_switch_command_type> switch_command 483 %type <tree_switch_command_type> switch_command
473 %type <tree_switch_case_type> switch_case default_case 484 %type <tree_switch_case_type> switch_case default_case
474 %type <tree_switch_case_list_type> case_list1 case_list 485 %type <tree_switch_case_list_type> case_list1 case_list
475 %type <tree_decl_elt_type> decl2 486 %type <tree_decl_elt_type> decl2
476 %type <tree_decl_init_list_type> decl1 487 %type <tree_decl_init_list_type> decl1
477 %type <tree_decl_command_type> declaration 488 %type <tree_decl_command_type> declaration
478 %type <tree_statement_type> statement function_end 489 %type <tree_statement_type> statement function_end classdef_end
479 %type <tree_statement_list_type> simple_list simple_list1 list list1 490 %type <tree_statement_list_type> simple_list simple_list1 list list1
480 %type <tree_statement_list_type> opt_list input1 491 %type <tree_statement_list_type> opt_list input1
492 // These types need to be specified.
493 %type <dummy_type> attr
494 %type <dummy_type> class_event
495 %type <dummy_type> class_property
496 %type <dummy_type> properties_list
497 %type <dummy_type> properties_block
498 %type <dummy_type> methods_list
499 %type <dummy_type> methods_block
500 %type <dummy_type> opt_attr_list
501 %type <dummy_type> attr_list
502 %type <dummy_type> events_list
503 %type <dummy_type> events_block
504 %type <dummy_type> class_body
481 505
482 // Precedence and associativity. 506 // Precedence and associativity.
483 %left ';' ',' '\n' 507 %left ';' ',' '\n'
484 %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 508 %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
485 %left EXPR_OR_OR 509 %left EXPR_OR_OR
599 symbol_table::symbol_record *sr = $1->sym_rec (); 623 symbol_table::symbol_record *sr = $1->sym_rec ();
600 $$ = new tree_identifier (*sr, $1->line (), $1->column ()); 624 $$ = new tree_identifier (*sr, $1->line (), $1->column ());
601 } 625 }
602 ; 626 ;
603 627
628 superclass_identifier
629 : SUPERCLASSREF
630 { $$ = new tree_identifier ($1->line (), $1->column ()); }
631 ;
632
633 meta_identifier : METAQUERY
634 { $$ = new tree_identifier ($1->line (), $1->column ()); }
635 ;
636
604 string : DQ_STRING 637 string : DQ_STRING
605 { $$ = make_constant (DQ_STRING, $1); } 638 { $$ = make_constant (DQ_STRING, $1); }
606 | SQ_STRING 639 | SQ_STRING
607 { $$ = make_constant (SQ_STRING, $1); } 640 { $$ = make_constant (SQ_STRING, $1); }
608 ; 641 ;
694 ; 727 ;
695 728
696 anon_fcn_handle : '@' param_list statement 729 anon_fcn_handle : '@' param_list statement
697 { $$ = make_anon_fcn_handle ($2, $3); } 730 { $$ = make_anon_fcn_handle ($2, $3); }
698 ; 731 ;
699 732
700 primary_expr : identifier 733 primary_expr : identifier
701 { $$ = $1; } 734 { $$ = $1; }
702 | constant 735 | constant
703 { $$ = $1; } 736 { $$ = $1; }
704 | fcn_handle 737 | fcn_handle
705 { $$ = $1; } 738 { $$ = $1; }
706 | matrix 739 | matrix
707 { $$ = $1; } 740 { $$ = $1; }
708 | cell 741 | cell
742 { $$ = $1; }
743 | meta_identifier
744 { $$ = $1; }
745 | superclass_identifier
709 { $$ = $1; } 746 { $$ = $1; }
710 | '(' expression ')' 747 | '(' expression ')'
711 { $$ = $2->mark_in_parens (); } 748 { $$ = $2->mark_in_parens (); }
712 ; 749 ;
713 750
923 { $$ = $1; } 960 { $$ = $1; }
924 | function 961 | function
925 { $$ = $1; } 962 { $$ = $1; }
926 | script_file 963 | script_file
927 { $$ = $1; } 964 { $$ = $1; }
965 | classdef
966 { $$ = $1; }
928 ; 967 ;
929 968
930 // ===================== 969 // =====================
931 // Declaration statemnts 970 // Declaration statemnts
932 // ===================== 971 // =====================
1262 // ============= 1301 // =============
1263 // Function file 1302 // Function file
1264 // ============= 1303 // =============
1265 1304
1266 function_file : FUNCTION_FILE function_list opt_sep END_OF_INPUT 1305 function_file : FUNCTION_FILE function_list opt_sep END_OF_INPUT
1306 { $$ = 0; }
1267 ; 1307 ;
1268 1308
1269 function_list : function 1309 function_list : function
1270 | function_list sep function 1310 | function_list sep function
1271 ; 1311 ;
1273 // =================== 1313 // ===================
1274 // Function definition 1314 // Function definition
1275 // =================== 1315 // ===================
1276 1316
1277 function_beg : push_fcn_symtab FCN stash_comment 1317 function_beg : push_fcn_symtab FCN stash_comment
1278 { $$ = $3; } 1318 {
1319 $$ = $3;
1320
1321 if (reading_classdef_file || lexer_flags.parsing_classdef)
1322 lexer_flags.maybe_classdef_get_set_method = true;
1323 }
1279 ; 1324 ;
1280 1325
1281 function : function_beg function1 1326 function : function_beg function1
1282 { 1327 {
1283 $$ = finish_function (0, $2, $1); 1328 $$ = finish_function (0, $2, $1);
1294 { 1339 {
1295 std::string id_name = $1->name (); 1340 std::string id_name = $1->name ();
1296 1341
1297 lexer_flags.parsed_function_name = true; 1342 lexer_flags.parsed_function_name = true;
1298 lexer_flags.defining_func = false; 1343 lexer_flags.defining_func = false;
1299 1344 lexer_flags.maybe_classdef_get_set_method = false;
1345
1300 $$ = $1; 1346 $$ = $1;
1347 }
1348 | GET '.' identifier
1349 {
1350 lexer_flags.maybe_classdef_get_set_method = false;
1351 $$ = $3;
1352 }
1353 | SET '.' identifier
1354 {
1355 lexer_flags.maybe_classdef_get_set_method = false;
1356 $$ = $3;
1301 } 1357 }
1302 ; 1358 ;
1303 1359
1304 function1 : fcn_name function2 1360 function1 : fcn_name function2
1305 { 1361 {
1347 { 1403 {
1348 yyerror ("function body open at end of input"); 1404 yyerror ("function body open at end of input");
1349 YYABORT; 1405 YYABORT;
1350 } 1406 }
1351 1407
1408 if (reading_classdef_file)
1409 {
1410 yyerror ("classdef body open at end of input");
1411 YYABORT;
1412 }
1413
1352 $$ = make_end ("endfunction", input_line_number, 1414 $$ = make_end ("endfunction", input_line_number,
1353 current_input_column); 1415 current_input_column);
1354 } 1416 }
1355 ; 1417 ;
1356 1418
1419 // ========
1420 // Classdef
1421 // ========
1422
1423 classdef_beg : CLASSDEF stash_comment
1424 {
1425 $$ = 0;
1426 lexer_flags.parsing_classdef = true;
1427 }
1428 ;
1429
1430 classdef_end : END
1431 {
1432 lexer_flags.parsing_classdef = false;
1433
1434 if (end_token_ok ($1, token::classdef_end))
1435 $$ = make_end ("endclassdef", $1->line (), $1->column ());
1436 else
1437 ABORT_PARSE;
1438 }
1439 ;
1440
1441 classdef1 : classdef_beg opt_attr_list identifier opt_superclasses
1442 { $$ = 0; }
1443 ;
1444
1445 classdef : classdef1 '\n' class_body '\n' stash_comment classdef_end
1446 { $$ = 0; }
1447 ;
1448
1449 opt_attr_list : // empty
1450 { $$ = 0; }
1451 | '(' attr_list ')'
1452 { $$ = 0; }
1453 ;
1454
1455 attr_list : attr
1456 { $$ = 0; }
1457 | attr_list ',' attr
1458 { $$ = 0; }
1459 ;
1460
1461 attr : identifier
1462 { $$ = 0; }
1463 | identifier '=' decl_param_init expression
1464 { $$ = 0; }
1465 | EXPR_NOT identifier
1466 { $$ = 0; }
1467 ;
1468
1469 opt_superclasses
1470 : // empty
1471 { $$ = 0; }
1472 | superclasses
1473 { $$ = 0; }
1474 ;
1475
1476 superclasses : EXPR_LT identifier '.' identifier
1477 { $$ = 0; }
1478 | EXPR_LT identifier
1479 { $$ = 0; }
1480 | superclasses EXPR_AND identifier '.' identifier
1481 { $$ = 0; }
1482 | superclasses EXPR_AND identifier
1483 { $$ = 0; }
1484 ;
1485
1486 class_body : properties_block
1487 { $$ = 0; }
1488 | methods_block
1489 { $$ = 0; }
1490 | events_block
1491 { $$ = 0; }
1492 | class_body '\n' properties_block
1493 { $$ = 0; }
1494 | class_body '\n' methods_block
1495 { $$ = 0; }
1496 | class_body '\n' events_block
1497 { $$ = 0; }
1498 ;
1499
1500 properties_beg : PROPERTIES stash_comment
1501 { $$ = 0; }
1502 ;
1503
1504 properties_block
1505 : properties_beg opt_attr_list '\n' properties_list '\n' END
1506 { $$ = 0; }
1507 ;
1508
1509 properties_list
1510 : class_property
1511 { $$ = 0; }
1512 | properties_list '\n' class_property
1513 { $$ = 0; }
1514 ;
1515
1516 class_property : identifier
1517 { $$ = 0; }
1518 | identifier '=' decl_param_init expression ';'
1519 { $$ = 0; }
1520 ;
1521
1522 methods_beg : METHODS stash_comment
1523 { $$ = 0; }
1524 ;
1525
1526 methods_block : methods_beg opt_attr_list '\n' methods_list '\n' END
1527 { $$ = 0; }
1528 ;
1529
1530 methods_list : function
1531 { $$ = 0; }
1532 | methods_list '\n' function
1533 { $$ = 0; }
1534 ;
1535
1536 events_beg : EVENTS stash_comment
1537 { $$ = 0; }
1538 ;
1539
1540 events_block : events_beg opt_attr_list '\n' events_list '\n' END
1541 { $$ = 0; }
1542 ;
1543
1544 events_list : class_event
1545 { $$ = 0; }
1546 | events_list '\n' class_event
1547 { $$ = 0; }
1548 ;
1549
1550 class_event : identifier
1551 { $$ = 0; }
1552 ;
1553
1357 // ============= 1554 // =============
1358 // Miscellaneous 1555 // Miscellaneous
1359 // ============= 1556 // =============
1360 1557
1361 stash_comment : // empty 1558 stash_comment : // empty
1412 { 1609 {
1413 int err_col = current_input_column - 1; 1610 int err_col = current_input_column - 1;
1414 1611
1415 std::ostringstream output_buf; 1612 std::ostringstream output_buf;
1416 1613
1417 if (reading_fcn_file || reading_script_file) 1614 if (reading_fcn_file || reading_script_file || reading_classdef_file)
1418 output_buf << "parse error near line " << input_line_number 1615 output_buf << "parse error near line " << input_line_number
1419 << " of file " << curr_fcn_file_full_name; 1616 << " of file " << curr_fcn_file_full_name;
1420 else 1617 else
1421 output_buf << "parse error:"; 1618 output_buf << "parse error:";
1422 1619
1472 1669
1473 case token::function_end: 1670 case token::function_end:
1474 error (fmt, type, "endfunction", l, c); 1671 error (fmt, type, "endfunction", l, c);
1475 break; 1672 break;
1476 1673
1674 case token::classdef_end:
1675 error (fmt, type, "endclassdef", l, c);
1676 break;
1677
1477 case token::if_end: 1678 case token::if_end:
1478 error (fmt, type, "endif", l, c); 1679 error (fmt, type, "endif", l, c);
1479 break; 1680 break;
1480 1681
1481 case token::switch_end: 1682 case token::switch_end:
1518 int l = tok->line (); 1719 int l = tok->line ();
1519 int c = tok->column (); 1720 int c = tok->column ();
1520 1721
1521 switch (expected) 1722 switch (expected)
1522 { 1723 {
1724 case token::classdef_end:
1725 end_error ("classdef", ettype, l, c);
1726 break;
1727
1523 case token::for_end: 1728 case token::for_end:
1524 end_error ("for", ettype, l, c); 1729 end_error ("for", ettype, l, c);
1525 break; 1730 break;
1526 1731
1527 case token::function_end: 1732 case token::function_end:
2656 2861
2657 id_name = nm; 2862 id_name = nm;
2658 } 2863 }
2659 } 2864 }
2660 2865
2661 if (reading_fcn_file || autoloading) 2866 if (reading_fcn_file || reading_classdef_file || autoloading)
2662 { 2867 {
2663 octave_time now; 2868 octave_time now;
2664 2869
2665 fcn->stash_fcn_file_name (curr_fcn_file_full_name); 2870 fcn->stash_fcn_file_name (curr_fcn_file_full_name);
2666 fcn->stash_fcn_file_time (now); 2871 fcn->stash_fcn_file_time (now);
3133 done: 3338 done:
3134 3339
3135 return (c == EOF); 3340 return (c == EOF);
3136 } 3341 }
3137 3342
3343 static bool
3344 looking_at_classdef_keyword (FILE *ffile)
3345 {
3346 bool status = false;
3347
3348 long pos = ftell (ffile);
3349
3350 char buf [10];
3351 fgets (buf, 10, ffile);
3352 size_t len = strlen (buf);
3353 if (len > 8 && strncmp (buf, "classdef", 8) == 0
3354 && ! (isalnum (buf[8]) || buf[8] == '_'))
3355 status = true;
3356
3357 fseek (ffile, pos, SEEK_SET);
3358
3359 return status;
3360 }
3361
3138 static std::string 3362 static std::string
3139 gobble_leading_white_space (FILE *ffile, bool& eof) 3363 gobble_leading_white_space (FILE *ffile, bool& eof)
3140 { 3364 {
3141 std::string help_txt; 3365 std::string help_txt;
3142 3366
3261 3485
3262 unwind_protect::protect_var (get_input_from_eval_string); 3486 unwind_protect::protect_var (get_input_from_eval_string);
3263 unwind_protect::protect_var (parser_end_of_input); 3487 unwind_protect::protect_var (parser_end_of_input);
3264 unwind_protect::protect_var (reading_fcn_file); 3488 unwind_protect::protect_var (reading_fcn_file);
3265 unwind_protect::protect_var (reading_script_file); 3489 unwind_protect::protect_var (reading_script_file);
3490 unwind_protect::protect_var (reading_classdef_file);
3491 unwind_protect::protect_var (Vecho_executing_commands);
3492
3266 3493
3267 get_input_from_eval_string = false; 3494 get_input_from_eval_string = false;
3268 parser_end_of_input = false; 3495 parser_end_of_input = false;
3269 3496
3270 if (! force_script && looking_at_function_keyword (ffile)) 3497 if (! force_script && looking_at_function_keyword (ffile))
3271 { 3498 {
3272 file_type = "function"; 3499 file_type = "function";
3273 3500
3274 unwind_protect::protect_var (Vecho_executing_commands);
3275
3276 Vecho_executing_commands = ECHO_OFF; 3501 Vecho_executing_commands = ECHO_OFF;
3502
3503 reading_classdef_file = false;
3277 reading_fcn_file = true; 3504 reading_fcn_file = true;
3505 reading_script_file = false;
3506 }
3507 else if (! force_script && looking_at_classdef_keyword (ffile))
3508 {
3509 file_type = "classdef";
3510
3511 Vecho_executing_commands = ECHO_OFF;
3512
3513 reading_classdef_file = true;
3514 reading_fcn_file = false;
3515 reading_script_file = false;
3278 } 3516 }
3279 else 3517 else
3280 { 3518 {
3281 file_type = "script"; 3519 file_type = "script";
3282 3520
3521 Vecho_executing_commands = ECHO_OFF;
3522
3523 reading_classdef_file = false;
3283 reading_fcn_file = false; 3524 reading_fcn_file = false;
3525 reading_script_file = true;
3284 } 3526 }
3285 3527
3286 reading_script_file = ! reading_fcn_file;
3287
3288 YY_BUFFER_STATE old_buf = current_buffer (); 3528 YY_BUFFER_STATE old_buf = current_buffer ();
3289 YY_BUFFER_STATE new_buf = create_buffer (ffile); 3529 YY_BUFFER_STATE new_buf = create_buffer (ffile);
3290 3530
3291 unwind_protect::add_fcn (switch_to_buffer, old_buf); 3531 unwind_protect::add_fcn (switch_to_buffer, old_buf);
3292 unwind_protect::add_fcn (delete_buffer, new_buf); 3532 unwind_protect::add_fcn (delete_buffer, new_buf);