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 }