comparison src/lex.l @ 5102:b04b30d30c66

[project @ 2004-12-28 01:59:05 by jwe]
author jwe
date Tue, 28 Dec 2004 01:59:05 +0000
parents 7830f271a53f
children 04d810c3eb51
comparison
equal deleted inserted replaced
5101:9b1af8135ecd 5102:b04b30d30c66
119 #define TOK_RETURN(tok) \ 119 #define TOK_RETURN(tok) \
120 do \ 120 do \
121 { \ 121 { \
122 current_input_column += yyleng; \ 122 current_input_column += yyleng; \
123 lexer_flags.quote_is_transpose = false; \ 123 lexer_flags.quote_is_transpose = false; \
124 lexer_flags.cant_be_identifier = false; \
125 lexer_flags.convert_spaces_to_comma = true; \ 124 lexer_flags.convert_spaces_to_comma = true; \
126 COUNT_TOK_AND_RETURN (tok); \ 125 COUNT_TOK_AND_RETURN (tok); \
127 } \ 126 } \
128 while (0) 127 while (0)
129 128
142 { \ 141 { \
143 yylval.tok_val = new token (input_line_number, current_input_column); \ 142 yylval.tok_val = new token (input_line_number, current_input_column); \
144 token_stack.push (yylval.tok_val); \ 143 token_stack.push (yylval.tok_val); \
145 current_input_column += yyleng; \ 144 current_input_column += yyleng; \
146 lexer_flags.quote_is_transpose = false; \ 145 lexer_flags.quote_is_transpose = false; \
147 lexer_flags.cant_be_identifier = true; \
148 lexer_flags.convert_spaces_to_comma = convert; \ 146 lexer_flags.convert_spaces_to_comma = convert; \
149 COUNT_TOK_AND_RETURN (tok); \ 147 COUNT_TOK_AND_RETURN (tok); \
150 } \ 148 } \
151 while (0) 149 while (0)
152 150
238 // Forward declarations for functions defined at the bottom of this 236 // Forward declarations for functions defined at the bottom of this
239 // file. 237 // file.
240 238
241 static void fixup_column_count (char *s); 239 static void fixup_column_count (char *s);
242 static void do_comma_insert_check (void); 240 static void do_comma_insert_check (void);
243 static int is_plot_keyword (const std::string& s);
244 static int is_keyword_token (const std::string& s); 241 static int is_keyword_token (const std::string& s);
245 static void prep_for_function (void); 242 static void prep_for_function (void);
246 static void prep_for_nested_function (void); 243 static void prep_for_nested_function (void);
247 static std::string plot_style_token (const std::string& s);
248 static symbol_record *lookup_identifier (const std::string& s); 244 static symbol_record *lookup_identifier (const std::string& s);
249 static std::string grab_help_text (void); 245 static std::string grab_help_text (void);
250 static bool match_any (char c, const char *s); 246 static bool match_any (char c, const char *s);
251 static bool next_token_is_sep_op (void); 247 static bool next_token_is_sep_op (void);
252 static bool next_token_is_bin_op (bool spc_prev); 248 static bool next_token_is_bin_op (bool spc_prev);
310 306
311 <COMMAND_START>{NL} { 307 <COMMAND_START>{NL} {
312 BEGIN (INITIAL); 308 BEGIN (INITIAL);
313 current_input_column = 1; 309 current_input_column = 1;
314 lexer_flags.quote_is_transpose = false; 310 lexer_flags.quote_is_transpose = false;
315 lexer_flags.cant_be_identifier = false;
316 lexer_flags.convert_spaces_to_comma = true; 311 lexer_flags.convert_spaces_to_comma = true;
317 COUNT_TOK_AND_RETURN ('\n'); 312 COUNT_TOK_AND_RETURN ('\n');
318 } 313 }
319 314
320 <COMMAND_START>[\;\,] { 315 <COMMAND_START>[\;\,] {
321 if (lexer_flags.doing_set && strcmp (yytext, ",") == 0) 316 if (lexer_flags.doing_rawcommand)
322 { 317 TOK_PUSH_AND_RETURN (yytext, STRING);
323 TOK_PUSH_AND_RETURN (yytext, STRING); 318
324 } 319 BEGIN (INITIAL);
320
321 if (strcmp (yytext, ",") == 0)
322 TOK_RETURN (',');
325 else 323 else
326 { 324 TOK_RETURN (';');
327 BEGIN (INITIAL);
328 if (strcmp (yytext, ",") == 0)
329 TOK_RETURN (',');
330 else
331 TOK_RETURN (';');
332 }
333 } 325 }
334 326
335 <COMMAND_START>[\"\'] { 327 <COMMAND_START>[\"\'] {
336 current_input_column++; 328 current_input_column++;
337 COUNT_TOK_AND_RETURN (handle_string (yytext[0], true)); 329 COUNT_TOK_AND_RETURN (handle_string (yytext[0], true));
382 current_input_column += yyleng; 374 current_input_column += yyleng;
383 375
384 int tmp = eat_continuation (); 376 int tmp = eat_continuation ();
385 377
386 lexer_flags.quote_is_transpose = false; 378 lexer_flags.quote_is_transpose = false;
387 lexer_flags.cant_be_identifier = false;
388 lexer_flags.convert_spaces_to_comma = true; 379 lexer_flags.convert_spaces_to_comma = true;
389 380
390 if ((tmp & ATE_NEWLINE) == ATE_NEWLINE) 381 if ((tmp & ATE_NEWLINE) == ATE_NEWLINE)
391 { 382 {
392 maybe_warn_separator_insert (';'); 383 maybe_warn_separator_insert (';');
421 412
422 yyunput (';', yytext); 413 yyunput (';', yytext);
423 } 414 }
424 415
425 lexer_flags.quote_is_transpose = false; 416 lexer_flags.quote_is_transpose = false;
426 lexer_flags.cant_be_identifier = false;
427 lexer_flags.convert_spaces_to_comma = true; 417 lexer_flags.convert_spaces_to_comma = true;
428 418
429 maybe_warn_separator_insert (','); 419 maybe_warn_separator_insert (',');
430 420
431 COUNT_TOK_AND_RETURN (','); 421 COUNT_TOK_AND_RETURN (',');
441 <MATRIX_START>{SNLCMT}*;{SNLCMT}* { 431 <MATRIX_START>{SNLCMT}*;{SNLCMT}* {
442 scan_for_comments (yytext); 432 scan_for_comments (yytext);
443 fixup_column_count (yytext); 433 fixup_column_count (yytext);
444 eat_whitespace (); 434 eat_whitespace ();
445 lexer_flags.quote_is_transpose = false; 435 lexer_flags.quote_is_transpose = false;
446 lexer_flags.cant_be_identifier = false;
447 lexer_flags.convert_spaces_to_comma = true; 436 lexer_flags.convert_spaces_to_comma = true;
448 COUNT_TOK_AND_RETURN (';'); 437 COUNT_TOK_AND_RETURN (';');
449 } 438 }
450 439
451 %{ 440 %{
459 scan_for_comments (yytext); 448 scan_for_comments (yytext);
460 fixup_column_count (yytext); 449 fixup_column_count (yytext);
461 eat_whitespace (); 450 eat_whitespace ();
462 451
463 lexer_flags.quote_is_transpose = false; 452 lexer_flags.quote_is_transpose = false;
464 lexer_flags.cant_be_identifier = false;
465 lexer_flags.convert_spaces_to_comma = true; 453 lexer_flags.convert_spaces_to_comma = true;
466 454
467 if (nesting_level.none ()) 455 if (nesting_level.none ())
468 return LEXICAL_ERROR; 456 return LEXICAL_ERROR;
469 457
473 461
474 COUNT_TOK_AND_RETURN (';'); 462 COUNT_TOK_AND_RETURN (';');
475 } 463 }
476 } 464 }
477 465
478 %{
479 // Open and close bracket are handled differently if we are in the range
480 // part of a plot command.
481 //
482 %}
483
484 \[{S}* { 466 \[{S}* {
485 nesting_level.bracket (); 467 nesting_level.bracket ();
486 468
487 current_input_column += yyleng; 469 current_input_column += yyleng;
488 lexer_flags.quote_is_transpose = false; 470 lexer_flags.quote_is_transpose = false;
489 lexer_flags.cant_be_identifier = false;
490 lexer_flags.convert_spaces_to_comma = true; 471 lexer_flags.convert_spaces_to_comma = true;
491 472
492 promptflag--; 473 promptflag--;
493 eat_whitespace (); 474 eat_whitespace ();
494 475
495 if (lexer_flags.plotting && ! lexer_flags.past_plot_range) 476 lexer_flags.bracketflag++;
496 { 477 BEGIN (MATRIX_START);
497 lexer_flags.in_plot_range = true; 478 COUNT_TOK_AND_RETURN ('[');
498 COUNT_TOK_AND_RETURN (OPEN_BRACE);
499 }
500 else
501 {
502 lexer_flags.bracketflag++;
503 BEGIN (MATRIX_START);
504 COUNT_TOK_AND_RETURN ('[');
505 }
506 } 479 }
507 480
508 \] { 481 \] {
509 nesting_level.remove (); 482 nesting_level.remove ();
510 483
511 if (lexer_flags.plotting && ! lexer_flags.past_plot_range) 484 TOK_RETURN (']');
512 {
513 lexer_flags.in_plot_range = false;
514 TOK_RETURN (CLOSE_BRACE);
515 }
516 else
517 TOK_RETURN (']');
518 } 485 }
519 486
520 %{ 487 %{
521 // Imaginary numbers. 488 // Imaginary numbers.
522 %} 489 %}
604 %} 571 %}
605 572
606 "@" { 573 "@" {
607 current_input_column++; 574 current_input_column++;
608 lexer_flags.quote_is_transpose = false; 575 lexer_flags.quote_is_transpose = false;
609 lexer_flags.cant_be_identifier = false;
610 lexer_flags.convert_spaces_to_comma = false; 576 lexer_flags.convert_spaces_to_comma = false;
611 lexer_flags.looking_at_function_handle++; 577 lexer_flags.looking_at_function_handle++;
612 COUNT_TOK_AND_RETURN ('@'); 578 COUNT_TOK_AND_RETURN ('@');
613 } 579 }
614 580
619 %} 585 %}
620 586
621 {NL} { 587 {NL} {
622 current_input_column = 1; 588 current_input_column = 1;
623 lexer_flags.quote_is_transpose = false; 589 lexer_flags.quote_is_transpose = false;
624 lexer_flags.cant_be_identifier = false;
625 lexer_flags.convert_spaces_to_comma = true; 590 lexer_flags.convert_spaces_to_comma = true;
626 591
627 if (nesting_level.none ()) 592 if (nesting_level.none ())
628 COUNT_TOK_AND_RETURN ('\n'); 593 COUNT_TOK_AND_RETURN ('\n');
629 else if (nesting_level.is_paren ()) 594 else if (nesting_level.is_paren ())
656 621
657 \" { 622 \" {
658 current_input_column++; 623 current_input_column++;
659 COUNT_TOK_AND_RETURN (handle_string ('"')); 624 COUNT_TOK_AND_RETURN (handle_string ('"'));
660 } 625 }
661
662 %{
663 // The colon operator is handled differently if we are in the range
664 // part of a plot command.
665 %}
666
667 ":" {
668 if (lexer_flags.plotting
669 && (lexer_flags.in_plot_range || lexer_flags.in_plot_using))
670 BIN_OP_RETURN (COLON, true);
671 else
672 BIN_OP_RETURN (':', false);
673 }
674 626
675 %{ 627 %{
676 // Gobble comments. If closest nesting is inside parentheses, don't 628 // Gobble comments. If closest nesting is inside parentheses, don't
677 // return a new line. 629 // return a new line.
678 %} 630 %}
716 octave_comment_buffer::append (buf); 668 octave_comment_buffer::append (buf);
717 } 669 }
718 670
719 current_input_column = 1; 671 current_input_column = 1;
720 lexer_flags.quote_is_transpose = false; 672 lexer_flags.quote_is_transpose = false;
721 lexer_flags.cant_be_identifier = false;
722 lexer_flags.convert_spaces_to_comma = true; 673 lexer_flags.convert_spaces_to_comma = true;
723 674
724 maybe_gripe_matlab_incompatible_comment (yytext[0]); 675 maybe_gripe_matlab_incompatible_comment (yytext[0]);
725 676
726 if (YY_START == COMMAND_START) 677 if (YY_START == COMMAND_START)
733 } 684 }
734 685
735 %{ 686 %{
736 // Other operators. 687 // Other operators.
737 %} 688 %}
689
690 ":" { BIN_OP_RETURN (':', false); }
738 691
739 ".+" { XBIN_OP_RETURN (EPLUS, false); } 692 ".+" { XBIN_OP_RETURN (EPLUS, false); }
740 ".-" { XBIN_OP_RETURN (EMINUS, false); } 693 ".-" { XBIN_OP_RETURN (EMINUS, false); }
741 ".*" { BIN_OP_RETURN (EMUL, false); } 694 ".*" { BIN_OP_RETURN (EMUL, false); }
742 "./" { BIN_OP_RETURN (EDIV, false); } 695 "./" { BIN_OP_RETURN (EDIV, false); }
753 ">=" { BIN_OP_RETURN (EXPR_GE, false); } 706 ">=" { BIN_OP_RETURN (EXPR_GE, false); }
754 "&" { BIN_OP_RETURN (EXPR_AND, false); } 707 "&" { BIN_OP_RETURN (EXPR_AND, false); }
755 "|" { BIN_OP_RETURN (EXPR_OR, false); } 708 "|" { BIN_OP_RETURN (EXPR_OR, false); }
756 "<" { BIN_OP_RETURN (EXPR_LT, false); } 709 "<" { BIN_OP_RETURN (EXPR_LT, false); }
757 ">" { BIN_OP_RETURN (EXPR_GT, false); } 710 ">" { BIN_OP_RETURN (EXPR_GT, false); }
711 "+" { BIN_OP_RETURN ('+', false); }
712 "-" { BIN_OP_RETURN ('-', false); }
758 "*" { BIN_OP_RETURN ('*', false); } 713 "*" { BIN_OP_RETURN ('*', false); }
759 "/" { BIN_OP_RETURN ('/', false); } 714 "/" { BIN_OP_RETURN ('/', false); }
760 "\\" { BIN_OP_RETURN (LEFTDIV, false); } 715 "\\" { BIN_OP_RETURN (LEFTDIV, false); }
761 ";" { BIN_OP_RETURN (';', true); } 716 ";" { BIN_OP_RETURN (';', true); }
762 "," { BIN_OP_RETURN (',', true); } 717 "," { BIN_OP_RETURN (',', true); }
767 "||" { BIN_OP_RETURN (EXPR_OR_OR, false); } 722 "||" { BIN_OP_RETURN (EXPR_OR_OR, false); }
768 "<<" { XBIN_OP_RETURN (LSHIFT, false); } 723 "<<" { XBIN_OP_RETURN (LSHIFT, false); }
769 ">>" { XBIN_OP_RETURN (RSHIFT, false); } 724 ">>" { XBIN_OP_RETURN (RSHIFT, false); }
770 725
771 {NOT} { 726 {NOT} {
772 if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
773 lexer_flags.past_plot_range = true;
774
775 if (yytext[0] == '~') 727 if (yytext[0] == '~')
776 BIN_OP_RETURN (EXPR_NOT, false); 728 BIN_OP_RETURN (EXPR_NOT, false);
777 else 729 else
778 XBIN_OP_RETURN (EXPR_NOT, false); 730 XBIN_OP_RETURN (EXPR_NOT, false);
779 } 731 }
780 732
781 "+" {
782 if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
783 lexer_flags.past_plot_range = true;
784 BIN_OP_RETURN ('+', false);
785 }
786
787 "-" {
788 if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
789 lexer_flags.past_plot_range = true;
790 BIN_OP_RETURN ('-', false);
791 }
792
793 "(" { 733 "(" {
794 lexer_flags.looking_at_indirect_ref = false; 734 lexer_flags.looking_at_indirect_ref = false;
795 if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
796 lexer_flags.past_plot_range = true;
797 nesting_level.paren (); 735 nesting_level.paren ();
798 promptflag--; 736 promptflag--;
799 TOK_RETURN ('('); 737 TOK_RETURN ('(');
800 } 738 }
801 739
802 ")" { 740 ")" {
803 nesting_level.remove (); 741 nesting_level.remove ();
804
805 current_input_column++; 742 current_input_column++;
806 lexer_flags.cant_be_identifier = true;
807 lexer_flags.quote_is_transpose = true; 743 lexer_flags.quote_is_transpose = true;
808 lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket_or_brace (); 744 lexer_flags.convert_spaces_to_comma = nesting_level.is_bracket_or_brace ();
809 do_comma_insert_check (); 745 do_comma_insert_check ();
810 COUNT_TOK_AND_RETURN (')'); 746 COUNT_TOK_AND_RETURN (')');
811 } 747 }
812 748
813 "." { 749 "." { TOK_RETURN ('.'); }
814 TOK_RETURN ('.');
815 }
816 750
817 "+=" { XBIN_OP_RETURN (ADD_EQ, false); } 751 "+=" { XBIN_OP_RETURN (ADD_EQ, false); }
818 "-=" { XBIN_OP_RETURN (SUB_EQ, false); } 752 "-=" { XBIN_OP_RETURN (SUB_EQ, false); }
819 "*=" { XBIN_OP_RETURN (MUL_EQ, false); } 753 "*=" { XBIN_OP_RETURN (MUL_EQ, false); }
820 "/=" { XBIN_OP_RETURN (DIV_EQ, false); } 754 "/=" { XBIN_OP_RETURN (DIV_EQ, false); }
834 \{{S}* { 768 \{{S}* {
835 nesting_level.brace (); 769 nesting_level.brace ();
836 770
837 current_input_column += yyleng; 771 current_input_column += yyleng;
838 lexer_flags.quote_is_transpose = false; 772 lexer_flags.quote_is_transpose = false;
839 lexer_flags.cant_be_identifier = false;
840 lexer_flags.convert_spaces_to_comma = true; 773 lexer_flags.convert_spaces_to_comma = true;
841 774
842 promptflag--; 775 promptflag--;
843 eat_whitespace (); 776 eat_whitespace ();
844 777
1024 delete_input_buffer (void *buf) 957 delete_input_buffer (void *buf)
1025 { 958 {
1026 delete_buffer (static_cast<YY_BUFFER_STATE> (buf)); 959 delete_buffer (static_cast<YY_BUFFER_STATE> (buf));
1027 } 960 }
1028 961
1029 // Check to see if a character string matches any of the possible line
1030 // styles for plots.
1031
1032 static std::string
1033 plot_style_token (const std::string& s)
1034 {
1035 std::string retval;
1036
1037 // XXX FIXME XXX -- specify minimum match length for these.
1038 static const char *plot_styles[] =
1039 {
1040 "boxes",
1041 "boxerrorbars",
1042 "boxxyerrorbars",
1043 "candlesticks",
1044 "dots",
1045 "errorbars",
1046 "financebars",
1047 "fsteps",
1048 "histeps",
1049 "impulses",
1050 "lines",
1051 "linespoints",
1052 "points",
1053 "steps",
1054 "vector",
1055 "xerrorbars",
1056 "xyerrorbars",
1057 "yerrorbars",
1058 0,
1059 };
1060
1061 const char * const *tmp = plot_styles;
1062 while (*tmp)
1063 {
1064 if (almost_match (*tmp, s.c_str ()))
1065 {
1066 retval = *tmp;
1067 break;
1068 }
1069
1070 tmp++;
1071 }
1072
1073 return retval;
1074 }
1075
1076 // Check to see if a character string matches any of the possible axes
1077 // tags for plots.
1078
1079 static std::string
1080 plot_axes_token (const std::string& s)
1081 {
1082 std::string retval;
1083
1084 // XXX FIXME XXX -- specify minimum match length for these.
1085 static const char *plot_axes[] =
1086 {
1087 "x1y1",
1088 "x1y2",
1089 "x2y1",
1090 "x2y2",
1091 0,
1092 };
1093
1094 const char **tmp = plot_axes;
1095 while (*tmp)
1096 {
1097 if (almost_match (*tmp, s.c_str ()))
1098 {
1099 retval = *tmp;
1100 break;
1101 }
1102
1103 tmp++;
1104 }
1105
1106 return retval;
1107 }
1108
1109 // Check to see if a character string matches any one of the plot
1110 // option keywords. Don't match abbreviations for clear, since that's
1111 // not a gnuplot keyword (users will probably only expect to be able
1112 // to abbreviate actual gnuplot keywords).
1113
1114 static int
1115 is_plot_keyword (const std::string& s)
1116 {
1117 const char *t = s.c_str ();
1118 if (almost_match ("title", t, 1))
1119 {
1120 return TITLE;
1121 }
1122 else if (almost_match ("using", t, 1))
1123 {
1124 lexer_flags.in_plot_using = true;
1125 return USING;
1126 }
1127 else if (almost_match ("with", t, 1))
1128 {
1129 lexer_flags.in_plot_style = true;
1130 return WITH;
1131 }
1132 else if (almost_match ("axes", t, 2) || almost_match ("axis", t, 2))
1133 {
1134 lexer_flags.in_plot_axes = true;
1135 return AXES;
1136 }
1137 else if (strcmp ("clear", t) == 0)
1138 {
1139 return CLEAR;
1140 }
1141 else
1142 {
1143 return 0;
1144 }
1145 }
1146
1147 static void 962 static void
1148 prep_for_function (void) 963 prep_for_function (void)
1149 { 964 {
1150 end_tokens_expected++; 965 end_tokens_expected++;
1151 966
1180 static int 995 static int
1181 is_keyword_token (const std::string& s) 996 is_keyword_token (const std::string& s)
1182 { 997 {
1183 int l = input_line_number; 998 int l = input_line_number;
1184 int c = current_input_column; 999 int c = current_input_column;
1185
1186 if (lexer_flags.plotting)
1187 {
1188 if (lexer_flags.in_plot_style)
1189 {
1190 std::string sty = plot_style_token (s);
1191
1192 if (! sty.empty ())
1193 {
1194 lexer_flags.in_plot_style = false;
1195 yylval.tok_val = new token (sty, l, c);
1196 token_stack.push (yylval.tok_val);
1197 return STYLE;
1198 }
1199 }
1200 else if (lexer_flags.in_plot_axes)
1201 {
1202 std::string axes = plot_axes_token (s);
1203
1204 if (! axes.empty ())
1205 {
1206 lexer_flags.in_plot_axes = false;
1207 yylval.tok_val = new token (axes, l, c);
1208 token_stack.push (yylval.tok_val);
1209 return AXES_TAG;
1210 }
1211 }
1212 }
1213 1000
1214 int len = s.length (); 1001 int len = s.length ();
1215 1002
1216 const octave_kw *kw = octave_kw_hash::in_word_set (s.c_str (), len); 1003 const octave_kw *kw = octave_kw_hash::in_word_set (s.c_str (), len);
1217 1004
1309 case unwind_protect_kw: 1096 case unwind_protect_kw:
1310 end_tokens_expected++; 1097 end_tokens_expected++;
1311 promptflag--; 1098 promptflag--;
1312 break; 1099 break;
1313 1100
1314 case gplot_kw:
1315 lexer_flags.plotting = true;
1316 yylval.tok_val = new token (token::two_dee, l, c);
1317 break;
1318
1319 case gsplot_kw:
1320 lexer_flags.plotting = true;
1321 yylval.tok_val = new token (token::three_dee, l, c);
1322 break;
1323
1324 case replot_kw:
1325 lexer_flags.plotting = true;
1326 yylval.tok_val = new token (token::replot, l, c);
1327 break;
1328
1329 case function_kw: 1101 case function_kw:
1330 { 1102 {
1331 if (lexer_flags.defining_func) 1103 if (lexer_flags.defining_func)
1332 { 1104 {
1333 if (reading_fcn_file) 1105 if (reading_fcn_file)
1967 // If yytext doesn't contain a valid number, we are in deep doo doo. 1739 // If yytext doesn't contain a valid number, we are in deep doo doo.
1968 1740
1969 assert (nread == 1); 1741 assert (nread == 1);
1970 1742
1971 lexer_flags.quote_is_transpose = true; 1743 lexer_flags.quote_is_transpose = true;
1972 lexer_flags.cant_be_identifier = true;
1973 lexer_flags.convert_spaces_to_comma = true; 1744 lexer_flags.convert_spaces_to_comma = true;
1974
1975 if (lexer_flags.plotting && ! lexer_flags.in_plot_range)
1976 lexer_flags.past_plot_range = true;
1977 1745
1978 yylval.tok_val = new token (value, yytext, input_line_number, 1746 yylval.tok_val = new token (value, yytext, input_line_number,
1979 current_input_column); 1747 current_input_column);
1980 1748
1981 token_stack.push (yylval.tok_val); 1749 token_stack.push (yylval.tok_val);
2197 buf << static_cast<char> (c); 1965 buf << static_cast<char> (c);
2198 else 1966 else
2199 { 1967 {
2200 c = yyinput (); 1968 c = yyinput ();
2201 if (c == delim) 1969 if (c == delim)
2202 buf << static_cast<char> (c); 1970 {
1971 buf << static_cast<char> (c);
1972 if (lexer_flags.doing_rawcommand)
1973 buf << static_cast<char> (c);
1974 }
2203 else 1975 else
2204 { 1976 {
1977 std::string s;
2205 yyunput (c, yytext); 1978 yyunput (c, yytext);
2206 buf << OSSTREAM_ENDS; 1979 buf << OSSTREAM_ENDS;
2207 std::string s = do_string_escapes (OSSTREAM_STR (buf)); 1980 if (lexer_flags.doing_rawcommand)
1981 s = OSSTREAM_STR (buf);
1982 else
1983 s = do_string_escapes (OSSTREAM_STR(buf));
2208 OSSTREAM_FREEZE (buf); 1984 OSSTREAM_FREEZE (buf);
2209 1985
2210 if (text_style && lexer_flags.doing_set) 1986 if (text_style && lexer_flags.doing_rawcommand)
2211 { 1987 s = std::string (1, delim) + s + std::string (1, delim);
2212 s = std::string (1, delim) + s + std::string (1, delim);
2213 }
2214 else 1988 else
2215 { 1989 {
2216 lexer_flags.quote_is_transpose = true; 1990 lexer_flags.quote_is_transpose = true;
2217 lexer_flags.cant_be_identifier = true;
2218 lexer_flags.convert_spaces_to_comma = true; 1991 lexer_flags.convert_spaces_to_comma = true;
2219 } 1992 }
2220 1993
2221 yylval.tok_val = new token (s, bos_line, bos_col); 1994 yylval.tok_val = new token (s, bos_line, bos_col);
2222 token_stack.push (yylval.tok_val); 1995 token_stack.push (yylval.tok_val);
2392 } 2165 }
2393 } 2166 }
2394 } 2167 }
2395 2168
2396 lexer_flags.quote_is_transpose = true; 2169 lexer_flags.quote_is_transpose = true;
2397 lexer_flags.cant_be_identifier = false;
2398 lexer_flags.convert_spaces_to_comma = true; 2170 lexer_flags.convert_spaces_to_comma = true;
2399 2171
2400 return retval; 2172 return retval;
2401 } 2173 }
2402 2174
2451 int c = yytext[yyleng-1]; 2223 int c = yytext[yyleng-1];
2452 2224
2453 int cont_is_spc = eat_continuation (); 2225 int cont_is_spc = eat_continuation ();
2454 2226
2455 int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t'); 2227 int spc_gobbled = (cont_is_spc || c == ' ' || c == '\t');
2456
2457 // It is almost always an error for an identifier to be followed
2458 // directly by another identifier. Special cases are handled
2459 // below.
2460
2461 lexer_flags.cant_be_identifier = true;
2462 2228
2463 // If we are expecting a structure element, avoid recognizing 2229 // If we are expecting a structure element, avoid recognizing
2464 // keywords and other special names and return STRUCT_ELT, which is 2230 // keywords and other special names and return STRUCT_ELT, which is
2465 // a string that is also a valid identifier. But first, we have to 2231 // a string that is also a valid identifier. But first, we have to
2466 // decide whether to insert a comma. 2232 // decide whether to insert a comma.
2474 yylval.tok_val = new token (tok, input_line_number, 2240 yylval.tok_val = new token (tok, input_line_number,
2475 current_input_column); 2241 current_input_column);
2476 2242
2477 token_stack.push (yylval.tok_val); 2243 token_stack.push (yylval.tok_val);
2478 2244
2479 lexer_flags.cant_be_identifier = false;
2480 lexer_flags.quote_is_transpose = true; 2245 lexer_flags.quote_is_transpose = true;
2481 lexer_flags.convert_spaces_to_comma = true; 2246 lexer_flags.convert_spaces_to_comma = true;
2482 2247
2483 current_input_column += yyleng; 2248 current_input_column += yyleng;
2484 2249
2497 } 2262 }
2498 else 2263 else
2499 TOK_PUSH_AND_RETURN (tok, FCN_HANDLE); 2264 TOK_PUSH_AND_RETURN (tok, FCN_HANDLE);
2500 } 2265 }
2501 2266
2502 // If we have a regular keyword, or a plot STYLE, return it. 2267 // If we have a regular keyword, return it.
2503 // Keywords can be followed by identifiers (TOK_RETURN handles 2268 // Keywords can be followed by identifiers (TOK_RETURN handles
2504 // that). 2269 // that).
2505 2270
2506 if (kw_token) 2271 if (kw_token)
2507 { 2272 {
2508 if (kw_token < 0) 2273 if (kw_token < 0)
2509 return kw_token; 2274 return kw_token;
2510 else if (kw_token == STYLE)
2511 {
2512 current_input_column += yyleng;
2513 lexer_flags.quote_is_transpose = false;
2514 lexer_flags.convert_spaces_to_comma = true;
2515 return kw_token;
2516 }
2517 else 2275 else
2518 TOK_RETURN (kw_token); 2276 TOK_RETURN (kw_token);
2519 } 2277 }
2520 2278
2521 // See if we have a plot keyword (title, using, with, or clear). 2279 // See if we have a plot keyword (title, using, with, or clear).
2522
2523 if (lexer_flags.plotting)
2524 {
2525 // Yes, we really do need both of these plot_range variables.
2526 // One is used to mark when we are past all possiblity of a plot
2527 // range, the other is used to mark when we are actually between
2528 // the square brackets that surround the range.
2529
2530 if (! lexer_flags.in_plot_range)
2531 lexer_flags.past_plot_range = true;
2532
2533 // Option keywords can't appear in brackets, braces, or parentheses.
2534
2535 int plot_option_kw = 0;
2536
2537 if (nesting_level.none ())
2538 plot_option_kw = is_plot_keyword (tok);
2539
2540 if (lexer_flags.cant_be_identifier && plot_option_kw)
2541 TOK_RETURN (plot_option_kw);
2542 }
2543 2280
2544 int c1 = yyinput (); 2281 int c1 = yyinput ();
2545 2282
2546 bool next_tok_is_paren = (c1 == '('); 2283 bool next_tok_is_paren = (c1 == '(');
2547 2284
2589 { 2326 {
2590 force_local_variable (tok); 2327 force_local_variable (tok);
2591 } 2328 }
2592 else if (! next_tok_is_paren) 2329 else if (! next_tok_is_paren)
2593 { 2330 {
2594 if (tok == "gset") 2331 BEGIN (COMMAND_START);
2595 lexer_flags.doing_set = true; 2332 }
2596 2333
2334 if (is_rawcommand_name (tok))
2335 {
2336 lexer_flags.doing_rawcommand = true;
2597 BEGIN (COMMAND_START); 2337 BEGIN (COMMAND_START);
2598 } 2338 }
2599 } 2339 }
2600 2340
2601 // Find the token in the symbol table. Beware the magic 2341 // Find the token in the symbol table. Beware the magic
2659 looking_at_matrix_or_assign_lhs = false; 2399 looking_at_matrix_or_assign_lhs = false;
2660 2400
2661 // Not parsing an object index. 2401 // Not parsing an object index.
2662 looking_at_object_index = 0; 2402 looking_at_object_index = 0;
2663 2403
2664 // Next token can be identifier.
2665 cant_be_identifier = false;
2666
2667 // No need to do comma insert or convert spaces to comma at 2404 // No need to do comma insert or convert spaces to comma at
2668 // beginning of input. 2405 // beginning of input.
2669 convert_spaces_to_comma = true; 2406 convert_spaces_to_comma = true;
2670 do_comma_insert = false; 2407 do_comma_insert = false;
2671 2408
2672 // Not initially doing any plotting or setting of plot attributes. 2409 // Not initially doing any plotting or setting of plot attributes.
2673 doing_set = false; 2410 doing_rawcommand = false;
2674 in_plot_range = false;
2675 in_plot_style = false;
2676 in_plot_axes = false;
2677 in_plot_using = false;
2678 past_plot_range = false;
2679 plotting = false;
2680 2411
2681 // Not initially looking at indirect references. 2412 // Not initially looking at indirect references.
2682 looking_at_indirect_ref = false; 2413 looking_at_indirect_ref = false;
2683 2414
2684 // Quote marks strings intially. 2415 // Quote marks strings intially.