Mercurial > hg > octave-nkf
comparison libinterp/parse-tree/lex.ll @ 16236:d8c0f46efaf0 classdef
maint: periodic merge of default to classdef
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Sat, 09 Mar 2013 17:54:40 -0500 |
parents | d2b268936783 2b15ae55c721 |
children | b8a2df776118 |
comparison
equal
deleted
inserted
replaced
16212:d2b268936783 | 16236:d8c0f46efaf0 |
---|---|
44 } | 44 } |
45 | 45 |
46 %s COMMAND_START | 46 %s COMMAND_START |
47 %s MATRIX_START | 47 %s MATRIX_START |
48 | 48 |
49 %x INPUT_FILE_BEGIN | 49 %x INPUT_FILE_START |
50 | |
51 %x BLOCK_COMMENT_START | |
52 %x LINE_COMMENT_START | |
50 | 53 |
51 %{ | 54 %{ |
52 | 55 |
53 #include <cctype> | 56 #include <cctype> |
54 #include <cstring> | 57 #include <cstring> |
125 #undef YY_FATAL_ERROR | 128 #undef YY_FATAL_ERROR |
126 #endif | 129 #endif |
127 #define YY_FATAL_ERROR(msg) \ | 130 #define YY_FATAL_ERROR(msg) \ |
128 (yyget_extra (yyscanner))->fatal_error (msg) | 131 (yyget_extra (yyscanner))->fatal_error (msg) |
129 | 132 |
130 #define DISPLAY_TOK_AND_RETURN(tok) \ | |
131 do \ | |
132 { \ | |
133 int tok_val = tok; \ | |
134 if (Vdisplay_tokens) \ | |
135 curr_lexer->display_token (tok_val); \ | |
136 if (lexer_debug_flag) \ | |
137 { \ | |
138 std::cerr << "R: "; \ | |
139 curr_lexer->display_token (tok_val); \ | |
140 std::cerr << std::endl; \ | |
141 } \ | |
142 return tok_val; \ | |
143 } \ | |
144 while (0) | |
145 | |
146 #define COUNT_TOK_AND_RETURN(tok) \ | |
147 do \ | |
148 { \ | |
149 if (tok != '\n') \ | |
150 { \ | |
151 Vtoken_count++; \ | |
152 curr_lexer->token_count++; \ | |
153 } \ | |
154 DISPLAY_TOK_AND_RETURN (tok); \ | |
155 } \ | |
156 while (0) | |
157 | |
158 #define TOK_RETURN(tok) \ | |
159 do \ | |
160 { \ | |
161 curr_lexer->current_input_column += yyleng; \ | |
162 curr_lexer->quote_is_transpose = false; \ | |
163 curr_lexer->convert_spaces_to_comma = true; \ | |
164 COUNT_TOK_AND_RETURN (tok); \ | |
165 } \ | |
166 while (0) | |
167 | |
168 #define TOK_PUSH_AND_RETURN(name, tok) \ | |
169 do \ | |
170 { \ | |
171 curr_lexer->push_token \ | |
172 (new token (name, curr_lexer->input_line_number, \ | |
173 curr_lexer->current_input_column)); \ | |
174 TOK_RETURN (tok); \ | |
175 } \ | |
176 while (0) | |
177 | |
178 #define BIN_OP_RETURN_INTERNAL(tok, convert, bos, qit) \ | |
179 do \ | |
180 { \ | |
181 curr_lexer->push_token \ | |
182 (new token (curr_lexer->input_line_number, \ | |
183 curr_lexer->current_input_column)); \ | |
184 curr_lexer->current_input_column += yyleng; \ | |
185 curr_lexer->quote_is_transpose = qit; \ | |
186 curr_lexer->convert_spaces_to_comma = convert; \ | |
187 curr_lexer->looking_for_object_index = false; \ | |
188 curr_lexer->at_beginning_of_statement = bos; \ | |
189 COUNT_TOK_AND_RETURN (tok); \ | |
190 } \ | |
191 while (0) | |
192 | |
193 #define XBIN_OP_RETURN_INTERNAL(tok, convert, bos, qit) \ | |
194 do \ | |
195 { \ | |
196 curr_lexer->gripe_matlab_incompatible_operator (yytext); \ | |
197 BIN_OP_RETURN_INTERNAL (tok, convert, bos, qit); \ | |
198 } \ | |
199 while (0) | |
200 | |
201 #define BIN_OP_RETURN(tok, convert, bos) \ | |
202 do \ | |
203 { \ | |
204 BIN_OP_RETURN_INTERNAL (tok, convert, bos, false); \ | |
205 } \ | |
206 while (0) | |
207 | |
208 #define XBIN_OP_RETURN(tok, convert, bos) \ | |
209 do \ | |
210 { \ | |
211 curr_lexer->gripe_matlab_incompatible_operator (yytext); \ | |
212 BIN_OP_RETURN (tok, convert, bos); \ | |
213 } \ | |
214 while (0) | |
215 | |
216 #define LEXER_DEBUG(pattern) \ | |
217 do \ | |
218 { \ | |
219 if (lexer_debug_flag) \ | |
220 curr_lexer->lexer_debug (pattern, yytext); \ | |
221 } \ | |
222 while (0) | |
223 | |
224 static bool Vdisplay_tokens = false; | 133 static bool Vdisplay_tokens = false; |
225 | 134 |
226 static unsigned int Vtoken_count = 0; | 135 static unsigned int Vtoken_count = 0; |
227 | 136 |
228 // Internal variable for lexer debugging state. | 137 // Internal variable for lexer debugging state. |
244 CONT ({EL}|{BS}) | 153 CONT ({EL}|{BS}) |
245 Im [iIjJ] | 154 Im [iIjJ] |
246 CCHAR [#%] | 155 CCHAR [#%] |
247 COMMENT ({CCHAR}.*{NL}) | 156 COMMENT ({CCHAR}.*{NL}) |
248 SNLCMT ({SNL}|{COMMENT}) | 157 SNLCMT ({SNL}|{COMMENT}) |
249 NOT ((\~)|(\!)) | |
250 POW ((\*\*)|(\^)) | |
251 EPOW (\.{POW}) | |
252 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) | 158 IDENT ([_$a-zA-Z][_$a-zA-Z0-9]*) |
253 EXPON ([DdEe][+-]?{D}+) | 159 EXPON ([DdEe][+-]?{D}+) |
254 NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) | 160 NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) |
161 | |
162 ANY_INCLUDING_NL (.|{NL}) | |
163 | |
255 %% | 164 %% |
256 | 165 |
257 %{ | 166 %{ |
258 // Make script and function files start with a bogus token. This makes | 167 // Make script and function files start with a bogus token. This makes |
259 // the parser go down a special path. | 168 // the parser go down a special path. |
260 %} | 169 %} |
261 | 170 |
262 <INPUT_FILE_BEGIN>. { | 171 <INPUT_FILE_START>{ANY_INCLUDING_NL} { |
263 LEXER_DEBUG ("<INPUT_FILE_BEGIN>."); | 172 curr_lexer->lexer_debug ("<INPUT_FILE_START>{ANY_INCLUDING_NL}"); |
264 | 173 |
265 BEGIN (INITIAL); | |
266 curr_lexer->xunput (yytext[0]); | 174 curr_lexer->xunput (yytext[0]); |
267 | 175 |
268 // May be reset later if we see "function" or "classdef" appears | 176 // May be reset later if we see "function" or "classdef" appears |
269 // as the first token. | 177 // as the first token. |
270 curr_lexer->reading_script_file = true; | 178 curr_lexer->reading_script_file = true; |
271 | 179 |
272 DISPLAY_TOK_AND_RETURN (INPUT_FILE); | 180 curr_lexer->pop_start_state (); |
181 | |
182 return curr_lexer->show_token (INPUT_FILE); | |
273 } | 183 } |
274 | 184 |
275 %{ | 185 %{ |
276 // Help and other command-style functions. | 186 // Help and other command-style functions. |
277 %} | 187 %} |
278 | 188 |
279 <COMMAND_START>{NL} { | 189 <COMMAND_START>{NL} { |
280 LEXER_DEBUG ("<COMMAND_START>{NL}"); | 190 curr_lexer->lexer_debug ("<COMMAND_START>{NL}"); |
281 | 191 |
282 BEGIN (INITIAL); | |
283 curr_lexer->input_line_number++; | 192 curr_lexer->input_line_number++; |
284 curr_lexer->current_input_column = 1; | 193 curr_lexer->current_input_column = 1; |
285 | 194 |
286 curr_lexer->quote_is_transpose = false; | 195 curr_lexer->quote_is_transpose = false; |
287 curr_lexer->convert_spaces_to_comma = true; | 196 curr_lexer->convert_spaces_to_comma = true; |
288 curr_lexer->looking_for_object_index = false; | 197 curr_lexer->looking_for_object_index = false; |
289 curr_lexer->at_beginning_of_statement = true; | 198 curr_lexer->at_beginning_of_statement = true; |
290 | 199 |
291 COUNT_TOK_AND_RETURN ('\n'); | 200 curr_lexer->pop_start_state (); |
201 | |
202 return curr_lexer->count_token ('\n'); | |
292 } | 203 } |
293 | 204 |
294 <COMMAND_START>[\;\,] { | 205 <COMMAND_START>[\;\,] { |
295 LEXER_DEBUG ("<COMMAND_START>[\\;\\,]"); | 206 curr_lexer->lexer_debug ("<COMMAND_START>[\\;\\,]"); |
296 | 207 |
297 curr_lexer->looking_for_object_index = false; | 208 curr_lexer->looking_for_object_index = false; |
298 curr_lexer->at_beginning_of_statement = true; | 209 curr_lexer->at_beginning_of_statement = true; |
299 | 210 |
300 BEGIN (INITIAL); | 211 curr_lexer->pop_start_state (); |
301 | 212 |
302 if (strcmp (yytext, ",") == 0) | 213 if (strcmp (yytext, ",") == 0) |
303 TOK_RETURN (','); | 214 return curr_lexer->handle_token (','); |
304 else | 215 else |
305 TOK_RETURN (';'); | 216 return curr_lexer->handle_token (';'); |
306 } | 217 } |
307 | 218 |
308 <COMMAND_START>[\"\'] { | 219 <COMMAND_START>[\"\'] { |
309 LEXER_DEBUG ("<COMMAND_START>[\\\"\\']"); | 220 curr_lexer->lexer_debug ("<COMMAND_START>[\\\"\\']"); |
310 | 221 |
311 curr_lexer->at_beginning_of_statement = false; | 222 curr_lexer->at_beginning_of_statement = false; |
312 | 223 |
313 curr_lexer->current_input_column++; | 224 curr_lexer->current_input_column++; |
314 int tok = curr_lexer->handle_string (yytext[0]); | 225 int tok = curr_lexer->handle_string (yytext[0]); |
315 | 226 |
316 COUNT_TOK_AND_RETURN (tok); | 227 return curr_lexer->count_token (tok); |
317 } | 228 } |
318 | 229 |
319 <COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}* { | 230 <COMMAND_START>[^#% \t\r\n\;\,\"\'][^ \t\r\n\;\,]*{S}* { |
320 LEXER_DEBUG ("<COMMAND_START>[^#% \\t\\r\\n\\;\\,\\\"\\'][^ \\t\\r\\n\\;\\,]*{S}*"); | 231 curr_lexer->lexer_debug ("<COMMAND_START>[^#% \\t\\r\\n\\;\\,\\\"\\'][^ \\t\\r\\n\\;\\,]*{S}*"); |
321 | 232 |
322 std::string tok = strip_trailing_whitespace (yytext); | 233 std::string tok = strip_trailing_whitespace (yytext); |
323 | 234 |
324 curr_lexer->looking_for_object_index = false; | 235 curr_lexer->looking_for_object_index = false; |
325 curr_lexer->at_beginning_of_statement = false; | 236 curr_lexer->at_beginning_of_statement = false; |
326 | 237 |
327 TOK_PUSH_AND_RETURN (tok, SQ_STRING); | 238 return curr_lexer->handle_token (tok, SQ_STRING); |
328 } | 239 } |
329 | 240 |
330 %{ | 241 %{ |
331 // For this and the next two rules, we're looking at ']', and we | 242 // For this and the next two rules, we're looking at ']', and we |
332 // need to know if the next token is '=' or '=='. | 243 // need to know if the next token is '=' or '=='. |
340 | 251 |
341 // FIXME -- we need to handle block comments here. | 252 // FIXME -- we need to handle block comments here. |
342 %} | 253 %} |
343 | 254 |
344 <MATRIX_START>{SNLCMT}*\]{S}* { | 255 <MATRIX_START>{SNLCMT}*\]{S}* { |
345 LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\]{S}*"); | 256 curr_lexer->lexer_debug ("<MATRIX_START>{SNLCMT}*\\]{S}*"); |
346 | 257 |
347 curr_lexer->scan_for_comments (yytext); | 258 curr_lexer->scan_for_comments (yytext); |
348 curr_lexer->fixup_column_count (yytext); | 259 curr_lexer->fixup_column_count (yytext); |
349 | 260 |
350 curr_lexer->looking_at_object_index.pop_front (); | 261 curr_lexer->looking_at_object_index.pop_front (); |
358 int tok_to_return = curr_lexer->handle_close_bracket (spc_gobbled, ']'); | 269 int tok_to_return = curr_lexer->handle_close_bracket (spc_gobbled, ']'); |
359 | 270 |
360 if (spc_gobbled) | 271 if (spc_gobbled) |
361 curr_lexer->xunput (' '); | 272 curr_lexer->xunput (' '); |
362 | 273 |
363 COUNT_TOK_AND_RETURN (tok_to_return); | 274 return curr_lexer->count_token (tok_to_return); |
364 } | 275 } |
365 | 276 |
366 %{ | 277 %{ |
367 // FIXME -- we need to handle block comments here. | 278 // FIXME -- we need to handle block comments here. |
368 %} | 279 %} |
369 | 280 |
370 <MATRIX_START>{SNLCMT}*\}{S}* { | 281 <MATRIX_START>{SNLCMT}*\}{S}* { |
371 LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*\\}{S}*"); | 282 curr_lexer->lexer_debug ("<MATRIX_START>{SNLCMT}*\\}{S}*"); |
372 | 283 |
373 curr_lexer->scan_for_comments (yytext); | 284 curr_lexer->scan_for_comments (yytext); |
374 curr_lexer->fixup_column_count (yytext); | 285 curr_lexer->fixup_column_count (yytext); |
375 | 286 |
376 curr_lexer->looking_at_object_index.pop_front (); | 287 curr_lexer->looking_at_object_index.pop_front (); |
384 int tok_to_return = curr_lexer->handle_close_bracket (spc_gobbled, '}'); | 295 int tok_to_return = curr_lexer->handle_close_bracket (spc_gobbled, '}'); |
385 | 296 |
386 if (spc_gobbled) | 297 if (spc_gobbled) |
387 curr_lexer->xunput (' '); | 298 curr_lexer->xunput (' '); |
388 | 299 |
389 COUNT_TOK_AND_RETURN (tok_to_return); | 300 return curr_lexer->count_token (tok_to_return); |
390 } | 301 } |
391 | 302 |
392 %{ | 303 %{ |
393 // Commas are element separators in matrix constants. If we don't | 304 // Commas are element separators in matrix constants. If we don't |
394 // check for continuations here we can end up inserting too many | 305 // check for continuations here we can end up inserting too many |
395 // commas. | 306 // commas. |
396 %} | 307 %} |
397 | 308 |
398 <MATRIX_START>{S}*\,{S}* { | 309 <MATRIX_START>{S}*\,{S}* { |
399 LEXER_DEBUG ("<MATRIX_START>{S}*\\,{S}*"); | 310 curr_lexer->lexer_debug ("<MATRIX_START>{S}*\\,{S}*"); |
400 | 311 |
401 curr_lexer->current_input_column += yyleng; | 312 curr_lexer->current_input_column += yyleng; |
402 | 313 |
403 int tmp = curr_lexer->eat_continuation (); | 314 int tmp = curr_lexer->eat_continuation (); |
404 | 315 |
415 | 326 |
416 curr_lexer->xunput (';'); | 327 curr_lexer->xunput (';'); |
417 } | 328 } |
418 } | 329 } |
419 | 330 |
420 COUNT_TOK_AND_RETURN (','); | 331 return curr_lexer->count_token (','); |
421 } | 332 } |
422 | 333 |
423 %{ | 334 %{ |
424 // In some cases, spaces in matrix constants can turn into commas. | 335 // In some cases, spaces in matrix constants can turn into commas. |
425 // If commas are required, spaces are not important in matrix | 336 // If commas are required, spaces are not important in matrix |
426 // constants so we just eat them. If we don't check for continuations | 337 // constants so we just eat them. If we don't check for continuations |
427 // here we can end up inserting too many commas. | 338 // here we can end up inserting too many commas. |
428 %} | 339 %} |
429 | 340 |
430 <MATRIX_START>{S}+ { | 341 <MATRIX_START>{S}+ { |
431 LEXER_DEBUG ("<MATRIX_START>{S}+"); | 342 curr_lexer->lexer_debug ("<MATRIX_START>{S}+"); |
432 | 343 |
433 curr_lexer->current_input_column += yyleng; | 344 curr_lexer->current_input_column += yyleng; |
434 | 345 |
435 curr_lexer->at_beginning_of_statement = false; | 346 curr_lexer->at_beginning_of_statement = false; |
436 | 347 |
457 curr_lexer->convert_spaces_to_comma = true; | 368 curr_lexer->convert_spaces_to_comma = true; |
458 curr_lexer->looking_for_object_index = false; | 369 curr_lexer->looking_for_object_index = false; |
459 | 370 |
460 curr_lexer->maybe_warn_separator_insert (','); | 371 curr_lexer->maybe_warn_separator_insert (','); |
461 | 372 |
462 COUNT_TOK_AND_RETURN (','); | 373 return curr_lexer->count_token (','); |
463 } | 374 } |
464 } | 375 } |
465 } | 376 } |
466 | 377 |
467 %{ | 378 %{ |
471 | 382 |
472 // FIXME -- we need to handle block comments here. | 383 // FIXME -- we need to handle block comments here. |
473 %} | 384 %} |
474 | 385 |
475 <MATRIX_START>{SNLCMT}*;{SNLCMT}* { | 386 <MATRIX_START>{SNLCMT}*;{SNLCMT}* { |
476 LEXER_DEBUG ("<MATRIX_START>{SNLCMT}*;{SNLCMT}*"); | 387 curr_lexer->lexer_debug ("<MATRIX_START>{SNLCMT}*;{SNLCMT}*"); |
477 | 388 |
478 curr_lexer->scan_for_comments (yytext); | 389 curr_lexer->scan_for_comments (yytext); |
479 curr_lexer->fixup_column_count (yytext); | 390 curr_lexer->fixup_column_count (yytext); |
480 curr_lexer->eat_whitespace (); | 391 curr_lexer->eat_whitespace (); |
481 | 392 |
482 curr_lexer->quote_is_transpose = false; | 393 curr_lexer->quote_is_transpose = false; |
483 curr_lexer->convert_spaces_to_comma = true; | 394 curr_lexer->convert_spaces_to_comma = true; |
484 curr_lexer->looking_for_object_index = false; | 395 curr_lexer->looking_for_object_index = false; |
485 curr_lexer->at_beginning_of_statement = false; | 396 curr_lexer->at_beginning_of_statement = false; |
486 | 397 |
487 COUNT_TOK_AND_RETURN (';'); | 398 return curr_lexer->count_token (';'); |
488 } | 399 } |
489 | 400 |
490 %{ | 401 %{ |
491 // In some cases, new lines can also become row separators. If we | 402 // In some cases, new lines can also become row separators. If we |
492 // don't eat whitespace here we can end up inserting too many | 403 // don't eat whitespace here we can end up inserting too many |
495 // FIXME -- we need to handle block comments here. | 406 // FIXME -- we need to handle block comments here. |
496 %} | 407 %} |
497 | 408 |
498 <MATRIX_START>{S}*{COMMENT}{SNLCMT}* | | 409 <MATRIX_START>{S}*{COMMENT}{SNLCMT}* | |
499 <MATRIX_START>{S}*{NL}{SNLCMT}* { | 410 <MATRIX_START>{S}*{NL}{SNLCMT}* { |
500 LEXER_DEBUG ("<MATRIX_START>{S}*{COMMENT}{SNLCMT}*|<MATRIX_START>{S}*{NL}{SNLCMT}*"); | 411 curr_lexer->lexer_debug ("<MATRIX_START>{S}*{COMMENT}{SNLCMT}*|<MATRIX_START>{S}*{NL}{SNLCMT}*"); |
501 | 412 |
502 curr_lexer->scan_for_comments (yytext); | 413 curr_lexer->scan_for_comments (yytext); |
503 curr_lexer->fixup_column_count (yytext); | 414 curr_lexer->fixup_column_count (yytext); |
504 curr_lexer->eat_whitespace (); | 415 curr_lexer->eat_whitespace (); |
505 | 416 |
513 if (! curr_lexer->looking_at_object_index.front () | 424 if (! curr_lexer->looking_at_object_index.front () |
514 && curr_lexer->nesting_level.is_bracket_or_brace ()) | 425 && curr_lexer->nesting_level.is_bracket_or_brace ()) |
515 { | 426 { |
516 curr_lexer->maybe_warn_separator_insert (';'); | 427 curr_lexer->maybe_warn_separator_insert (';'); |
517 | 428 |
518 COUNT_TOK_AND_RETURN (';'); | 429 return curr_lexer->count_token (';'); |
519 } | 430 } |
520 } | 431 } |
521 | 432 |
522 \[{S}* { | 433 \[{S}* { |
523 LEXER_DEBUG ("\\[{S}*"); | 434 curr_lexer->lexer_debug ("\\[{S}*"); |
524 | 435 |
525 curr_lexer->nesting_level.bracket (); | 436 curr_lexer->nesting_level.bracket (); |
526 | 437 |
527 curr_lexer->looking_at_object_index.push_front (false); | 438 curr_lexer->looking_at_object_index.push_front (false); |
528 | 439 |
540 | 451 |
541 curr_lexer->decrement_promptflag (); | 452 curr_lexer->decrement_promptflag (); |
542 curr_lexer->eat_whitespace (); | 453 curr_lexer->eat_whitespace (); |
543 | 454 |
544 curr_lexer->bracketflag++; | 455 curr_lexer->bracketflag++; |
545 BEGIN (MATRIX_START); | 456 |
546 COUNT_TOK_AND_RETURN ('['); | 457 curr_lexer->push_start_state (MATRIX_START); |
458 | |
459 return curr_lexer->count_token ('['); | |
547 } | 460 } |
548 | 461 |
549 \] { | 462 \] { |
550 LEXER_DEBUG ("\\]"); | 463 curr_lexer->lexer_debug ("\\]"); |
551 | 464 |
552 curr_lexer->nesting_level.remove (); | 465 curr_lexer->nesting_level.remove (); |
553 | 466 |
554 curr_lexer->looking_at_object_index.pop_front (); | 467 curr_lexer->looking_at_object_index.pop_front (); |
555 | 468 |
556 curr_lexer->looking_for_object_index = true; | 469 curr_lexer->looking_for_object_index = true; |
557 curr_lexer->at_beginning_of_statement = false; | 470 curr_lexer->at_beginning_of_statement = false; |
558 | 471 |
559 TOK_RETURN (']'); | 472 return curr_lexer->handle_token (']'); |
473 } | |
474 | |
475 %{ | |
476 // Gobble comments. | |
477 %} | |
478 | |
479 %{ | |
480 // Start of a block comment. If the comment marker appears immediately | |
481 // after a block of full-line comments, finish the full line comment | |
482 // block. | |
483 %} | |
484 | |
485 ^{S}*{CCHAR}\{{S}*{NL} { | |
486 curr_lexer->lexer_debug ("^{S}*{CCHAR}\{{S}*{NL}"); | |
487 | |
488 int tok = 0; | |
489 | |
490 if (curr_lexer->start_state () == LINE_COMMENT_START) | |
491 { | |
492 if (! curr_lexer->comment_text.empty ()) | |
493 tok = curr_lexer->finish_comment (octave_comment_elt::full_line); | |
494 | |
495 curr_lexer->pop_start_state (); | |
496 } | |
497 | |
498 curr_lexer->push_start_state (BLOCK_COMMENT_START); | |
499 | |
500 yyless (0); | |
501 | |
502 if (tok > 0) | |
503 return curr_lexer->count_token (tok); | |
504 } | |
505 | |
506 <BLOCK_COMMENT_START>^{S}*{CCHAR}\{{S}*{NL} { | |
507 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>^{S}*{CCHAR}\{{S}*{NL}"); | |
508 | |
509 curr_lexer->input_line_number++; | |
510 curr_lexer->current_input_column = 1; | |
511 | |
512 if (curr_lexer->block_comment_nesting_level) | |
513 curr_lexer->comment_text = "\n"; | |
514 | |
515 curr_lexer->block_comment_nesting_level++; | |
516 } | |
517 | |
518 %{ | |
519 // End of a block comment. If this block comment is nested inside | |
520 // another, wait for the outermost block comment block to be closed | |
521 // before storing the comment. | |
522 %} | |
523 | |
524 <BLOCK_COMMENT_START>^{S}*{CCHAR}\}{S}*{NL} { | |
525 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>^{S}*{CCHAR}\\}{S}*{NL}"); | |
526 | |
527 curr_lexer->input_line_number++; | |
528 curr_lexer->current_input_column = 1; | |
529 | |
530 int tok = 0; | |
531 | |
532 if (curr_lexer->block_comment_nesting_level > 1) | |
533 curr_lexer->comment_text = "\n"; | |
534 else | |
535 tok = curr_lexer->finish_comment (octave_comment_elt::block); | |
536 | |
537 curr_lexer->block_comment_nesting_level--; | |
538 curr_lexer->pop_start_state (); | |
539 | |
540 if (tok > 0) | |
541 return curr_lexer->count_token (tok); | |
542 } | |
543 | |
544 %{ | |
545 // Body of a block comment. | |
546 %} | |
547 | |
548 <BLOCK_COMMENT_START>.*{NL} { | |
549 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>.*{NL}"); | |
550 | |
551 curr_lexer->input_line_number++; | |
552 curr_lexer->current_input_column = 1; | |
553 curr_lexer->comment_text += yytext; | |
554 } | |
555 | |
556 %{ | |
557 // Full-line or end-of-line comment. | |
558 %} | |
559 | |
560 {S}*{CCHAR}.*{NL} { | |
561 curr_lexer->lexer_debug ("{S}*{CCHAR}.*{NL}"); | |
562 | |
563 curr_lexer->push_start_state (LINE_COMMENT_START); | |
564 yyless (0); | |
565 } | |
566 | |
567 <LINE_COMMENT_START>{S}*{CCHAR}.*{NL} { | |
568 curr_lexer->lexer_debug ("<LINE_COMMENT_START>{S}*{CCHAR}.*{NL}"); | |
569 | |
570 bool full_line_comment = curr_lexer->current_input_column == 1; | |
571 curr_lexer->input_line_number++; | |
572 curr_lexer->current_input_column = 1; | |
573 | |
574 size_t len = yyleng; | |
575 size_t i = 0; | |
576 while (i < len) | |
577 { | |
578 char c = yytext[i]; | |
579 if (c == '#' || c == '%' || c == ' ' || c == '\t') | |
580 i++; | |
581 else | |
582 break; | |
583 } | |
584 | |
585 curr_lexer->comment_text += &yytext[i]; | |
586 | |
587 int tok = 0; | |
588 | |
589 if (! full_line_comment) | |
590 { | |
591 tok = curr_lexer->finish_comment (octave_comment_elt::end_of_line); | |
592 | |
593 curr_lexer->pop_start_state (); | |
594 | |
595 if (curr_lexer->start_state () == COMMAND_START) | |
596 { | |
597 // Allow the actions for the end of a COMMAND line to be | |
598 // executed next. | |
599 | |
600 tok = 0; | |
601 curr_lexer->xunput ('\n'); | |
602 } | |
603 } | |
604 | |
605 if (tok > 0) | |
606 return curr_lexer->count_token (tok); | |
607 } | |
608 | |
609 %{ | |
610 // End of a block of full-line comments. | |
611 %} | |
612 | |
613 <LINE_COMMENT_START>{ANY_INCLUDING_NL} { | |
614 curr_lexer->lexer_debug ("<LINE_COMMENT_START>{ANY_INCLUDING_NL}"); | |
615 | |
616 curr_lexer->xunput (yytext[0]); | |
617 | |
618 int tok = curr_lexer->finish_comment (octave_comment_elt::full_line); | |
619 | |
620 curr_lexer->pop_start_state (); | |
621 | |
622 if (tok > 0) | |
623 return curr_lexer->count_token (tok); | |
560 } | 624 } |
561 | 625 |
562 %{ | 626 %{ |
563 // Imaginary numbers. | 627 // Imaginary numbers. |
564 %} | 628 %} |
565 | 629 |
566 {NUMBER}{Im} { | 630 {NUMBER}{Im} { |
567 LEXER_DEBUG ("{NUMBER}{Im}"); | 631 curr_lexer->lexer_debug ("{NUMBER}{Im}"); |
568 | 632 |
569 curr_lexer->handle_number (); | 633 curr_lexer->handle_number (); |
570 COUNT_TOK_AND_RETURN (IMAG_NUM); | 634 return curr_lexer->count_token (IMAG_NUM); |
571 } | 635 } |
572 | 636 |
573 %{ | 637 %{ |
574 // Real numbers. Don't grab the '.' part of a dot operator as part of | 638 // Real numbers. Don't grab the '.' part of a dot operator as part of |
575 // the constant. | 639 // the constant. |
576 %} | 640 %} |
577 | 641 |
578 {D}+/\.[\*/\\^\'] | | 642 {D}+/\.[\*/\\^\'] | |
579 {NUMBER} { | 643 {NUMBER} { |
580 LEXER_DEBUG ("{D}+/\\.[\\*/\\^\\']|{NUMBER}"); | 644 curr_lexer->lexer_debug ("{D}+/\\.[\\*/\\^\\']|{NUMBER}"); |
581 curr_lexer->handle_number (); | 645 curr_lexer->handle_number (); |
582 COUNT_TOK_AND_RETURN (NUM); | 646 return curr_lexer->count_token (NUM); |
583 } | 647 } |
584 | 648 |
585 %{ | 649 %{ |
586 // Eat whitespace. Whitespace inside matrix constants is handled by | 650 // Eat whitespace. Whitespace inside matrix constants is handled by |
587 // the <MATRIX_START> start state code above. | 651 // the <MATRIX_START> start state code above. |
595 // Continuation lines. Allow comments after continuations. | 659 // Continuation lines. Allow comments after continuations. |
596 %} | 660 %} |
597 | 661 |
598 {CONT}{S}*{NL} | | 662 {CONT}{S}*{NL} | |
599 {CONT}{S}*{COMMENT} { | 663 {CONT}{S}*{COMMENT} { |
600 LEXER_DEBUG ("{CONT}{S}*{NL}|{CONT}{S}*{COMMENT}"); | 664 curr_lexer->lexer_debug ("{CONT}{S}*{NL}|{CONT}{S}*{COMMENT}"); |
601 | 665 |
602 if (yytext[0] == '\\') | 666 if (yytext[0] == '\\') |
603 curr_lexer->gripe_matlab_incompatible_continuation (); | 667 curr_lexer->gripe_matlab_incompatible_continuation (); |
604 curr_lexer->scan_for_comments (yytext); | 668 curr_lexer->scan_for_comments (yytext); |
605 curr_lexer->decrement_promptflag (); | 669 curr_lexer->decrement_promptflag (); |
619 // Identifiers. Truncate the token at the first space or tab but | 683 // Identifiers. Truncate the token at the first space or tab but |
620 // don't write directly on yytext. | 684 // don't write directly on yytext. |
621 %} | 685 %} |
622 | 686 |
623 {IDENT}{S}* { | 687 {IDENT}{S}* { |
624 LEXER_DEBUG ("{IDENT}{S}*"); | 688 curr_lexer->lexer_debug ("{IDENT}{S}*"); |
625 | 689 |
626 int id_tok = curr_lexer->handle_identifier (); | 690 int id_tok = curr_lexer->handle_identifier (); |
627 | 691 |
628 if (id_tok >= 0) | 692 if (id_tok >= 0) |
629 COUNT_TOK_AND_RETURN (id_tok); | 693 return curr_lexer->count_token (id_tok); |
630 } | 694 } |
631 | 695 |
632 %{ | 696 %{ |
633 // Superclass method identifiers. | 697 // Superclass method identifiers. |
634 %} | 698 %} |
635 | 699 |
636 {IDENT}@{IDENT}{S}* | | 700 {IDENT}@{IDENT}{S}* | |
637 {IDENT}@{IDENT}.{IDENT}{S}* { | 701 {IDENT}@{IDENT}.{IDENT}{S}* { |
638 LEXER_DEBUG ("{IDENT}@{IDENT}{S}*|{IDENT}@{IDENT}.{IDENT}{S}*"); | 702 curr_lexer->lexer_debug ("{IDENT}@{IDENT}{S}*|{IDENT}@{IDENT}.{IDENT}{S}*"); |
639 | 703 |
640 int id_tok = curr_lexer->handle_superclass_identifier (); | 704 int id_tok = curr_lexer->handle_superclass_identifier (); |
641 | 705 |
642 if (id_tok >= 0) | 706 if (id_tok >= 0) |
643 { | 707 { |
644 curr_lexer->looking_for_object_index = true; | 708 curr_lexer->looking_for_object_index = true; |
645 | 709 |
646 COUNT_TOK_AND_RETURN (id_tok); | 710 return curr_lexer->count_token (id_tok); |
647 } | 711 } |
648 } | 712 } |
649 | 713 |
650 %{ | 714 %{ |
651 // Metaclass query | 715 // Metaclass query |
652 %} | 716 %} |
653 | 717 |
654 \?{IDENT}{S}* | | 718 \?{IDENT}{S}* | |
655 \?{IDENT}\.{IDENT}{S}* { | 719 \?{IDENT}\.{IDENT}{S}* { |
656 LEXER_DEBUG ("\\?{IDENT}{S}*|\\?{IDENT}\\.{IDENT}{S}*"); | 720 curr_lexer->lexer_debug ("\\?{IDENT}{S}*|\\?{IDENT}\\.{IDENT}{S}*"); |
657 | 721 |
658 int id_tok = curr_lexer->handle_meta_identifier (); | 722 int id_tok = curr_lexer->handle_meta_identifier (); |
659 | 723 |
660 if (id_tok >= 0) | 724 if (id_tok >= 0) |
661 { | 725 { |
662 curr_lexer->looking_for_object_index = true; | 726 curr_lexer->looking_for_object_index = true; |
663 | 727 |
664 COUNT_TOK_AND_RETURN (id_tok); | 728 return curr_lexer->count_token (id_tok); |
665 } | 729 } |
666 } | 730 } |
667 | 731 |
668 %{ | 732 %{ |
669 // Function handles and superclass references | 733 // Function handles and superclass references |
670 %} | 734 %} |
671 | 735 |
672 "@" { | 736 "@" { |
673 LEXER_DEBUG ("@"); | 737 curr_lexer->lexer_debug ("@"); |
674 | 738 |
675 curr_lexer->current_input_column++; | 739 curr_lexer->current_input_column++; |
676 | 740 |
677 curr_lexer->quote_is_transpose = false; | 741 curr_lexer->quote_is_transpose = false; |
678 curr_lexer->convert_spaces_to_comma = false; | 742 curr_lexer->convert_spaces_to_comma = false; |
679 curr_lexer->looking_at_function_handle++; | 743 curr_lexer->looking_at_function_handle++; |
680 curr_lexer->looking_for_object_index = false; | 744 curr_lexer->looking_for_object_index = false; |
681 curr_lexer->at_beginning_of_statement = false; | 745 curr_lexer->at_beginning_of_statement = false; |
682 | 746 |
683 COUNT_TOK_AND_RETURN ('@'); | 747 return curr_lexer->count_token ('@'); |
684 | 748 |
685 } | 749 } |
686 | 750 |
687 %{ | 751 %{ |
688 // A new line character. New line characters inside matrix constants | 752 // A new line character. New line characters inside matrix constants |
689 // are handled by the <MATRIX_START> start state code above. If closest | 753 // are handled by the <MATRIX_START> start state code above. If closest |
690 // nesting is inside parentheses, don't return a row separator. | 754 // nesting is inside parentheses, don't return a row separator. |
691 %} | 755 %} |
692 | 756 |
693 {NL} { | 757 {NL} { |
694 LEXER_DEBUG ("{NL}"); | 758 curr_lexer->lexer_debug ("{NL}"); |
695 | 759 |
696 curr_lexer->input_line_number++; | 760 curr_lexer->input_line_number++; |
697 curr_lexer->current_input_column = 1; | 761 curr_lexer->current_input_column = 1; |
698 | 762 |
699 curr_lexer->quote_is_transpose = false; | 763 curr_lexer->quote_is_transpose = false; |
700 curr_lexer->convert_spaces_to_comma = true; | 764 curr_lexer->convert_spaces_to_comma = true; |
701 | 765 |
702 if (curr_lexer->nesting_level.none ()) | 766 if (curr_lexer->nesting_level.none ()) |
703 { | 767 { |
704 curr_lexer->at_beginning_of_statement = true; | 768 curr_lexer->at_beginning_of_statement = true; |
705 COUNT_TOK_AND_RETURN ('\n'); | 769 return curr_lexer->count_token ('\n'); |
706 } | 770 } |
707 else if (curr_lexer->nesting_level.is_paren ()) | 771 else if (curr_lexer->nesting_level.is_paren ()) |
708 { | 772 { |
709 curr_lexer->at_beginning_of_statement = false; | 773 curr_lexer->at_beginning_of_statement = false; |
710 curr_lexer->gripe_matlab_incompatible ("bare newline inside parentheses"); | 774 curr_lexer->gripe_matlab_incompatible ("bare newline inside parentheses"); |
717 // Single quote can either be the beginning of a string or a transpose | 781 // Single quote can either be the beginning of a string or a transpose |
718 // operator. | 782 // operator. |
719 %} | 783 %} |
720 | 784 |
721 "'" { | 785 "'" { |
722 LEXER_DEBUG ("'"); | 786 curr_lexer->lexer_debug ("'"); |
723 | 787 |
724 curr_lexer->current_input_column++; | 788 curr_lexer->current_input_column++; |
725 curr_lexer->convert_spaces_to_comma = true; | 789 curr_lexer->convert_spaces_to_comma = true; |
726 | 790 |
727 if (curr_lexer->quote_is_transpose) | 791 if (curr_lexer->quote_is_transpose) |
728 { | 792 { |
729 curr_lexer->do_comma_insert_check (); | 793 curr_lexer->do_comma_insert_check (); |
730 COUNT_TOK_AND_RETURN (QUOTE); | 794 return curr_lexer->count_token (QUOTE); |
731 } | 795 } |
732 else | 796 else |
733 { | 797 { |
734 int tok = curr_lexer->handle_string ('\''); | 798 int tok = curr_lexer->handle_string ('\''); |
735 COUNT_TOK_AND_RETURN (tok); | 799 return curr_lexer->count_token (tok); |
736 } | 800 } |
737 } | 801 } |
738 | 802 |
739 %{ | 803 %{ |
740 // Double quotes always begin strings. | 804 // Double quotes always begin strings. |
741 %} | 805 %} |
742 | 806 |
743 \" { | 807 \" { |
744 LEXER_DEBUG ("\""); | 808 curr_lexer->lexer_debug ("\""); |
745 | 809 |
746 curr_lexer->current_input_column++; | 810 curr_lexer->current_input_column++; |
747 int tok = curr_lexer->handle_string ('"'); | 811 int tok = curr_lexer->handle_string ('"'); |
748 | 812 |
749 COUNT_TOK_AND_RETURN (tok); | 813 return curr_lexer->count_token (tok); |
750 } | 814 } |
751 | |
752 %{ | |
753 // Gobble comments. | |
754 %} | |
755 | |
756 {CCHAR} { | |
757 LEXER_DEBUG ("{CCHAR}"); | |
758 | |
759 curr_lexer->looking_for_object_index = false; | |
760 | |
761 curr_lexer->xunput (yytext[0]); | |
762 | |
763 bool eof = false; | |
764 int tok = curr_lexer->process_comment (false, eof); | |
765 | |
766 if (eof) | |
767 return curr_lexer->handle_end_of_input (); | |
768 else if (tok > 0) | |
769 COUNT_TOK_AND_RETURN (tok); | |
770 } | |
771 | |
772 %{ | |
773 // Block comments. | |
774 %} | |
775 | |
776 ^{S}*{CCHAR}\{{S}*{NL} { | |
777 LEXER_DEBUG ("^{S}*{CCHAR}\\{{S}*{NL}"); | |
778 | |
779 curr_lexer->looking_for_object_index = false; | |
780 | |
781 curr_lexer->input_line_number++; | |
782 curr_lexer->current_input_column = 1; | |
783 curr_lexer->block_comment_nesting_level++; | |
784 curr_lexer->decrement_promptflag (); | |
785 | |
786 bool eof = false; | |
787 curr_lexer->process_comment (true, eof); | |
788 } | |
789 | 815 |
790 %{ | 816 %{ |
791 // Other operators. | 817 // Other operators. |
792 %} | 818 %} |
793 | 819 |
794 ":" { LEXER_DEBUG (":"); BIN_OP_RETURN (':', false, false); } | 820 ":" { return curr_lexer->handle_op (":", ':'); } |
795 | 821 ".+" { return curr_lexer->handle_incompatible_op (".+", EPLUS); } |
796 ".+" { LEXER_DEBUG (".+"); XBIN_OP_RETURN (EPLUS, false, false); } | 822 ".-" { return curr_lexer->handle_incompatible_op (".-", EMINUS); } |
797 ".-" { LEXER_DEBUG (".-"); XBIN_OP_RETURN (EMINUS, false, false); } | 823 ".*" { return curr_lexer->handle_op (".*", EMUL); } |
798 ".*" { LEXER_DEBUG (".*"); BIN_OP_RETURN (EMUL, false, false); } | 824 "./" { return curr_lexer->handle_op ("./", EDIV); } |
799 "./" { LEXER_DEBUG ("./"); BIN_OP_RETURN (EDIV, false, false); } | 825 ".\\" { return curr_lexer->handle_op (".\\", ELEFTDIV); } |
800 ".\\" { LEXER_DEBUG (".\\"); BIN_OP_RETURN (ELEFTDIV, false, false); } | 826 ".^" { return curr_lexer->handle_op (".^", EPOW); } |
801 ".^" { LEXER_DEBUG (".^"); BIN_OP_RETURN (EPOW, false, false); } | 827 ".**" { return curr_lexer->handle_incompatible_op (".**", EPOW); } |
802 ".**" { LEXER_DEBUG (".**"); XBIN_OP_RETURN (EPOW, false, false); } | 828 "<=" { return curr_lexer->handle_op ("<=", EXPR_LE); } |
803 ".'" { LEXER_DEBUG (".'"); curr_lexer->do_comma_insert_check (); BIN_OP_RETURN (TRANSPOSE, true, false); } | 829 "==" { return curr_lexer->handle_op ("==", EXPR_EQ); } |
804 "++" { LEXER_DEBUG ("++"); curr_lexer->do_comma_insert_check (); XBIN_OP_RETURN_INTERNAL (PLUS_PLUS, true, false, true); } | 830 "~=" { return curr_lexer->handle_op ("~=", EXPR_NE); } |
805 "--" { LEXER_DEBUG ("--"); curr_lexer->do_comma_insert_check (); XBIN_OP_RETURN_INTERNAL (MINUS_MINUS, true, false, true); } | 831 "!=" { return curr_lexer->handle_incompatible_op ("!=", EXPR_NE); } |
806 "<=" { LEXER_DEBUG ("<="); BIN_OP_RETURN (EXPR_LE, false, false); } | 832 ">=" { return curr_lexer->handle_op (">=", EXPR_GE); } |
807 "==" { LEXER_DEBUG ("=="); BIN_OP_RETURN (EXPR_EQ, false, false); } | 833 "&" { return curr_lexer->handle_op ("&", EXPR_AND); } |
808 "~=" { LEXER_DEBUG ("~="); BIN_OP_RETURN (EXPR_NE, false, false); } | 834 "|" { return curr_lexer->handle_op ("|", EXPR_OR); } |
809 "!=" { LEXER_DEBUG ("!="); XBIN_OP_RETURN (EXPR_NE, false, false); } | 835 "<" { return curr_lexer->handle_op ("<", EXPR_LT); } |
810 ">=" { LEXER_DEBUG (">="); BIN_OP_RETURN (EXPR_GE, false, false); } | 836 ">" { return curr_lexer->handle_op (">", EXPR_GT); } |
811 "&" { LEXER_DEBUG ("&"); BIN_OP_RETURN (EXPR_AND, false, false); } | 837 "+" { return curr_lexer->handle_op ("+", '+'); } |
812 "|" { LEXER_DEBUG ("|"); BIN_OP_RETURN (EXPR_OR, false, false); } | 838 "-" { return curr_lexer->handle_op ("-", '-'); } |
813 "<" { LEXER_DEBUG ("<"); BIN_OP_RETURN (EXPR_LT, false, false); } | 839 "*" { return curr_lexer->handle_op ("*", '*'); } |
814 ">" { LEXER_DEBUG (">"); BIN_OP_RETURN (EXPR_GT, false, false); } | 840 "/" { return curr_lexer->handle_op ("/", '/'); } |
815 "+" { LEXER_DEBUG ("+"); BIN_OP_RETURN ('+', false, false); } | 841 "\\" { return curr_lexer->handle_op ("\\", LEFTDIV); } |
816 "-" { LEXER_DEBUG ("-"); BIN_OP_RETURN ('-', false, false); } | 842 "^" { return curr_lexer->handle_op ("^", POW); } |
817 "*" { LEXER_DEBUG ("*"); BIN_OP_RETURN ('*', false, false); } | 843 "**" { return curr_lexer->handle_incompatible_op ("**", POW); } |
818 "/" { LEXER_DEBUG ("/"); BIN_OP_RETURN ('/', false, false); } | 844 "=" { return curr_lexer->handle_op ("=", '=', true, false); } |
819 "\\" { LEXER_DEBUG ("\\"); BIN_OP_RETURN (LEFTDIV, false, false); } | 845 "&&" { return curr_lexer->handle_op ("&&", EXPR_AND_AND); } |
820 ";" { LEXER_DEBUG (";"); BIN_OP_RETURN (';', true, true); } | 846 "||" { return curr_lexer->handle_op ("||", EXPR_OR_OR); } |
821 "," { LEXER_DEBUG (","); BIN_OP_RETURN (',', true, ! curr_lexer->looking_at_object_index.front ()); } | 847 "<<" { return curr_lexer->handle_incompatible_op ("<<", LSHIFT); } |
822 "^" { LEXER_DEBUG ("^"); BIN_OP_RETURN (POW, false, false); } | 848 ">>" { return curr_lexer->handle_incompatible_op (">>", RSHIFT); } |
823 "**" { LEXER_DEBUG ("**"); XBIN_OP_RETURN (POW, false, false); } | 849 "~" { return curr_lexer->handle_op ("~", EXPR_NOT); } |
824 "=" { LEXER_DEBUG ("="); BIN_OP_RETURN ('=', true, false); } | 850 "!" { return curr_lexer->handle_incompatible_op ("!", EXPR_NOT); } |
825 "&&" { LEXER_DEBUG ("&&"); BIN_OP_RETURN (EXPR_AND_AND, false, false); } | 851 ";" { return curr_lexer->handle_op (";", ';', true, true); } |
826 "||" { LEXER_DEBUG ("||"); BIN_OP_RETURN (EXPR_OR_OR, false, false); } | 852 |
827 "<<" { LEXER_DEBUG ("<<"); XBIN_OP_RETURN (LSHIFT, false, false); } | 853 "," { |
828 ">>" { LEXER_DEBUG (">>"); XBIN_OP_RETURN (RSHIFT, false, false); } | 854 return curr_lexer->handle_op |
829 | 855 (",", ',', true, ! curr_lexer->looking_at_object_index.front ()); |
830 {NOT} { | 856 } |
831 LEXER_DEBUG ("{NOT}"); | 857 |
832 | 858 ".'" { |
833 if (yytext[0] == '~') | 859 curr_lexer->do_comma_insert_check (); |
834 BIN_OP_RETURN (EXPR_NOT, false, false); | 860 return curr_lexer->handle_op (".'", TRANSPOSE, true, false); |
835 else | 861 } |
836 XBIN_OP_RETURN (EXPR_NOT, false, false); | 862 |
863 "++" { | |
864 curr_lexer->do_comma_insert_check (); | |
865 return curr_lexer->handle_incompatible_op | |
866 ("++", PLUS_PLUS, true, false, true); | |
867 } | |
868 | |
869 "--" { | |
870 ; | |
871 curr_lexer->do_comma_insert_check (); | |
872 return curr_lexer->handle_incompatible_op | |
873 ("--", MINUS_MINUS, true, false, true); | |
837 } | 874 } |
838 | 875 |
839 "(" { | 876 "(" { |
840 LEXER_DEBUG ("("); | 877 curr_lexer->lexer_debug ("("); |
841 | 878 |
842 // If we are looking for an object index, then push TRUE for | 879 // If we are looking for an object index, then push TRUE for |
843 // looking_at_object_index. Otherwise, just push whatever state | 880 // looking_at_object_index. Otherwise, just push whatever state |
844 // is current (so that we can pop it off the stack when we find | 881 // is current (so that we can pop it off the stack when we find |
845 // the matching close paren). | 882 // the matching close paren). |
852 curr_lexer->at_beginning_of_statement = false; | 889 curr_lexer->at_beginning_of_statement = false; |
853 | 890 |
854 curr_lexer->nesting_level.paren (); | 891 curr_lexer->nesting_level.paren (); |
855 curr_lexer->decrement_promptflag (); | 892 curr_lexer->decrement_promptflag (); |
856 | 893 |
857 TOK_RETURN ('('); | 894 return curr_lexer->handle_token ('('); |
858 } | 895 } |
859 | 896 |
860 ")" { | 897 ")" { |
861 LEXER_DEBUG (")"); | 898 curr_lexer->lexer_debug (")"); |
862 | 899 |
863 curr_lexer->nesting_level.remove (); | 900 curr_lexer->nesting_level.remove (); |
864 curr_lexer->current_input_column++; | 901 curr_lexer->current_input_column++; |
865 | 902 |
866 curr_lexer->looking_at_object_index.pop_front (); | 903 curr_lexer->looking_at_object_index.pop_front (); |
875 if (curr_lexer->looking_at_anon_fcn_args) | 912 if (curr_lexer->looking_at_anon_fcn_args) |
876 curr_lexer->looking_at_anon_fcn_args = false; | 913 curr_lexer->looking_at_anon_fcn_args = false; |
877 | 914 |
878 curr_lexer->do_comma_insert_check (); | 915 curr_lexer->do_comma_insert_check (); |
879 | 916 |
880 COUNT_TOK_AND_RETURN (')'); | 917 return curr_lexer->count_token (')'); |
881 } | 918 } |
882 | 919 |
883 "." { | 920 "." { |
884 LEXER_DEBUG ("."); | 921 curr_lexer->lexer_debug ("."); |
885 | 922 |
886 curr_lexer->looking_for_object_index = false; | 923 curr_lexer->looking_for_object_index = false; |
887 curr_lexer->at_beginning_of_statement = false; | 924 curr_lexer->at_beginning_of_statement = false; |
888 | 925 |
889 TOK_RETURN ('.'); | 926 return curr_lexer->handle_token ('.'); |
890 } | 927 } |
891 | 928 |
892 "+=" { LEXER_DEBUG ("+="); XBIN_OP_RETURN (ADD_EQ, false, false); } | 929 %{ |
893 "-=" { LEXER_DEBUG ("-="); XBIN_OP_RETURN (SUB_EQ, false, false); } | 930 // op= operators. |
894 "*=" { LEXER_DEBUG ("*="); XBIN_OP_RETURN (MUL_EQ, false, false); } | 931 %} |
895 "/=" { LEXER_DEBUG ("/="); XBIN_OP_RETURN (DIV_EQ, false, false); } | 932 |
896 "\\=" { LEXER_DEBUG ("\\="); XBIN_OP_RETURN (LEFTDIV_EQ, false, false); } | 933 "+=" { return curr_lexer->handle_incompatible_op ("+=", ADD_EQ); } |
897 ".+=" { LEXER_DEBUG (".+="); XBIN_OP_RETURN (ADD_EQ, false, false); } | 934 "-=" { return curr_lexer->handle_incompatible_op ("-=", SUB_EQ); } |
898 ".-=" { LEXER_DEBUG (".-="); XBIN_OP_RETURN (SUB_EQ, false, false); } | 935 "*=" { return curr_lexer->handle_incompatible_op ("*=", MUL_EQ); } |
899 ".*=" { LEXER_DEBUG (".*="); XBIN_OP_RETURN (EMUL_EQ, false, false); } | 936 "/=" { return curr_lexer->handle_incompatible_op ("/=", DIV_EQ); } |
900 "./=" { LEXER_DEBUG ("./="); XBIN_OP_RETURN (EDIV_EQ, false, false); } | 937 "\\=" { return curr_lexer->handle_incompatible_op ("\\=", LEFTDIV_EQ); } |
901 ".\\=" { LEXER_DEBUG (".\\="); XBIN_OP_RETURN (ELEFTDIV_EQ, false, false); } | 938 ".+=" { return curr_lexer->handle_incompatible_op (".+=", ADD_EQ); } |
902 {POW}= { LEXER_DEBUG ("{POW}="); XBIN_OP_RETURN (POW_EQ, false, false); } | 939 ".-=" { return curr_lexer->handle_incompatible_op (".-=", SUB_EQ); } |
903 {EPOW}= { LEXER_DEBUG ("{EPOW}="); XBIN_OP_RETURN (EPOW_EQ, false, false); } | 940 ".*=" { return curr_lexer->handle_incompatible_op (".*=", EMUL_EQ); } |
904 "&=" { LEXER_DEBUG ("&="); XBIN_OP_RETURN (AND_EQ, false, false); } | 941 "./=" { return curr_lexer->handle_incompatible_op ("./=", EDIV_EQ); } |
905 "|=" { LEXER_DEBUG ("|="); XBIN_OP_RETURN (OR_EQ, false, false); } | 942 ".\\=" { return curr_lexer->handle_incompatible_op (".\\=", ELEFTDIV_EQ); } |
906 "<<=" { LEXER_DEBUG ("<<="); XBIN_OP_RETURN (LSHIFT_EQ, false, false); } | 943 "^=" { return curr_lexer->handle_incompatible_op ("^=", POW_EQ); } |
907 ">>=" { LEXER_DEBUG (">>="); XBIN_OP_RETURN (RSHIFT_EQ, false, false); } | 944 "**=" { return curr_lexer->handle_incompatible_op ("^=", POW_EQ); } |
945 ".^=" { return curr_lexer->handle_incompatible_op (".^=", EPOW_EQ); } | |
946 ".**=" { return curr_lexer->handle_incompatible_op (".^=", EPOW_EQ); } | |
947 "&=" { return curr_lexer->handle_incompatible_op ("&=", AND_EQ); } | |
948 "|=" { return curr_lexer->handle_incompatible_op ("|=", OR_EQ); } | |
949 "<<=" { return curr_lexer->handle_incompatible_op ("<<=", LSHIFT_EQ); } | |
950 ">>=" { return curr_lexer->handle_incompatible_op (">>=", RSHIFT_EQ); } | |
908 | 951 |
909 \{{S}* { | 952 \{{S}* { |
910 LEXER_DEBUG ("\\{{S}*"); | 953 curr_lexer->lexer_debug ("\\{{S}*"); |
911 | 954 |
912 curr_lexer->nesting_level.brace (); | 955 curr_lexer->nesting_level.brace (); |
913 | 956 |
914 curr_lexer->looking_at_object_index.push_front | 957 curr_lexer->looking_at_object_index.push_front |
915 (curr_lexer->looking_for_object_index); | 958 (curr_lexer->looking_for_object_index); |
922 | 965 |
923 curr_lexer->decrement_promptflag (); | 966 curr_lexer->decrement_promptflag (); |
924 curr_lexer->eat_whitespace (); | 967 curr_lexer->eat_whitespace (); |
925 | 968 |
926 curr_lexer->braceflag++; | 969 curr_lexer->braceflag++; |
927 BEGIN (MATRIX_START); | 970 |
928 COUNT_TOK_AND_RETURN ('{'); | 971 curr_lexer->push_start_state (MATRIX_START); |
972 | |
973 return curr_lexer->count_token ('{'); | |
929 } | 974 } |
930 | 975 |
931 "}" { | 976 "}" { |
932 LEXER_DEBUG ("}"); | 977 curr_lexer->lexer_debug ("}"); |
933 | 978 |
934 curr_lexer->looking_at_object_index.pop_front (); | 979 curr_lexer->looking_at_object_index.pop_front (); |
935 | 980 |
936 curr_lexer->looking_for_object_index = true; | 981 curr_lexer->looking_for_object_index = true; |
937 curr_lexer->at_beginning_of_statement = false; | 982 curr_lexer->at_beginning_of_statement = false; |
938 | 983 |
939 curr_lexer->nesting_level.remove (); | 984 curr_lexer->nesting_level.remove (); |
940 | 985 |
941 TOK_RETURN ('}'); | 986 return curr_lexer->handle_token ('}'); |
942 } | 987 } |
943 | 988 |
944 %{ | 989 %{ |
945 // Unrecognized input is a lexical error. | 990 // Unrecognized input is a lexical error. |
946 %} | 991 %} |
947 | 992 |
948 . { | 993 . { |
949 LEXER_DEBUG ("."); | 994 curr_lexer->lexer_debug ("."); |
950 | 995 |
951 curr_lexer->xunput (yytext[0]); | 996 curr_lexer->xunput (yytext[0]); |
952 | 997 |
953 int c = curr_lexer->text_yyinput (); | 998 int c = curr_lexer->text_yyinput (); |
954 | 999 |
1292 char *buf; | 1337 char *buf; |
1293 }; | 1338 }; |
1294 | 1339 |
1295 lexical_feedback::~lexical_feedback (void) | 1340 lexical_feedback::~lexical_feedback (void) |
1296 { | 1341 { |
1297 reset_token_stack (); | 1342 tokens.clear (); |
1298 } | 1343 } |
1299 | 1344 |
1300 void | 1345 void |
1301 lexical_feedback::init (void) | 1346 lexical_feedback::init (void) |
1302 { | 1347 { |
1338 defining_func = 0; | 1383 defining_func = 0; |
1339 looking_at_function_handle = 0; | 1384 looking_at_function_handle = 0; |
1340 block_comment_nesting_level = 0; | 1385 block_comment_nesting_level = 0; |
1341 token_count = 0; | 1386 token_count = 0; |
1342 current_input_line = ""; | 1387 current_input_line = ""; |
1388 comment_text = ""; | |
1343 help_text = ""; | 1389 help_text = ""; |
1344 fcn_file_name = ""; | 1390 fcn_file_name = ""; |
1345 fcn_file_full_name = ""; | 1391 fcn_file_full_name = ""; |
1346 looking_at_object_index.clear (); | 1392 looking_at_object_index.clear (); |
1347 looking_at_object_index.push_front (false); | 1393 looking_at_object_index.push_front (false); |
1351 | 1397 |
1352 pending_local_variables.clear (); | 1398 pending_local_variables.clear (); |
1353 | 1399 |
1354 nesting_level.reset (); | 1400 nesting_level.reset (); |
1355 | 1401 |
1356 reset_token_stack (); | 1402 tokens.clear (); |
1357 } | 1403 } |
1358 | 1404 |
1359 void | 1405 static bool |
1360 lexical_feedback::reset_token_stack (void) | 1406 looks_like_copyright (const std::string& s) |
1361 { | 1407 { |
1362 // Clear out the stack of token info used to track line and | 1408 bool retval = false; |
1363 // column numbers. | 1409 |
1364 | 1410 if (! s.empty ()) |
1365 while (! token_stack.empty ()) | 1411 { |
1366 { | 1412 size_t offset = s.find_first_not_of (" \t"); |
1367 delete token_stack.top (); | 1413 |
1368 token_stack.pop (); | 1414 retval = (s.substr (offset, 9) == "Copyright" || s.substr (offset, 6) == "Author"); |
1369 } | 1415 } |
1416 | |
1417 return retval; | |
1418 } | |
1419 | |
1420 int | |
1421 lexical_feedback::finish_comment (octave_comment_elt::comment_type typ) | |
1422 { | |
1423 bool copyright = looks_like_copyright (comment_text); | |
1424 | |
1425 if (nesting_level.none () && help_text.empty () | |
1426 && ! comment_text.empty () && ! copyright) | |
1427 help_text = comment_text; | |
1428 | |
1429 if (copyright) | |
1430 typ = octave_comment_elt::copyright; | |
1431 | |
1432 octave_comment_buffer::append (comment_text, typ); | |
1433 | |
1434 comment_text = ""; | |
1435 | |
1436 quote_is_transpose = false; | |
1437 convert_spaces_to_comma = true; | |
1438 at_beginning_of_statement = true; | |
1439 | |
1440 if (nesting_level.none ()) | |
1441 return '\n'; | |
1442 else if (nesting_level.is_bracket_or_brace ()) | |
1443 // FIXME -- this result will be different if the comment follows a | |
1444 // continuation token. | |
1445 return ';'; | |
1446 else | |
1447 return 0; | |
1370 } | 1448 } |
1371 | 1449 |
1372 void | 1450 void |
1373 octave_lexer::input_buffer::fill (const std::string& input, bool eof_arg) | 1451 octave_lexer::input_buffer::fill (const std::string& input, bool eof_arg) |
1374 { | 1452 { |
1424 yylex_init (&scanner); | 1502 yylex_init (&scanner); |
1425 | 1503 |
1426 // Make octave_lexer object available through yyextra in | 1504 // Make octave_lexer object available through yyextra in |
1427 // flex-generated lexer. | 1505 // flex-generated lexer. |
1428 yyset_extra (this, scanner); | 1506 yyset_extra (this, scanner); |
1507 | |
1508 clear_start_state (); | |
1429 } | 1509 } |
1430 | 1510 |
1431 // Inside Flex-generated functions, yyg is the scanner cast to its real | 1511 // Inside Flex-generated functions, yyg is the scanner cast to its real |
1432 // type. The BEGIN macro uses yyg and we want to use that in | 1512 // type. Some flex macros that we use in octave_lexer member functions |
1433 // octave_lexer member functions. If we could set the start state | 1513 // (for example, BEGIN) use yyg. If we could perform the actions of |
1434 // by calling a function instead of using the BEGIN macro, we could | 1514 // these macros with functions instead, we could eliminate the |
1435 // eliminate the OCTAVE_YYG macro. | 1515 // OCTAVE_YYG macro. |
1436 | 1516 |
1437 #define OCTAVE_YYG \ | 1517 #define OCTAVE_YYG \ |
1438 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner) | 1518 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner) |
1439 | 1519 |
1440 void | 1520 void |
1441 octave_lexer::reset (void) | 1521 octave_lexer::reset (void) |
1442 { | 1522 { |
1443 OCTAVE_YYG; | |
1444 | |
1445 // Start off on the right foot. | 1523 // Start off on the right foot. |
1446 BEGIN (INITIAL); | 1524 clear_start_state (); |
1447 | 1525 |
1448 parser_symtab_context.clear (); | 1526 parser_symtab_context.clear (); |
1449 | 1527 |
1450 // We do want a prompt by default. | 1528 // We do want a prompt by default. |
1451 promptflag (1); | 1529 promptflag (1); |
1467 } | 1545 } |
1468 | 1546 |
1469 void | 1547 void |
1470 octave_lexer::prep_for_file (void) | 1548 octave_lexer::prep_for_file (void) |
1471 { | 1549 { |
1472 OCTAVE_YYG; | 1550 reading_script_file = true; |
1473 | 1551 |
1474 BEGIN (INPUT_FILE_BEGIN); | 1552 push_start_state (INPUT_FILE_START); |
1475 } | 1553 } |
1476 | 1554 |
1477 int | 1555 int |
1478 octave_lexer::read (char *buf, unsigned max_size) | 1556 octave_lexer::read (char *buf, unsigned max_size) |
1479 { | 1557 { |
1500 } | 1578 } |
1501 | 1579 |
1502 int | 1580 int |
1503 octave_lexer::handle_end_of_input (void) | 1581 octave_lexer::handle_end_of_input (void) |
1504 { | 1582 { |
1505 // FIXME -- we need this because of the way TOK_RETURN is defined. DO | 1583 lexer_debug ("<<EOF>>"); |
1506 // something better than that... | |
1507 OCTAVE_YYG; | |
1508 | |
1509 LEXER_DEBUG ("<<EOF>>"); | |
1510 | 1584 |
1511 if (block_comment_nesting_level != 0) | 1585 if (block_comment_nesting_level != 0) |
1512 { | 1586 { |
1513 warning ("block comment open at end of input"); | 1587 warning ("block comment open at end of input"); |
1514 | 1588 |
1516 && ! fcn_file_name.empty ()) | 1590 && ! fcn_file_name.empty ()) |
1517 warning ("near line %d of file '%s.m'", | 1591 warning ("near line %d of file '%s.m'", |
1518 input_line_number, fcn_file_name.c_str ()); | 1592 input_line_number, fcn_file_name.c_str ()); |
1519 } | 1593 } |
1520 | 1594 |
1521 TOK_RETURN (END_OF_INPUT); | 1595 return handle_token (END_OF_INPUT); |
1522 } | 1596 } |
1523 | 1597 |
1524 char * | 1598 char * |
1525 octave_lexer::flex_yytext (void) | 1599 octave_lexer::flex_yytext (void) |
1526 { | 1600 { |
1889 octave_lexer::is_variable (const std::string& name) | 1963 octave_lexer::is_variable (const std::string& name) |
1890 { | 1964 { |
1891 return (symbol_table::is_variable (name) | 1965 return (symbol_table::is_variable (name) |
1892 || (pending_local_variables.find (name) | 1966 || (pending_local_variables.find (name) |
1893 != pending_local_variables.end ())); | 1967 != pending_local_variables.end ())); |
1894 } | |
1895 | |
1896 std::string | |
1897 octave_lexer::grab_block_comment (stream_reader& reader, bool& eof) | |
1898 { | |
1899 std::string buf; | |
1900 | |
1901 bool at_bol = true; | |
1902 bool look_for_marker = false; | |
1903 | |
1904 bool warned_incompatible = false; | |
1905 | |
1906 int c = 0; | |
1907 | |
1908 while ((c = reader.getc ()) != EOF) | |
1909 { | |
1910 current_input_column++; | |
1911 | |
1912 if (look_for_marker) | |
1913 { | |
1914 at_bol = false; | |
1915 look_for_marker = false; | |
1916 | |
1917 if (c == '{' || c == '}') | |
1918 { | |
1919 std::string tmp_buf (1, static_cast<char> (c)); | |
1920 | |
1921 int type = c; | |
1922 | |
1923 bool done = false; | |
1924 | |
1925 while ((c = reader.getc ()) != EOF && ! done) | |
1926 { | |
1927 current_input_column++; | |
1928 | |
1929 switch (c) | |
1930 { | |
1931 case ' ': | |
1932 case '\t': | |
1933 tmp_buf += static_cast<char> (c); | |
1934 break; | |
1935 | |
1936 case '\n': | |
1937 { | |
1938 current_input_column = 0; | |
1939 at_bol = true; | |
1940 done = true; | |
1941 | |
1942 if (type == '{') | |
1943 { | |
1944 block_comment_nesting_level++; | |
1945 decrement_promptflag (); | |
1946 } | |
1947 else | |
1948 { | |
1949 block_comment_nesting_level--; | |
1950 increment_promptflag (); | |
1951 | |
1952 if (block_comment_nesting_level == 0) | |
1953 { | |
1954 buf += grab_comment_block (reader, true, eof); | |
1955 | |
1956 return buf; | |
1957 } | |
1958 } | |
1959 } | |
1960 break; | |
1961 | |
1962 default: | |
1963 at_bol = false; | |
1964 tmp_buf += static_cast<char> (c); | |
1965 buf += tmp_buf; | |
1966 done = true; | |
1967 break; | |
1968 } | |
1969 } | |
1970 } | |
1971 } | |
1972 | |
1973 if (at_bol && (c == '%' || c == '#')) | |
1974 { | |
1975 if (c == '#' && ! warned_incompatible) | |
1976 { | |
1977 warned_incompatible = true; | |
1978 maybe_gripe_matlab_incompatible_comment (c); | |
1979 } | |
1980 | |
1981 at_bol = false; | |
1982 look_for_marker = true; | |
1983 } | |
1984 else | |
1985 { | |
1986 buf += static_cast<char> (c); | |
1987 | |
1988 if (c == '\n') | |
1989 { | |
1990 current_input_column = 0; | |
1991 at_bol = true; | |
1992 } | |
1993 } | |
1994 } | |
1995 | |
1996 if (c == EOF) | |
1997 eof = true; | |
1998 | |
1999 return buf; | |
2000 } | |
2001 | |
2002 std::string | |
2003 octave_lexer::grab_comment_block (stream_reader& reader, bool at_bol, | |
2004 bool& eof) | |
2005 { | |
2006 std::string buf; | |
2007 | |
2008 // TRUE means we are at the beginning of a comment block. | |
2009 bool begin_comment = false; | |
2010 | |
2011 // TRUE means we are currently reading a comment block. | |
2012 bool in_comment = false; | |
2013 | |
2014 bool warned_incompatible = false; | |
2015 | |
2016 int c = 0; | |
2017 | |
2018 while ((c = reader.getc ()) != EOF) | |
2019 { | |
2020 current_input_column++; | |
2021 | |
2022 if (begin_comment) | |
2023 { | |
2024 if (c == '%' || c == '#') | |
2025 { | |
2026 at_bol = false; | |
2027 continue; | |
2028 } | |
2029 else if (at_bol && c == '{') | |
2030 { | |
2031 std::string tmp_buf (1, static_cast<char> (c)); | |
2032 | |
2033 bool done = false; | |
2034 | |
2035 while ((c = reader.getc ()) != EOF && ! done) | |
2036 { | |
2037 current_input_column++; | |
2038 | |
2039 switch (c) | |
2040 { | |
2041 case ' ': | |
2042 case '\t': | |
2043 tmp_buf += static_cast<char> (c); | |
2044 break; | |
2045 | |
2046 case '\n': | |
2047 { | |
2048 current_input_column = 0; | |
2049 at_bol = true; | |
2050 done = true; | |
2051 | |
2052 block_comment_nesting_level++; | |
2053 decrement_promptflag (); | |
2054 | |
2055 buf += grab_block_comment (reader, eof); | |
2056 | |
2057 in_comment = false; | |
2058 | |
2059 if (eof) | |
2060 goto done; | |
2061 } | |
2062 break; | |
2063 | |
2064 default: | |
2065 at_bol = false; | |
2066 tmp_buf += static_cast<char> (c); | |
2067 buf += tmp_buf; | |
2068 done = true; | |
2069 break; | |
2070 } | |
2071 } | |
2072 } | |
2073 else | |
2074 { | |
2075 at_bol = false; | |
2076 begin_comment = false; | |
2077 } | |
2078 } | |
2079 | |
2080 if (in_comment) | |
2081 { | |
2082 buf += static_cast<char> (c); | |
2083 | |
2084 if (c == '\n') | |
2085 { | |
2086 at_bol = true; | |
2087 current_input_column = 0; | |
2088 in_comment = false; | |
2089 | |
2090 // FIXME -- bailing out here prevents things like | |
2091 // | |
2092 // octave> # comment | |
2093 // octave> x = 1 | |
2094 // | |
2095 // from failing at the command line, while still | |
2096 // allowing blocks of comments to be grabbed properly | |
2097 // for function doc strings. But only the first line of | |
2098 // a mult-line doc string will be picked up for | |
2099 // functions defined on the command line. We need a | |
2100 // better way of collecting these comments... | |
2101 if (! (reading_fcn_file || reading_script_file)) | |
2102 goto done; | |
2103 } | |
2104 } | |
2105 else | |
2106 { | |
2107 switch (c) | |
2108 { | |
2109 case ' ': | |
2110 case '\t': | |
2111 break; | |
2112 | |
2113 case '#': | |
2114 if (! warned_incompatible) | |
2115 { | |
2116 warned_incompatible = true; | |
2117 maybe_gripe_matlab_incompatible_comment (c); | |
2118 } | |
2119 // fall through... | |
2120 | |
2121 case '%': | |
2122 in_comment = true; | |
2123 begin_comment = true; | |
2124 break; | |
2125 | |
2126 default: | |
2127 current_input_column--; | |
2128 reader.ungetc (c); | |
2129 goto done; | |
2130 } | |
2131 } | |
2132 } | |
2133 | |
2134 done: | |
2135 | |
2136 if (c == EOF) | |
2137 eof = true; | |
2138 | |
2139 return buf; | |
2140 } | |
2141 | |
2142 static bool | |
2143 looks_like_copyright (const std::string& s) | |
2144 { | |
2145 bool retval = false; | |
2146 | |
2147 if (! s.empty ()) | |
2148 { | |
2149 size_t offset = s.find_first_not_of (" \t"); | |
2150 | |
2151 retval = (s.substr (offset, 9) == "Copyright" || s.substr (offset, 6) == "Author"); | |
2152 } | |
2153 | |
2154 return retval; | |
2155 } | |
2156 | |
2157 int | |
2158 octave_lexer::process_comment (bool start_in_block, bool& eof) | |
2159 { | |
2160 OCTAVE_YYG; | |
2161 | |
2162 eof = false; | |
2163 | |
2164 char *yytxt = flex_yytext (); | |
2165 flex_stream_reader flex_reader (this, yytxt); | |
2166 | |
2167 // process_comment is only supposed to be called when we are not | |
2168 // initially looking at a block comment. | |
2169 | |
2170 std::string txt = start_in_block | |
2171 ? grab_block_comment (flex_reader, eof) | |
2172 : grab_comment_block (flex_reader, false, eof); | |
2173 | |
2174 if (lexer_debug_flag) | |
2175 std::cerr << "C: " << txt << std::endl; | |
2176 | |
2177 if (nesting_level.none () && help_text.empty () && ! txt.empty () | |
2178 && ! looks_like_copyright (txt)) | |
2179 help_text = txt; | |
2180 | |
2181 octave_comment_buffer::append (txt); | |
2182 | |
2183 current_input_column = 1; | |
2184 quote_is_transpose = false; | |
2185 convert_spaces_to_comma = true; | |
2186 at_beginning_of_statement = true; | |
2187 | |
2188 if (YY_START == COMMAND_START) | |
2189 BEGIN (INITIAL); | |
2190 | |
2191 if (nesting_level.none ()) | |
2192 return '\n'; | |
2193 else if (nesting_level.is_bracket_or_brace ()) | |
2194 return ';'; | |
2195 else | |
2196 return 0; | |
2197 } | 1968 } |
2198 | 1969 |
2199 // Recognize separators. If the separator is a CRLF pair, it is | 1970 // Recognize separators. If the separator is a CRLF pair, it is |
2200 // replaced by a single LF. | 1971 // replaced by a single LF. |
2201 | 1972 |
2910 } | 2681 } |
2911 | 2682 |
2912 int | 2683 int |
2913 octave_lexer::handle_close_bracket (bool spc_gobbled, int bracket_type) | 2684 octave_lexer::handle_close_bracket (bool spc_gobbled, int bracket_type) |
2914 { | 2685 { |
2915 OCTAVE_YYG; | |
2916 | |
2917 int retval = bracket_type; | 2686 int retval = bracket_type; |
2918 | 2687 |
2919 if (! nesting_level.none ()) | 2688 if (! nesting_level.none ()) |
2920 { | 2689 { |
2921 nesting_level.remove (); | 2690 nesting_level.remove (); |
2926 braceflag--; | 2695 braceflag--; |
2927 else | 2696 else |
2928 panic_impossible (); | 2697 panic_impossible (); |
2929 } | 2698 } |
2930 | 2699 |
2931 if (bracketflag == 0 && braceflag == 0) | 2700 pop_start_state (); |
2932 BEGIN (INITIAL); | |
2933 | 2701 |
2934 if (bracket_type == ']' | 2702 if (bracket_type == ']' |
2935 && next_token_is_assign_op () | 2703 && next_token_is_assign_op () |
2936 && ! looking_at_return_list) | 2704 && ! looking_at_return_list) |
2937 { | 2705 { |
3364 // should be ignored. | 3132 // should be ignored. |
3365 | 3133 |
3366 int | 3134 int |
3367 octave_lexer::handle_identifier (void) | 3135 octave_lexer::handle_identifier (void) |
3368 { | 3136 { |
3369 OCTAVE_YYG; | |
3370 | |
3371 bool at_bos = at_beginning_of_statement; | 3137 bool at_bos = at_beginning_of_statement; |
3372 | 3138 |
3373 char *yytxt = flex_yytext (); | 3139 char *yytxt = flex_yytext (); |
3374 | 3140 |
3375 std::string tok = strip_trailing_whitespace (yytxt); | 3141 std::string tok = strip_trailing_whitespace (yytxt); |
3483 if (! is_variable (tok)) | 3249 if (! is_variable (tok)) |
3484 { | 3250 { |
3485 if (at_bos && spc_gobbled && can_be_command (tok) | 3251 if (at_bos && spc_gobbled && can_be_command (tok) |
3486 && looks_like_command_arg ()) | 3252 && looks_like_command_arg ()) |
3487 { | 3253 { |
3488 BEGIN (COMMAND_START); | 3254 push_start_state (COMMAND_START); |
3489 } | 3255 } |
3490 else if (next_tok_is_eq | 3256 else if (next_tok_is_eq |
3491 || looking_at_decl_list | 3257 || looking_at_decl_list |
3492 || looking_at_return_list | 3258 || looking_at_return_list |
3493 || (looking_at_parameter_list | 3259 || (looking_at_parameter_list |
3513 // After seeing an identifer, it is ok to convert spaces to a comma | 3279 // After seeing an identifer, it is ok to convert spaces to a comma |
3514 // (if needed). | 3280 // (if needed). |
3515 | 3281 |
3516 convert_spaces_to_comma = true; | 3282 convert_spaces_to_comma = true; |
3517 | 3283 |
3518 if (! (next_tok_is_eq || YY_START == COMMAND_START)) | 3284 if (! (next_tok_is_eq || start_state () == COMMAND_START)) |
3519 { | 3285 { |
3520 quote_is_transpose = true; | 3286 quote_is_transpose = true; |
3521 | 3287 |
3522 do_comma_insert_check (); | 3288 do_comma_insert_check (); |
3523 | 3289 |
3603 void | 3369 void |
3604 octave_lexer::push_token (token *tok) | 3370 octave_lexer::push_token (token *tok) |
3605 { | 3371 { |
3606 YYSTYPE *lval = yyget_lval (scanner); | 3372 YYSTYPE *lval = yyget_lval (scanner); |
3607 lval->tok_val = tok; | 3373 lval->tok_val = tok; |
3608 token_stack.push (tok); | 3374 tokens.push (tok); |
3609 } | 3375 } |
3610 | 3376 |
3611 token * | 3377 token * |
3612 octave_lexer::current_token (void) | 3378 octave_lexer::current_token (void) |
3613 { | 3379 { |
3750 } | 3516 } |
3751 break; | 3517 break; |
3752 } | 3518 } |
3753 } | 3519 } |
3754 | 3520 |
3755 static void | 3521 void |
3756 display_state (int state) | 3522 octave_lexer::fatal_error (const char *msg) |
3523 { | |
3524 error (msg); | |
3525 | |
3526 OCTAVE_QUIT; | |
3527 | |
3528 yy_fatal_error (msg, scanner); | |
3529 } | |
3530 | |
3531 void | |
3532 octave_lexer::lexer_debug (const char *pattern) | |
3533 { | |
3534 if (lexer_debug_flag) | |
3535 { | |
3536 std::cerr << std::endl; | |
3537 | |
3538 display_start_state (); | |
3539 | |
3540 std::cerr << "P: " << pattern << std::endl; | |
3541 std::cerr << "T: " << flex_yytext () << std::endl; | |
3542 } | |
3543 } | |
3544 | |
3545 void | |
3546 octave_lexer::push_start_state (int state) | |
3547 { | |
3548 OCTAVE_YYG; | |
3549 | |
3550 start_state_stack.push (state); | |
3551 | |
3552 BEGIN (start_state ()); | |
3553 } | |
3554 | |
3555 void | |
3556 octave_lexer::pop_start_state (void) | |
3557 { | |
3558 OCTAVE_YYG; | |
3559 | |
3560 start_state_stack.pop (); | |
3561 | |
3562 BEGIN (start_state ()); | |
3563 } | |
3564 | |
3565 void | |
3566 octave_lexer::clear_start_state (void) | |
3567 { | |
3568 while (! start_state_stack.empty ()) | |
3569 start_state_stack.pop (); | |
3570 | |
3571 push_start_state (INITIAL); | |
3572 } | |
3573 | |
3574 void | |
3575 octave_lexer::display_start_state (void) const | |
3757 { | 3576 { |
3758 std::cerr << "S: "; | 3577 std::cerr << "S: "; |
3759 | 3578 |
3760 switch (state) | 3579 switch (start_state ()) |
3761 { | 3580 { |
3762 case INITIAL: | 3581 case INITIAL: |
3763 std::cerr << "INITIAL" << std::endl; | 3582 std::cerr << "INITIAL" << std::endl; |
3764 break; | 3583 break; |
3765 | 3584 |
3769 | 3588 |
3770 case MATRIX_START: | 3589 case MATRIX_START: |
3771 std::cerr << "MATRIX_START" << std::endl; | 3590 std::cerr << "MATRIX_START" << std::endl; |
3772 break; | 3591 break; |
3773 | 3592 |
3774 case INPUT_FILE_BEGIN: | 3593 case INPUT_FILE_START: |
3775 std::cerr << "INPUT_FILE_BEGIN" << std::endl; | 3594 std::cerr << "INPUT_FILE_BEGIN" << std::endl; |
3595 break; | |
3596 | |
3597 case BLOCK_COMMENT_START: | |
3598 std::cerr << "BLOCK_COMMENT_START" << std::endl; | |
3599 break; | |
3600 | |
3601 case LINE_COMMENT_START: | |
3602 std::cerr << "LINE_COMMENT_START" << std::endl; | |
3776 break; | 3603 break; |
3777 | 3604 |
3778 default: | 3605 default: |
3779 std::cerr << "UNKNOWN START STATE!" << std::endl; | 3606 std::cerr << "UNKNOWN START STATE!" << std::endl; |
3780 break; | 3607 break; |
3781 } | 3608 } |
3782 } | 3609 } |
3783 | 3610 |
3784 void | 3611 int |
3785 octave_lexer::fatal_error (const char *msg) | 3612 octave_lexer::handle_op (const char *pattern, int tok, bool convert, |
3786 { | 3613 bool bos, bool qit) |
3787 error (msg); | 3614 { |
3788 | 3615 return handle_op_internal (pattern, tok, convert, bos, qit, true); |
3789 OCTAVE_QUIT; | 3616 } |
3790 | 3617 |
3791 yy_fatal_error (msg, scanner); | 3618 int |
3792 } | 3619 octave_lexer::handle_incompatible_op (const char *pattern, int tok, |
3793 | 3620 bool convert, bool bos, bool qit) |
3794 void | 3621 { |
3795 octave_lexer::lexer_debug (const char *pattern, const char *text) | 3622 return handle_op_internal (pattern, tok, convert, bos, qit, false); |
3796 { | 3623 } |
3797 OCTAVE_YYG; | 3624 |
3798 | 3625 int |
3799 std::cerr << std::endl; | 3626 octave_lexer::handle_op_internal (const char *pattern, int tok, bool convert, |
3800 | 3627 bool bos, bool qit, bool compat) |
3801 display_state (YY_START); | 3628 { |
3802 | 3629 lexer_debug (pattern); |
3803 std::cerr << "P: " << pattern << std::endl; | 3630 |
3804 std::cerr << "T: " << text << std::endl; | 3631 if (! compat) |
3805 } | 3632 gripe_matlab_incompatible_operator (flex_yytext ()); |
3633 | |
3634 push_token (new token (input_line_number, current_input_column)); | |
3635 | |
3636 current_input_column += flex_yyleng (); | |
3637 quote_is_transpose = qit; | |
3638 convert_spaces_to_comma = convert; | |
3639 looking_for_object_index = false; | |
3640 at_beginning_of_statement = bos; | |
3641 | |
3642 return count_token (tok); | |
3643 } | |
3644 | |
3645 int | |
3646 octave_lexer::handle_token (const std::string& name, int tok) | |
3647 { | |
3648 token *tok_val = new token (name, input_line_number, current_input_column); | |
3649 | |
3650 return handle_token (tok, tok_val); | |
3651 } | |
3652 | |
3653 int | |
3654 octave_lexer::handle_token (int tok, token *tok_val) | |
3655 { | |
3656 if (! tok_val) | |
3657 tok_val = new token (input_line_number, current_input_column); | |
3658 | |
3659 push_token (tok_val); | |
3660 | |
3661 current_input_column += flex_yyleng (); | |
3662 quote_is_transpose = false; | |
3663 convert_spaces_to_comma = true; | |
3664 | |
3665 return count_token (tok); | |
3666 } | |
3667 | |
3668 int | |
3669 octave_lexer::count_token (int tok) | |
3670 { | |
3671 if (tok != '\n') | |
3672 { | |
3673 Vtoken_count++; | |
3674 token_count++; | |
3675 } | |
3676 | |
3677 return show_token (tok); | |
3678 } | |
3679 | |
3680 int | |
3681 octave_lexer::show_token (int tok) | |
3682 { | |
3683 if (Vdisplay_tokens) | |
3684 display_token (tok); | |
3685 | |
3686 if (lexer_debug_flag) | |
3687 { | |
3688 std::cerr << "R: "; | |
3689 display_token (tok); | |
3690 std::cerr << std::endl; | |
3691 } | |
3692 | |
3693 return tok; | |
3694 } |