Mercurial > hg > octave-nkf
comparison src/parse.y @ 143:7849db4b6dbc
[project @ 1993-10-04 02:36:45 by jwe]
author | jwe |
---|---|
date | Mon, 04 Oct 1993 02:36:58 +0000 |
parents | 27f35bee46f6 |
children | a500c60e8f23 |
comparison
equal
deleted
inserted
replaced
142:6906d6591452 | 143:7849db4b6dbc |
---|---|
1 /* parse.y -*- text -*- | 1 /* parse.y -*- text -*- |
2 | 2 |
3 Copyright (C) 1992, 1993 John W. Eaton | 3 Copyright (C) 1992, 1993 John W. Eaton |
4 | 4 |
5 This file is part of Octave. | 5 This file is part of Octave. |
6 | 6 |
41 #include "symtab.h" | 41 #include "symtab.h" |
42 #include "builtins.h" | 42 #include "builtins.h" |
43 #include "octave.h" | 43 #include "octave.h" |
44 #include "parse.h" | 44 #include "parse.h" |
45 #include "lex.h" | 45 #include "lex.h" |
46 #include "token.h" | |
46 | 47 |
47 // Identifier to define if we are reading an M-fie. | 48 // Identifier to define if we are reading an M-fie. |
48 tree_identifier *id_to_define; | 49 tree_identifier *id_to_define; |
49 | 50 |
50 // Nonzero means we're in the middle of defining a function. | 51 // Nonzero means we're in the middle of defining a function. |
77 | 78 |
78 // The current input line number. | 79 // The current input line number. |
79 int input_line_number = 0; | 80 int input_line_number = 0; |
80 | 81 |
81 // The column of the current token. | 82 // The column of the current token. |
82 int current_input_column = 0; | 83 int current_input_column = 1; |
83 | 84 |
84 // Buffer for help text snagged from M-files. | 85 // Buffer for help text snagged from M-files. |
85 // Probably shouldn't be a fixed size... | 86 // Probably shouldn't be a fixed size... |
86 char help_buf [HELP_BUF_LENGTH]; | 87 char help_buf [HELP_BUF_LENGTH]; |
87 | 88 |
99 int in_plot_using = 0; | 100 int in_plot_using = 0; |
100 | 101 |
101 // Nonzero means we're looking at the style part of a plot command. | 102 // Nonzero means we're looking at the style part of a plot command. |
102 int in_plot_style = 0; | 103 int in_plot_style = 0; |
103 | 104 |
104 // The type of an END token. This declaration is repeated in lex.l. | 105 // Check to see that end statements are properly matched. |
105 enum end_tok_type | 106 static int check_end (token *tok, token::end_tok_type expected); |
106 { | |
107 simple_end, | |
108 for_end, | |
109 function_end, | |
110 if_end, | |
111 while_end, | |
112 }; | |
113 | |
114 // The type of a PLOT token. This declaration is repeated in lex.l. | |
115 enum plot_tok_type | |
116 { | |
117 two_dee = 2, | |
118 three_dee = 3, | |
119 }; | |
120 | 107 |
121 // Error mesages for mismatched end statements. | 108 // Error mesages for mismatched end statements. |
122 static void end_error (char *type, end_tok_type ettype); | 109 static void end_error (char *type, token::end_tok_type ettype, int l, int c); |
123 | 110 |
124 // Generic error messages. | 111 // Generic error messages. |
125 static void yyerror (char *s); | 112 static void yyerror (char *s); |
126 | 113 |
127 static tree *maybe_convert_to_ans_assign (tree *expr); | 114 static tree *maybe_convert_to_ans_assign (tree *expr); |
145 /* | 132 /* |
146 * Bison declarations. | 133 * Bison declarations. |
147 */ | 134 */ |
148 %union | 135 %union |
149 { | 136 { |
137 // The type of the basic tokens returned by the lexer. | |
138 token *tok_val; | |
139 | |
140 // Types for the nonterminals we generate. | |
150 tree *tree_type; | 141 tree *tree_type; |
151 tree_constant *tree_constant_type; | 142 tree_constant *tree_constant_type; |
152 tree_matrix *tree_matrix_type; | 143 tree_matrix *tree_matrix_type; |
153 tree_identifier *tree_identifier_type; | 144 tree_identifier *tree_identifier_type; |
154 tree_function *tree_function_type; | 145 tree_function *tree_function_type; |
165 tree_subplot_list *tree_subplot_list_type; | 156 tree_subplot_list *tree_subplot_list_type; |
166 tree_plot_limits *tree_plot_limits_type; | 157 tree_plot_limits *tree_plot_limits_type; |
167 tree_plot_range *tree_plot_range_type; | 158 tree_plot_range *tree_plot_range_type; |
168 tree_subplot_using *tree_subplot_using_type; | 159 tree_subplot_using *tree_subplot_using_type; |
169 tree_subplot_style *tree_subplot_style_type; | 160 tree_subplot_style *tree_subplot_style_type; |
170 symbol_record *sym_rec; | |
171 double number; | |
172 char *string; | |
173 end_tok_type ettype; | |
174 plot_tok_type pttype; | |
175 } | 161 } |
176 | 162 |
177 /* | 163 // Tokens with line and column information. |
178 * There are 20 shift/reduce conflicts, ok? | 164 %token <tok_val> '=' ':' '-' '+' '*' '/' |
179 */ | 165 %token <tok_val> EXPR_AND EXPR_OR EXPR_NOT |
180 %expect 20 | 166 %token <tok_val> EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT |
181 | 167 %token <tok_val> LEFTDIV EMUL EDIV ELEFTDIV QUOTE TRANSPOSE |
182 /* | 168 %token <tok_val> PLUS_PLUS MINUS_MINUS POW EPOW |
183 * Reserved words. | 169 %token <tok_val> NUM IMAG_NUM |
184 */ | 170 %token <tok_val> NAME SCREW CLEAR |
171 %token <tok_val> END | |
172 %token <tok_val> PLOT | |
173 %token <tok_val> TEXT STYLE | |
174 | |
175 // Other tokens. | |
185 %token FOR WHILE IF ELSEIF ELSE FCN BREAK CONTINUE FUNC_RET SCREW_TWO | 176 %token FOR WHILE IF ELSEIF ELSE FCN BREAK CONTINUE FUNC_RET SCREW_TWO |
186 %token END_OF_INPUT GLOBAL CLEAR | 177 %token END_OF_INPUT GLOBAL |
187 | |
188 %token USING TITLE WITH COLON OPEN_BRACE CLOSE_BRACE | 178 %token USING TITLE WITH COLON OPEN_BRACE CLOSE_BRACE |
189 | 179 |
190 // tree | 180 // Nonterminals we construct. |
191 %type <tree_type> input command | 181 %type <tree_type> input command |
192 %type <tree_type> ans_expression expression simple_expr simple_expr1 | 182 %type <tree_type> ans_expression expression simple_expr simple_expr1 |
193 %type <tree_type> title | 183 %type <tree_type> title |
194 | |
195 // tree_matrix | |
196 %type <tree_matrix_type> matrix | 184 %type <tree_matrix_type> matrix |
197 | |
198 // tree_identifier | |
199 %type <tree_identifier_type> identifier | 185 %type <tree_identifier_type> identifier |
200 | |
201 // tree_function | |
202 %type <tree_function_type> func_def func_def1 func_def2 func_def3 | 186 %type <tree_function_type> func_def func_def1 func_def2 func_def3 |
203 | |
204 // tree_index_expression | |
205 %type <tree_index_expression_type> variable | 187 %type <tree_index_expression_type> variable |
206 | |
207 // tree_colon_expression | |
208 %type <tree_colon_expression_type> colon_expr | 188 %type <tree_colon_expression_type> colon_expr |
209 | |
210 // tree_argument_list | |
211 %type <tree_argument_list_type> arg_list arg_list1 | 189 %type <tree_argument_list_type> arg_list arg_list1 |
212 | |
213 // tree_parameter_list | |
214 %type <tree_parameter_list_type> param_list param_list1 func_def1a | 190 %type <tree_parameter_list_type> param_list param_list1 func_def1a |
215 | |
216 // tree_word_list | |
217 %type <tree_word_list_type> word_list word_list1 | 191 %type <tree_word_list_type> word_list word_list1 |
218 | |
219 // tree_command | |
220 %type <tree_command_type> statement | 192 %type <tree_command_type> statement |
221 | |
222 // tree_if_command | |
223 %type <tree_if_command_type> elseif | 193 %type <tree_if_command_type> elseif |
224 | |
225 // tree_command_list | |
226 %type <tree_command_list_type> simple_list simple_list1 list list1 opt_list | 194 %type <tree_command_list_type> simple_list simple_list1 list list1 opt_list |
227 | |
228 // tree_word_list_command | |
229 %type <tree_word_list_command_type> word_list_cmd | 195 %type <tree_word_list_command_type> word_list_cmd |
230 | |
231 // tree_plot_command | |
232 %type <tree_plot_command_type> plot_command | 196 %type <tree_plot_command_type> plot_command |
233 | |
234 // tree_subplot_list | |
235 %type <tree_subplot_list_type> plot_command1 plot_command2 plot_options | 197 %type <tree_subplot_list_type> plot_command1 plot_command2 plot_options |
236 | |
237 // tree_plot_limits | |
238 %type <tree_plot_limits_type> ranges | 198 %type <tree_plot_limits_type> ranges |
239 | |
240 // tree_plot_range | |
241 %type <tree_plot_range_type> ranges1 | 199 %type <tree_plot_range_type> ranges1 |
242 | |
243 // tree_subplot_using | |
244 %type <tree_subplot_using_type> using using1 | 200 %type <tree_subplot_using_type> using using1 |
245 | |
246 // tree_subplot_style | |
247 %type <tree_subplot_style_type> style | 201 %type <tree_subplot_style_type> style |
248 | 202 |
249 %token <number> NUM IMAG_NUM | 203 // Precedence and associativity. |
250 %token <sym_rec> NAME SCREW | |
251 %token <string> TEXT STYLE | |
252 %token <ettype> END | |
253 %token <pttype> PLOT | |
254 | |
255 %left ';' ',' '\n' | 204 %left ';' ',' '\n' |
256 %right '=' | 205 %right '=' |
257 %left EXPR_AND EXPR_OR | 206 %left EXPR_AND EXPR_OR |
258 %left EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT | 207 %left EXPR_LT EXPR_LE EXPR_EQ EXPR_NE EXPR_GE EXPR_GT |
259 %left ':' | 208 %left ':' |
261 %left '*' '/' LEFTDIV EMUL EDIV ELEFTDIV | 210 %left '*' '/' LEFTDIV EMUL EDIV ELEFTDIV |
262 %left QUOTE TRANSPOSE | 211 %left QUOTE TRANSPOSE |
263 %left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT | 212 %left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT |
264 %right POW EPOW | 213 %right POW EPOW |
265 | 214 |
215 // There are 20 shift/reduce conflicts, ok? | |
216 %expect 20 | |
217 | |
218 // Where to start. | |
266 %start input | 219 %start input |
267 | 220 |
268 /* | 221 /* |
269 * Grammar rules. | 222 * Grammar rules. |
270 */ | 223 */ |
395 ; | 348 ; |
396 | 349 |
397 plot_command : PLOT plot_command1 | 350 plot_command : PLOT plot_command1 |
398 { | 351 { |
399 tree_subplot_list *tmp = $2->reverse (); | 352 tree_subplot_list *tmp = $2->reverse (); |
400 $$ = new tree_plot_command (tmp, $1); | 353 $$ = new tree_plot_command (tmp, $1->pttype ()); |
401 plotting = 0; | 354 plotting = 0; |
402 past_plot_range = 0; | 355 past_plot_range = 0; |
403 in_plot_range = 0; | 356 in_plot_range = 0; |
404 in_plot_using = 0; | 357 in_plot_using = 0; |
405 in_plot_style = 0; | 358 in_plot_style = 0; |
406 } | 359 } |
407 | PLOT ranges plot_command1 | 360 | PLOT ranges plot_command1 |
408 { | 361 { |
409 tree_subplot_list *tmp = $3->reverse (); | 362 tree_subplot_list *tmp = $3->reverse (); |
410 $$ = new tree_plot_command (tmp, $2, $1); | 363 $$ = new tree_plot_command (tmp, $2, $1->pttype ()); |
411 plotting = 0; | 364 plotting = 0; |
412 past_plot_range = 0; | 365 past_plot_range = 0; |
413 in_plot_range = 0; | 366 in_plot_range = 0; |
414 in_plot_using = 0; | 367 in_plot_using = 0; |
415 in_plot_style = 0; | 368 in_plot_style = 0; |
504 title : TITLE expression | 457 title : TITLE expression |
505 { $$ = $2; } | 458 { $$ = $2; } |
506 ; | 459 ; |
507 | 460 |
508 style : WITH STYLE | 461 style : WITH STYLE |
509 { $$ = new tree_subplot_style ($2); } | 462 { $$ = new tree_subplot_style ($2->string ()); } |
510 | WITH STYLE expression | 463 | WITH STYLE expression |
511 { $$ = new tree_subplot_style ($2, $3); } | 464 { $$ = new tree_subplot_style ($2->string (), $3); } |
512 | WITH STYLE expression bogus_syntax expression | 465 | WITH STYLE expression bogus_syntax expression |
513 { $$ = new tree_subplot_style ($2, $3, $5); } | 466 { $$ = new tree_subplot_style ($2->string (), $3, $5); } |
514 ; | 467 ; |
515 | 468 |
516 bogus_syntax : // empty | 469 bogus_syntax : // empty |
517 ; | 470 ; |
518 | 471 |
523 global_decl : GLOBAL global_decl1 | 476 global_decl : GLOBAL global_decl1 |
524 { } | 477 { } |
525 ; | 478 ; |
526 | 479 |
527 global_decl1 : NAME | 480 global_decl1 : NAME |
528 { force_global ($1->name ()); } | 481 { force_global ($1->sym_rec()->name ()); } |
529 | NAME '=' expression | 482 | NAME '=' expression |
530 { | 483 { |
531 symbol_record *sr = force_global ($1->name ()); | 484 symbol_record *sr = force_global ($1->sym_rec()->name ()); |
532 tree_identifier *id = new tree_identifier (sr); | 485 tree_identifier *id = new tree_identifier |
486 (sr, $1->line (), $1->column ()); | |
533 tree_simple_assignment_expression *expr = | 487 tree_simple_assignment_expression *expr = |
534 new tree_simple_assignment_expression (id, $3); | 488 new tree_simple_assignment_expression |
489 (id, $3, $2->line () , $2->column ()); | |
535 expr->eval (0); | 490 expr->eval (0); |
536 } | 491 } |
537 | global_decl1 optcomma NAME | 492 | global_decl1 optcomma NAME |
538 { force_global ($3->name ()); } | 493 { force_global ($3->sym_rec()->name ()); } |
539 | global_decl1 optcomma NAME '=' expression | 494 | global_decl1 optcomma NAME '=' expression |
540 { | 495 { |
541 symbol_record *sr = force_global ($3->name ()); | 496 symbol_record *sr = force_global ($3->sym_rec()->name ()); |
542 tree_identifier *id = new tree_identifier (sr); | 497 tree_identifier *id = new tree_identifier |
498 (sr, $3->line (), $3->column ()); | |
543 tree_simple_assignment_expression *expr = | 499 tree_simple_assignment_expression *expr = |
544 new tree_simple_assignment_expression (id, $5); | 500 new tree_simple_assignment_expression |
501 (id, $5, $4->line (), $4->column ()); | |
545 expr->eval (0); | 502 expr->eval (0); |
546 } | 503 } |
547 ; | 504 ; |
548 | 505 |
549 optcomma : // empty | 506 optcomma : // empty |
556 ; | 513 ; |
557 | 514 |
558 statement : WHILE expression optsep opt_list END | 515 statement : WHILE expression optsep opt_list END |
559 { | 516 { |
560 maybe_warn_assign_as_truth_value ($2); | 517 maybe_warn_assign_as_truth_value ($2); |
561 if ($5 != while_end && $5 != simple_end) | 518 if (check_end ($5, token::while_end)) |
562 { | 519 ABORT_PARSE; |
563 yyerror ("parse error"); | |
564 end_error ("while", $5); | |
565 ABORT_PARSE; | |
566 } | |
567 looping--; | 520 looping--; |
568 $$ = new tree_while_command ($2, $4); | 521 $$ = new tree_while_command ($2, $4); |
569 } | 522 } |
570 | FOR variable '=' expression optsep opt_list END | 523 | FOR variable '=' expression optsep opt_list END |
571 { | 524 { |
572 if ($7 != for_end && $7 != simple_end) | 525 if (check_end ($7, token::for_end)) |
573 { | 526 ABORT_PARSE; |
574 yyerror ("parse error"); | |
575 end_error ("for", $7); | |
576 ABORT_PARSE; | |
577 } | |
578 looping--; | 527 looping--; |
579 $$ = new tree_for_command ($2, $4, $6); | 528 $$ = new tree_for_command ($2, $4, $6); |
580 } | 529 } |
581 | IF expression optsep opt_list END | 530 | IF expression optsep opt_list END |
582 { | 531 { |
583 maybe_warn_assign_as_truth_value ($2); | 532 maybe_warn_assign_as_truth_value ($2); |
584 if ($5 != if_end && $5 != simple_end) | 533 if (check_end ($5, token::if_end)) |
585 { | 534 ABORT_PARSE; |
586 yyerror ("parse error"); | |
587 end_error ("if", $5); | |
588 ABORT_PARSE; | |
589 } | |
590 iffing--; | 535 iffing--; |
591 $$ = new tree_if_command ($2, $4); | 536 $$ = new tree_if_command ($2, $4); |
592 } | 537 } |
593 | IF expression optsep opt_list ELSE optsep opt_list END | 538 | IF expression optsep opt_list ELSE optsep opt_list END |
594 { | 539 { |
595 maybe_warn_assign_as_truth_value ($2); | 540 maybe_warn_assign_as_truth_value ($2); |
596 if ($8 != if_end && $8 != simple_end) | 541 if (check_end ($8, token::if_end)) |
597 { | 542 ABORT_PARSE; |
598 yyerror ("parse error"); | |
599 end_error ("if", $8); | |
600 ABORT_PARSE; | |
601 } | |
602 iffing--; | 543 iffing--; |
603 tree_if_command *t1 = new tree_if_command ($7); | 544 tree_if_command *t1 = new tree_if_command ($7); |
604 $$ = t1->chain ($2, $4); | 545 $$ = t1->chain ($2, $4); |
605 } | 546 } |
606 | IF expression optsep opt_list elseif END | 547 | IF expression optsep opt_list elseif END |
607 { | 548 { |
608 maybe_warn_assign_as_truth_value ($2); | 549 maybe_warn_assign_as_truth_value ($2); |
609 if ($6 != if_end && $6 != simple_end) | 550 if (check_end ($6, token::if_end)) |
610 { | 551 ABORT_PARSE; |
611 yyerror ("parse error"); | |
612 end_error ("if", $6); | |
613 ABORT_PARSE; | |
614 } | |
615 iffing--; | 552 iffing--; |
616 tree_if_command *t1 = $5->reverse (); | 553 tree_if_command *t1 = $5->reverse (); |
617 // Add the if list to the new head of the elseif | 554 // Add the if list to the new head of the elseif |
618 // list, and return the list. | 555 // list, and return the list. |
619 $$ = t1->chain ($2, $4); | 556 $$ = t1->chain ($2, $4); |
620 } | 557 } |
621 | IF expression optsep opt_list elseif ELSE optsep opt_list END | 558 | IF expression optsep opt_list elseif ELSE optsep opt_list END |
622 { | 559 { |
623 maybe_warn_assign_as_truth_value ($2); | 560 maybe_warn_assign_as_truth_value ($2); |
624 if ($9 != if_end && $9 != simple_end) | 561 if (check_end ($9, token::if_end)) |
625 { | 562 ABORT_PARSE; |
626 yyerror ("parse error"); | |
627 end_error ("if", $9); | |
628 ABORT_PARSE; | |
629 } | |
630 iffing--; | 563 iffing--; |
631 // Add the else list to the head of the elseif list, | 564 // Add the else list to the head of the elseif list, |
632 // then reverse the list. | 565 // then reverse the list. |
633 tree_if_command *t1 = $5->chain ($8); | 566 tree_if_command *t1 = $5->chain ($8); |
634 t1 = t1->reverse (); | 567 t1 = t1->reverse (); |
697 screwed_again : // empty | 630 screwed_again : // empty |
698 { maybe_screwed_again++; } | 631 { maybe_screwed_again++; } |
699 ; | 632 ; |
700 | 633 |
701 expression : variable '=' expression | 634 expression : variable '=' expression |
702 { $$ = new tree_simple_assignment_expression ($1, $3); } | 635 { $$ = new tree_simple_assignment_expression |
636 ($1, $3, $2->line (), $2->column ()); } | |
703 | '[' screwed_again matrix_row SCREW_TWO '=' expression | 637 | '[' screwed_again matrix_row SCREW_TWO '=' expression |
704 { | 638 { |
705 | 639 |
706 // Will need a way to convert the matrix list to a list of | 640 // Will need a way to convert the matrix list to a list of |
707 // identifiers. If that fails, we can abort here, without losing | 641 // identifiers. If that fails, we can abort here, without losing |
708 // anything -- no other possible syntax is valid if we've seen the | 642 // anything -- no other possible syntax is valid if we've seen the |
709 // equals sign as the next token after the `]'. | 643 // equals sign as the next token after the `]'. |
710 | 644 |
711 $$ = (tree_multi_assignment_expression *) NULL; | 645 $$ = (tree_multi_assignment_expression *) NULL; |
712 maybe_screwed_again--; | 646 maybe_screwed_again--; |
714 tmp = tmp->reverse (); | 648 tmp = tmp->reverse (); |
715 tree_return_list *id_list = tmp->to_return_list (); | 649 tree_return_list *id_list = tmp->to_return_list (); |
716 if (id_list == NULL_TREE) | 650 if (id_list == NULL_TREE) |
717 { | 651 { |
718 yyerror ("parse error"); | 652 yyerror ("parse error"); |
719 error ("invalid identifier list for assignment"); | 653 error ("invalid identifier list for assignment"); |
720 $$ = (tree_multi_assignment_expression *) NULL; | 654 $$ = (tree_multi_assignment_expression *) NULL; |
721 ABORT_PARSE; | 655 ABORT_PARSE; |
722 } | 656 } |
723 else | 657 else |
724 $$ = new tree_multi_assignment_expression (id_list, $6); | 658 $$ = new tree_multi_assignment_expression |
659 (id_list, $6, $5->line (), $5->column ()); | |
725 } | 660 } |
726 | NUM '=' expression | 661 | NUM '=' expression |
727 { | 662 { |
728 yyerror ("parse error"); | 663 yyerror ("parse error"); |
729 error ("invalid assignment to a number"); | 664 error ("invalid assignment to a number"); |
735 ; | 670 ; |
736 | 671 |
737 simple_expr : simple_expr1 | 672 simple_expr : simple_expr1 |
738 { $$ = $1; } | 673 { $$ = $1; } |
739 | identifier PLUS_PLUS | 674 | identifier PLUS_PLUS |
740 { $$ = new tree_postfix_expression ($1, tree::increment); } | 675 { $$ = new tree_postfix_expression |
676 ($1, tree::increment, $2->line (), $2->column ()); } | |
741 | identifier MINUS_MINUS | 677 | identifier MINUS_MINUS |
742 { $$ = new tree_postfix_expression ($1, tree::decrement); } | 678 { $$ = new tree_postfix_expression |
679 ($1, tree::decrement, $2->line (), $2->column ()); } | |
743 | simple_expr QUOTE | 680 | simple_expr QUOTE |
744 { $$ = new tree_unary_expression ($1, tree::hermitian); } | 681 { $$ = new tree_unary_expression |
682 ($1, tree::hermitian, $2->line (), $2->column ()); } | |
745 | simple_expr TRANSPOSE | 683 | simple_expr TRANSPOSE |
746 { $$ = new tree_unary_expression ($1, tree::transpose); } | 684 { $$ = new tree_unary_expression |
685 ($1, tree::transpose, $2->line (), $2->column ()); } | |
747 | simple_expr POW simple_expr | 686 | simple_expr POW simple_expr |
748 { $$ = new tree_binary_expression ($1, $3, tree::power); } | 687 { $$ = new tree_binary_expression |
688 ($1, $3, tree::power, $2->line (), $2->column ()); } | |
749 | simple_expr EPOW simple_expr | 689 | simple_expr EPOW simple_expr |
750 { $$ = new tree_binary_expression ($1, $3, tree::elem_pow); } | 690 { $$ = new tree_binary_expression |
691 ($1, $3, tree::elem_pow, $2->line (), $2->column ()); } | |
751 | simple_expr '+' simple_expr | 692 | simple_expr '+' simple_expr |
752 { $$ = new tree_binary_expression ($1, $3, tree::add); } | 693 { $$ = new tree_binary_expression |
694 ($1, $3, tree::add, $2->line (), $2->column ()); } | |
753 | simple_expr '-' simple_expr | 695 | simple_expr '-' simple_expr |
754 { $$ = new tree_binary_expression ($1, $3, tree::subtract); } | 696 { $$ = new tree_binary_expression |
697 ($1, $3, tree::subtract, $2->line (), $2->column ()); } | |
755 | simple_expr '*' simple_expr | 698 | simple_expr '*' simple_expr |
756 { $$ = new tree_binary_expression ($1, $3, tree::multiply); } | 699 { $$ = new tree_binary_expression |
700 ($1, $3, tree::multiply, $2->line (), $2->column ()); } | |
757 | simple_expr '/' simple_expr | 701 | simple_expr '/' simple_expr |
758 { $$ = new tree_binary_expression ($1, $3, tree::divide); } | 702 { $$ = new tree_binary_expression |
703 ($1, $3, tree::divide, $2->line (), $2->column ()); } | |
759 | simple_expr EMUL simple_expr | 704 | simple_expr EMUL simple_expr |
760 { $$ = new tree_binary_expression ($1, $3, tree::el_mul); } | 705 { $$ = new tree_binary_expression |
706 ($1, $3, tree::el_mul, $2->line (), $2->column ()); } | |
761 | simple_expr EDIV simple_expr | 707 | simple_expr EDIV simple_expr |
762 { $$ = new tree_binary_expression ($1, $3, tree::el_div); } | 708 { $$ = new tree_binary_expression |
709 ($1, $3, tree::el_div, $2->line (), $2->column ()); } | |
763 | simple_expr LEFTDIV simple_expr | 710 | simple_expr LEFTDIV simple_expr |
764 { $$ = new tree_binary_expression ($1, $3, tree::leftdiv); } | 711 { $$ = new tree_binary_expression |
712 ($1, $3, tree::leftdiv, $2->line (), $2->column ()); } | |
765 | simple_expr ELEFTDIV simple_expr | 713 | simple_expr ELEFTDIV simple_expr |
766 { $$ = new tree_binary_expression ($1, $3, | 714 { $$ = new tree_binary_expression |
767 tree::el_leftdiv); } | 715 ($1, $3, tree::el_leftdiv, $2->line (), $2->column ()); } |
768 | simple_expr EXPR_LT simple_expr | 716 | simple_expr EXPR_LT simple_expr |
769 { $$ = new tree_binary_expression ($1, $3, tree::cmp_lt); } | 717 { $$ = new tree_binary_expression |
718 ($1, $3, tree::cmp_lt, $2->line (), $2->column ()); } | |
770 | simple_expr EXPR_LE simple_expr | 719 | simple_expr EXPR_LE simple_expr |
771 { $$ = new tree_binary_expression ($1, $3, tree::cmp_le); } | 720 { $$ = new tree_binary_expression |
721 ($1, $3, tree::cmp_le, $2->line (), $2->column ()); } | |
772 | simple_expr EXPR_EQ simple_expr | 722 | simple_expr EXPR_EQ simple_expr |
773 { $$ = new tree_binary_expression ($1, $3, tree::cmp_eq); } | 723 { $$ = new tree_binary_expression |
724 ($1, $3, tree::cmp_eq, $2->line (), $2->column ()); } | |
774 | simple_expr EXPR_GE simple_expr | 725 | simple_expr EXPR_GE simple_expr |
775 { $$ = new tree_binary_expression ($1, $3, tree::cmp_ge); } | 726 { $$ = new tree_binary_expression |
727 ($1, $3, tree::cmp_ge, $2->line (), $2->column ()); } | |
776 | simple_expr EXPR_GT simple_expr | 728 | simple_expr EXPR_GT simple_expr |
777 { $$ = new tree_binary_expression ($1, $3, tree::cmp_gt); } | 729 { $$ = new tree_binary_expression |
730 ($1, $3, tree::cmp_gt, $2->line (), $2->column ()); } | |
778 | simple_expr EXPR_NE simple_expr | 731 | simple_expr EXPR_NE simple_expr |
779 { $$ = new tree_binary_expression ($1, $3, tree::cmp_ne); } | 732 { $$ = new tree_binary_expression |
733 ($1, $3, tree::cmp_ne, $2->line (), $2->column ()); } | |
780 | simple_expr EXPR_AND simple_expr | 734 | simple_expr EXPR_AND simple_expr |
781 { $$ = new tree_binary_expression ($1, $3, tree::and); } | 735 { $$ = new tree_binary_expression |
736 ($1, $3, tree::and, $2->line (), $2->column ()); } | |
782 | simple_expr EXPR_OR simple_expr | 737 | simple_expr EXPR_OR simple_expr |
783 { $$ = new tree_binary_expression ($1, $3, tree::or); } | 738 { $$ = new tree_binary_expression |
739 ($1, $3, tree::or, $2->line (), $2->column ()); } | |
784 ; | 740 ; |
785 | 741 |
786 simple_expr1 : NUM | 742 simple_expr1 : NUM |
787 { $$ = new tree_constant ($1); } | 743 { $$ = new tree_constant ($1->number ()); } |
788 | IMAG_NUM | 744 | IMAG_NUM |
789 { $$ = new tree_constant (Complex (0.0, $1)); } | 745 { $$ = new tree_constant (Complex (0.0, $1->number ())); } |
790 | TEXT | 746 | TEXT |
791 { $$ = new tree_constant ($1); } | 747 { $$ = new tree_constant ($1->string ()); } |
792 | word_list_cmd | 748 | word_list_cmd |
793 { $$ = $1; } | 749 { $$ = $1; } |
794 | '(' expression ')' | 750 | '(' expression ')' |
795 { | 751 { |
796 if ($2->is_assignment_expression ()) | 752 if ($2->is_assignment_expression ()) |
802 | matrix | 758 | matrix |
803 { $$ = $1; } | 759 { $$ = $1; } |
804 | colon_expr | 760 | colon_expr |
805 { $$ = $1; } | 761 { $$ = $1; } |
806 | PLUS_PLUS identifier %prec UNARY | 762 | PLUS_PLUS identifier %prec UNARY |
807 { $$ = new tree_prefix_expression ($2, tree::increment); } | 763 { $$ = new tree_prefix_expression |
764 ($2, tree::increment, $1->line (), $1->column ()); } | |
808 | MINUS_MINUS identifier %prec UNARY | 765 | MINUS_MINUS identifier %prec UNARY |
809 { $$ = new tree_prefix_expression ($2, tree::decrement); } | 766 { $$ = new tree_prefix_expression |
767 ($2, tree::decrement, $1->line (), $1->column ()); } | |
810 | EXPR_NOT simple_expr | 768 | EXPR_NOT simple_expr |
811 { $$ = new tree_unary_expression ($2, tree::not); } | 769 { $$ = new tree_unary_expression |
770 ($2, tree::not, $1->line (), $1->column ()); } | |
812 | '+' simple_expr %prec UNARY | 771 | '+' simple_expr %prec UNARY |
813 { $$ = $2; } | 772 { $$ = $2; } |
814 | '-' simple_expr %prec UNARY | 773 | '-' simple_expr %prec UNARY |
815 { $$ = new tree_unary_expression ($2, tree::uminus); } | 774 { $$ = new tree_unary_expression |
775 ($2, tree::uminus, $1->line (), $1->column ()); } | |
816 ; | 776 ; |
817 | 777 |
818 colon_expr : simple_expr ':' simple_expr | 778 colon_expr : simple_expr ':' simple_expr |
819 { $$ = new tree_colon_expression ($1, $3); } | 779 { $$ = new tree_colon_expression |
780 ($1, $3, $2->line (), $2->column ()); } | |
820 | colon_expr ':' simple_expr | 781 | colon_expr ':' simple_expr |
821 { | 782 { |
822 $$ = $1->chain ($3); | 783 $$ = $1->chain ($3); |
823 if ($$ == (tree_colon_expression *) NULL) | 784 if ($$ == (tree_colon_expression *) NULL) |
824 { | 785 { |
836 { | 797 { |
837 yyerror ("parse error"); | 798 yyerror ("parse error"); |
838 error ("clear: invalid within function body"); | 799 error ("clear: invalid within function body"); |
839 ABORT_PARSE; | 800 ABORT_PARSE; |
840 } | 801 } |
841 symbol_record *sr = global_sym_tab->lookup ("clear", 1, 0); | 802 tree_identifier *tmp = new tree_identifier |
842 assert (sr != (symbol_record *) NULL); | 803 ($1->sym_rec (), $1->line (), $1->column ()); |
843 tree_identifier *tmp = new tree_identifier (sr); | |
844 $$ = new tree_word_list_command (tmp, | 804 $$ = new tree_word_list_command (tmp, |
845 (tree_word_list *) NULL); | 805 (tree_word_list *) NULL); |
846 } | 806 } |
847 | CLEAR word_list | 807 | CLEAR word_list |
848 { | 808 { |
850 { | 810 { |
851 yyerror ("parse error"); | 811 yyerror ("parse error"); |
852 error ("clear: invalid within function body"); | 812 error ("clear: invalid within function body"); |
853 ABORT_PARSE; | 813 ABORT_PARSE; |
854 } | 814 } |
855 symbol_record *sr = global_sym_tab->lookup ("clear", 1, 0); | 815 tree_identifier *tmp = new tree_identifier |
856 assert (sr != (symbol_record *) NULL); | 816 ($1->sym_rec (), $1->line (), $1->column ()); |
857 tree_identifier *tmp = new tree_identifier (sr); | |
858 $$ = new tree_word_list_command (tmp, $2); | 817 $$ = new tree_word_list_command (tmp, $2); |
859 } | 818 } |
860 ; | 819 ; |
861 | 820 |
862 word_list : word_list1 | 821 word_list : word_list1 |
863 { $$ = $1->reverse (); } | 822 { $$ = $1->reverse (); } |
864 ; | 823 ; |
865 | 824 |
866 word_list1 : TEXT | 825 word_list1 : TEXT |
867 { $$ = new tree_word_list ($1); } | 826 { $$ = new tree_word_list ($1->string ()); } |
868 | word_list1 TEXT | 827 | word_list1 TEXT |
869 { $$ = $1->chain ($2); } | 828 { $$ = $1->chain ($2->string ()); } |
870 ; | 829 ; |
871 | 830 |
872 // This is truly disgusting. | 831 // This is truly disgusting. |
873 | 832 |
874 g_symtab : // empty | 833 g_symtab : // empty |
901 } | 860 } |
902 ; | 861 ; |
903 | 862 |
904 func_def1 : SCREW safe g_symtab '=' func_def2 | 863 func_def1 : SCREW safe g_symtab '=' func_def2 |
905 { | 864 { |
906 tree_identifier *tmp = new tree_identifier ($1); | 865 tree_identifier *tmp = new tree_identifier |
866 ($1->sym_rec (), $1->line (), $1->column ()); | |
907 tree_parameter_list *tpl = new tree_parameter_list (tmp); | 867 tree_parameter_list *tpl = new tree_parameter_list (tmp); |
908 tpl = tpl->reverse (); | 868 tpl = tpl->reverse (); |
909 tpl->mark_as_formal_parameters (); | 869 tpl->mark_as_formal_parameters (); |
910 $$ = $5->define_ret_list (tpl); | 870 $$ = $5->define_ret_list (tpl); |
911 } | 871 } |
956 $1->define ($4); | 916 $1->define ($4); |
957 $1->document (help_buf); | 917 $1->document (help_buf); |
958 top_level_sym_tab->clear (id_name); | 918 top_level_sym_tab->clear (id_name); |
959 } | 919 } |
960 | 920 |
921 $4->stash_function_name (id_name); | |
961 $$ = $4; | 922 $$ = $4; |
962 } | 923 } |
963 ; | 924 ; |
964 | 925 |
965 func_def3 : param_list optsep opt_list fcn_end_or_eof | 926 func_def3 : param_list optsep opt_list fcn_end_or_eof |
973 { $$ = new tree_function ($2, curr_sym_tab); } | 934 { $$ = new tree_function ($2, curr_sym_tab); } |
974 ; | 935 ; |
975 | 936 |
976 fcn_end_or_eof : END | 937 fcn_end_or_eof : END |
977 { | 938 { |
978 if ($1 != function_end && $1 != simple_end) | 939 if (check_end ($1, token::function_end)) |
979 { | |
980 yyerror ("parse error"); | |
981 end_error ("function", $1); | |
982 ABORT_PARSE; | 940 ABORT_PARSE; |
983 } | |
984 | 941 |
985 if (reading_m_file) | 942 if (reading_m_file) |
986 check_for_garbage_after_fcn_def (); | 943 check_for_garbage_after_fcn_def (); |
987 } | 944 } |
988 | END_OF_INPUT | 945 | END_OF_INPUT |
1033 $$ = (tree_parameter_list *) NULL; | 990 $$ = (tree_parameter_list *) NULL; |
1034 } | 991 } |
1035 ; | 992 ; |
1036 | 993 |
1037 identifier : NAME | 994 identifier : NAME |
1038 { $$ = new tree_identifier ($1); } | 995 { $$ = new tree_identifier |
996 ($1->sym_rec (), $1->line (), $1->column ()); } | |
1039 | 997 |
1040 arg_list : arg_list1 | 998 arg_list : arg_list1 |
1041 { $$ = $1->reverse (); } | 999 { $$ = $1->reverse (); } |
1042 ; | 1000 ; |
1043 | 1001 |
1099 { | 1057 { |
1100 if (mlnm.top ()) | 1058 if (mlnm.top ()) |
1101 { | 1059 { |
1102 mlnm.pop (); | 1060 mlnm.pop (); |
1103 mlnm.push (0); | 1061 mlnm.push (0); |
1104 tree_matrix *tmp = new tree_matrix ($1, tree::md_none); | 1062 tree_matrix *tmp = new tree_matrix ($1, tree::md_none); |
1105 ml.push (tmp); | 1063 ml.push (tmp); |
1106 } | 1064 } |
1107 else | 1065 else |
1108 { | 1066 { |
1109 tree_matrix *tmp = ml.pop (); | 1067 tree_matrix *tmp = ml.pop (); |
1124 | 1082 |
1125 static void | 1083 static void |
1126 yyerror (char *s) | 1084 yyerror (char *s) |
1127 { | 1085 { |
1128 char *line = current_input_line; | 1086 char *line = current_input_line; |
1129 int err_col = current_input_column; | 1087 int err_col = current_input_column - 1; |
1130 if (err_col == 0) | 1088 if (err_col == 0) |
1131 err_col = strlen (current_input_line) + 1; | 1089 err_col = strlen (current_input_line) + 1; |
1132 | 1090 |
1133 // Print a message like `parse error'. | 1091 // Print a message like `parse error'. |
1134 fprintf (stderr, "\n%s", s); | 1092 fprintf (stderr, "\n%s", s); |
1150 fprintf (stderr, ":\n\n %s\n\n", line); | 1108 fprintf (stderr, ":\n\n %s\n\n", line); |
1151 else | 1109 else |
1152 fprintf (stderr, ":\n\n %s\n %*s\n\n", line, err_col, "^"); | 1110 fprintf (stderr, ":\n\n %s\n %*s\n\n", line, err_col, "^"); |
1153 } | 1111 } |
1154 | 1112 |
1113 static int | |
1114 check_end (token *tok, token::end_tok_type expected) | |
1115 { | |
1116 token::end_tok_type ettype = tok->ettype (); | |
1117 if (ettype != expected && ettype != token::simple_end) | |
1118 { | |
1119 yyerror ("parse error"); | |
1120 | |
1121 int l = tok->line (); | |
1122 int c = tok->column (); | |
1123 | |
1124 switch (expected) | |
1125 { | |
1126 case token::for_end: | |
1127 end_error ("for", ettype, l, c); | |
1128 break; | |
1129 case token::function_end: | |
1130 end_error ("function", ettype, l, c); | |
1131 break; | |
1132 case token::if_end: | |
1133 end_error ("if", ettype, l, c); | |
1134 break; | |
1135 case token::while_end: | |
1136 end_error ("while", ettype, l, c); | |
1137 break; | |
1138 default: | |
1139 panic_impossible (); | |
1140 break; | |
1141 } | |
1142 return 1; | |
1143 } | |
1144 else | |
1145 return 0; | |
1146 } | |
1147 | |
1155 static void | 1148 static void |
1156 end_error (char *type, end_tok_type ettype) | 1149 end_error (char *type, token::end_tok_type ettype, int l, int c) |
1157 { | 1150 { |
1151 static char *fmt = "%s command matched by `%s' near line %d column %d"; | |
1152 | |
1158 switch (ettype) | 1153 switch (ettype) |
1159 { | 1154 { |
1160 case simple_end: | 1155 case token::simple_end: |
1161 error ("%s command matched by `end'", type); | 1156 error (fmt, type, "end", l, c); |
1162 break; | 1157 break; |
1163 case for_end: | 1158 case token::for_end: |
1164 error ("%s command matched by `endfor'", type); | 1159 error (fmt, type, "endfor", l, c); |
1165 break; | 1160 break; |
1166 case function_end: | 1161 case token::function_end: |
1167 error ("%s command matched by `endfunction'", type); | 1162 error (fmt, type, "endfunction", l, c); |
1168 break; | 1163 break; |
1169 case if_end: | 1164 case token::if_end: |
1170 error ("%s command matched by `endif'", type); | 1165 error (fmt, type, "endif", l, c); |
1171 break; | 1166 break; |
1172 case while_end: | 1167 case token::while_end: |
1173 error ("%s command matched by `endwhile'", type); | 1168 error (fmt, type, "endwhile", l, c); |
1174 break; | 1169 break; |
1175 default: | 1170 default: |
1176 panic_impossible (); | 1171 panic_impossible (); |
1177 break; | 1172 break; |
1178 } | 1173 } |