comparison libinterp/parse-tree/lex.ll @ 16680:de79cdbbdf7c

improve parsing of commands * lex.ll (CMD_OR_COMPUTED_ASSIGN_OP): New macro. ("+=", "-=", "*=", "/=", "\\=", ".+=", ".-=", ".*=", "./=", ".\\=", "^=", "**=", ".^=", ".**=", "&=", "|=", "<<=", ">>="): Use it. (CMD_OR_UNARY_OP): Use previous_token_may_be_command instead of looks_like_command_arg. ("--", "++"): Use CMD_OR_UNARY_OP. ( \?{IDENT} | \?{IDENT}\.{IDENT}): Check for possible command syntax. ({IDENT}@{IDENT} | {IDENT}@{IDENT}.{IDENT}): Likewise.
author John W. Eaton <jwe@octave.org>
date Sat, 18 May 2013 14:34:25 -0400
parents 4258750c76ed
children d3619d4d267c
comparison
equal deleted inserted replaced
16679:cf939872811c 16680:de79cdbbdf7c
145 return curr_lexer->handle_op_internal (TOK, false, COMPAT); \ 145 return curr_lexer->handle_op_internal (TOK, false, COMPAT); \
146 } \ 146 } \
147 } \ 147 } \
148 while (0) 148 while (0)
149 149
150 #define CMD_OR_COMPUTED_ASSIGN_OP(PATTERN, TOK) \
151 \
152 do \
153 { \
154 curr_lexer->lexer_debug (PATTERN); \
155 \
156 if (curr_lexer->previous_token_may_be_command ()) \
157 { \
158 yyless (0); \
159 curr_lexer->push_start_state (COMMAND_START); \
160 } \
161 else \
162 { \
163 return curr_lexer->handle_incompatible_op (PATTERN, TOK, false); \
164 } \
165 } \
166 while (0)
167
150 #define CMD_OR_UNARY_OP(PATTERN, TOK, COMPAT) \ 168 #define CMD_OR_UNARY_OP(PATTERN, TOK, COMPAT) \
151 \ 169 \
152 do \ 170 do \
153 { \ 171 { \
154 curr_lexer->lexer_debug (PATTERN); \ 172 curr_lexer->lexer_debug (PATTERN); \
155 \ 173 \
156 if (curr_lexer->looks_like_command_arg ()) \ 174 if (curr_lexer->previous_token_may_be_command ()) \
157 { \ 175 { \
158 yyless (0); \ 176 yyless (0); \
159 curr_lexer->push_start_state (COMMAND_START); \ 177 curr_lexer->push_start_state (COMMAND_START); \
160 } \ 178 } \
161 else \ 179 else \
735 753
736 {IDENT}@{IDENT} | 754 {IDENT}@{IDENT} |
737 {IDENT}@{IDENT}.{IDENT} { 755 {IDENT}@{IDENT}.{IDENT} {
738 curr_lexer->lexer_debug ("{IDENT}@{IDENT}|{IDENT}@{IDENT}.{IDENT}"); 756 curr_lexer->lexer_debug ("{IDENT}@{IDENT}|{IDENT}@{IDENT}.{IDENT}");
739 757
740 int id_tok = curr_lexer->handle_superclass_identifier (); 758 if (curr_lexer->previous_token_may_be_command ())
741 759 {
742 if (id_tok >= 0) 760 yyless (0);
743 { 761 curr_lexer->push_start_state (COMMAND_START);
744 curr_lexer->looking_for_object_index = true; 762 }
745 763 else
746 return curr_lexer->count_token_internal (SUPERCLASSREF); 764 {
765 int id_tok = curr_lexer->handle_superclass_identifier ();
766
767 if (id_tok >= 0)
768 {
769 curr_lexer->looking_for_object_index = true;
770
771 return curr_lexer->count_token_internal (SUPERCLASSREF);
772 }
747 } 773 }
748 } 774 }
749 775
750 %{ 776 %{
751 // Metaclass query 777 // Metaclass query
753 779
754 \?{IDENT} | 780 \?{IDENT} |
755 \?{IDENT}\.{IDENT} { 781 \?{IDENT}\.{IDENT} {
756 curr_lexer->lexer_debug ("\\?{IDENT}|\\?{IDENT}\\.{IDENT}"); 782 curr_lexer->lexer_debug ("\\?{IDENT}|\\?{IDENT}\\.{IDENT}");
757 783
758 int id_tok = curr_lexer->handle_meta_identifier (); 784 if (curr_lexer->previous_token_may_be_command ()
759 785 && curr_lexer->space_follows_previous_token ())
760 if (id_tok >= 0) 786 {
761 { 787 yyless (0);
762 curr_lexer->looking_for_object_index = true; 788 curr_lexer->push_start_state (COMMAND_START);
763 789 }
764 return curr_lexer->count_token_internal (METAQUERY); 790 else
791 {
792 int id_tok = curr_lexer->handle_meta_identifier ();
793
794 if (id_tok >= 0)
795 {
796 curr_lexer->looking_for_object_index = true;
797
798 return curr_lexer->count_token_internal (METAQUERY);
799 }
765 } 800 }
766 } 801 }
767 802
768 "@" { 803 "@" {
769 if (curr_lexer->previous_token_may_be_command () 804 if (curr_lexer->previous_token_may_be_command ()
994 1029
995 ".'" { 1030 ".'" {
996 return curr_lexer->handle_op (".'", TRANSPOSE, false); 1031 return curr_lexer->handle_op (".'", TRANSPOSE, false);
997 } 1032 }
998 1033
999 "++" { 1034 "++" { CMD_OR_UNARY_OP ("++", PLUS_PLUS, false); }
1000 curr_lexer->lexer_debug ("++"); 1035 "--" { CMD_OR_UNARY_OP ("--", MINUS_MINUS, false); }
1001 1036
1002 int tok = curr_lexer->handle_incompatible_unary_op (PLUS_PLUS, false); 1037 "(" {
1003 1038 curr_lexer->lexer_debug ("(");
1004 if (tok < 0) 1039
1040 bool unput_comma = false;
1041
1042 if (curr_lexer->whitespace_is_significant ()
1043 && curr_lexer->space_follows_previous_token ())
1044 {
1045 int tok = curr_lexer->previous_token_value ();
1046
1047 if (! (tok == '[' || tok == '{'
1048 || curr_lexer->previous_token_is_binop ()))
1049 unput_comma = true;
1050 }
1051
1052 if (unput_comma)
1005 { 1053 {
1006 yyless (0); 1054 yyless (0);
1007 curr_lexer->xunput (','); 1055 curr_lexer->xunput (',');
1008 // Adjust for comma that was not really in the input stream. 1056 // Adjust for comma that was not really in the input stream.
1009 curr_lexer->current_input_column--; 1057 curr_lexer->current_input_column--;
1010 } 1058 }
1011 else 1059 else
1012 return tok;
1013 }
1014
1015 "--" {
1016 curr_lexer->lexer_debug ("--");
1017
1018 int tok = curr_lexer->handle_incompatible_unary_op (MINUS_MINUS, false);
1019
1020 if (tok < 0)
1021 {
1022 yyless (0);
1023 curr_lexer->xunput (',');
1024 // Adjust for comma that was not really in the input stream.
1025 curr_lexer->current_input_column--;
1026 }
1027 else
1028 return tok;
1029 }
1030
1031 "(" {
1032 curr_lexer->lexer_debug ("(");
1033
1034 bool unput_comma = false;
1035
1036 if (curr_lexer->whitespace_is_significant ()
1037 && curr_lexer->space_follows_previous_token ())
1038 {
1039 int tok = curr_lexer->previous_token_value ();
1040
1041 if (! (tok == '[' || tok == '{'
1042 || curr_lexer->previous_token_is_binop ()))
1043 unput_comma = true;
1044 }
1045
1046 if (unput_comma)
1047 {
1048 yyless (0);
1049 curr_lexer->xunput (',');
1050 // Adjust for comma that was not really in the input stream.
1051 curr_lexer->current_input_column--;
1052 }
1053 else
1054 { 1060 {
1055 // If we are looking for an object index, then push TRUE for 1061 // If we are looking for an object index, then push TRUE for
1056 // looking_at_object_index. Otherwise, just push whatever state 1062 // looking_at_object_index. Otherwise, just push whatever state
1057 // is current (so that we can pop it off the stack when we find 1063 // is current (so that we can pop it off the stack when we find
1058 // the matching close paren). 1064 // the matching close paren).
1117 curr_lexer->maybe_mark_previous_token_as_variable (); 1123 curr_lexer->maybe_mark_previous_token_as_variable ();
1118 1124
1119 return curr_lexer->handle_op ("=", '='); 1125 return curr_lexer->handle_op ("=", '=');
1120 } 1126 }
1121 1127
1122 "+=" { return curr_lexer->handle_incompatible_op ("+=", ADD_EQ); } 1128 "+=" { CMD_OR_COMPUTED_ASSIGN_OP ("+=", ADD_EQ); }
1123 "-=" { return curr_lexer->handle_incompatible_op ("-=", SUB_EQ); } 1129 "-=" { CMD_OR_COMPUTED_ASSIGN_OP ("-=", SUB_EQ); }
1124 "*=" { return curr_lexer->handle_incompatible_op ("*=", MUL_EQ); } 1130 "*=" { CMD_OR_COMPUTED_ASSIGN_OP ("*=", MUL_EQ); }
1125 "/=" { return curr_lexer->handle_incompatible_op ("/=", DIV_EQ); } 1131 "/=" { CMD_OR_COMPUTED_ASSIGN_OP ("/=", DIV_EQ); }
1126 "\\=" { return curr_lexer->handle_incompatible_op ("\\=", LEFTDIV_EQ); } 1132 "\\=" { CMD_OR_COMPUTED_ASSIGN_OP ("\\=", LEFTDIV_EQ); }
1127 ".+=" { return curr_lexer->handle_incompatible_op (".+=", ADD_EQ); } 1133 ".+=" { CMD_OR_COMPUTED_ASSIGN_OP (".+=", ADD_EQ); }
1128 ".-=" { return curr_lexer->handle_incompatible_op (".-=", SUB_EQ); } 1134 ".-=" { CMD_OR_COMPUTED_ASSIGN_OP (".-=", SUB_EQ); }
1129 ".*=" { return curr_lexer->handle_incompatible_op (".*=", EMUL_EQ); } 1135 ".*=" { CMD_OR_COMPUTED_ASSIGN_OP (".*=", EMUL_EQ); }
1130 "./=" { return curr_lexer->handle_incompatible_op ("./=", EDIV_EQ); } 1136 "./=" { CMD_OR_COMPUTED_ASSIGN_OP ("./=", EDIV_EQ); }
1131 ".\\=" { return curr_lexer->handle_incompatible_op (".\\=", ELEFTDIV_EQ); } 1137 ".\\=" { CMD_OR_COMPUTED_ASSIGN_OP (".\\=", ELEFTDIV_EQ); }
1132 "^=" { return curr_lexer->handle_incompatible_op ("^=", POW_EQ); } 1138 "^=" { CMD_OR_COMPUTED_ASSIGN_OP ("^=", POW_EQ); }
1133 "**=" { return curr_lexer->handle_incompatible_op ("^=", POW_EQ); } 1139 "**=" { CMD_OR_COMPUTED_ASSIGN_OP ("^=", POW_EQ); }
1134 ".^=" { return curr_lexer->handle_incompatible_op (".^=", EPOW_EQ); } 1140 ".^=" { CMD_OR_COMPUTED_ASSIGN_OP (".^=", EPOW_EQ); }
1135 ".**=" { return curr_lexer->handle_incompatible_op (".^=", EPOW_EQ); } 1141 ".**=" { CMD_OR_COMPUTED_ASSIGN_OP (".^=", EPOW_EQ); }
1136 "&=" { return curr_lexer->handle_incompatible_op ("&=", AND_EQ); } 1142 "&=" { CMD_OR_COMPUTED_ASSIGN_OP ("&=", AND_EQ); }
1137 "|=" { return curr_lexer->handle_incompatible_op ("|=", OR_EQ); } 1143 "|=" { CMD_OR_COMPUTED_ASSIGN_OP ("|=", OR_EQ); }
1138 "<<=" { return curr_lexer->handle_incompatible_op ("<<=", LSHIFT_EQ); } 1144 "<<=" { CMD_OR_COMPUTED_ASSIGN_OP ("<<=", LSHIFT_EQ); }
1139 ">>=" { return curr_lexer->handle_incompatible_op (">>=", RSHIFT_EQ); } 1145 ">>=" { CMD_OR_COMPUTED_ASSIGN_OP (">>=", RSHIFT_EQ); }
1140 1146
1141 %{ 1147 %{
1142 // In Matlab, '{' may also trigger command syntax. 1148 // In Matlab, '{' may also trigger command syntax.
1143 %} 1149 %}
1144 1150