1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29
30 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
31 // This one needs to be global.
32 # pragma GCC diagnostic ignored "-Wunused-function"
33 // Disable these warnings for code that is generated by flex,
34 // including pattern rules. Push the current state so we can
35 // restore the warning state prior to functions we define at
36 // the bottom of the file.
37 # pragma GCC diagnostic push
38 # pragma GCC diagnostic ignored "-Wold-style-cast"
39 # pragma GCC diagnostic ignored "-Wsign-compare"
40 # pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
41 # if defined (HAVE_WARN_IMPLICIT_FALLTHROUGH)
42 # pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
43 # endif
44 #endif
45
46 // Define away the deprecated register storage class specifier to avoid
47 // potential warnings about it.
48 #if ! defined (register)
49 # define register
50 #endif
51
52 #line 53 "libinterp/parse-tree/lex.cc"
53
54 #define YY_INT_ALIGNED short int
55
56 /* A lexical scanner generated by flex */
57
58 #define FLEX_SCANNER
59 #define YY_FLEX_MAJOR_VERSION 2
60 #define YY_FLEX_MINOR_VERSION 6
61 #define YY_FLEX_SUBMINOR_VERSION 4
62 #if YY_FLEX_SUBMINOR_VERSION > 0
63 #define FLEX_BETA
64 #endif
65
66 #ifdef yy_create_buffer
67 #define octave__create_buffer_ALREADY_DEFINED
68 #else
69 #define yy_create_buffer octave__create_buffer
70 #endif
71
72 #ifdef yy_delete_buffer
73 #define octave__delete_buffer_ALREADY_DEFINED
74 #else
75 #define yy_delete_buffer octave__delete_buffer
76 #endif
77
78 #ifdef yy_scan_buffer
79 #define octave__scan_buffer_ALREADY_DEFINED
80 #else
81 #define yy_scan_buffer octave__scan_buffer
82 #endif
83
84 #ifdef yy_scan_string
85 #define octave__scan_string_ALREADY_DEFINED
86 #else
87 #define yy_scan_string octave__scan_string
88 #endif
89
90 #ifdef yy_scan_bytes
91 #define octave__scan_bytes_ALREADY_DEFINED
92 #else
93 #define yy_scan_bytes octave__scan_bytes
94 #endif
95
96 #ifdef yy_init_buffer
97 #define octave__init_buffer_ALREADY_DEFINED
98 #else
99 #define yy_init_buffer octave__init_buffer
100 #endif
101
102 #ifdef yy_flush_buffer
103 #define octave__flush_buffer_ALREADY_DEFINED
104 #else
105 #define yy_flush_buffer octave__flush_buffer
106 #endif
107
108 #ifdef yy_load_buffer_state
109 #define octave__load_buffer_state_ALREADY_DEFINED
110 #else
111 #define yy_load_buffer_state octave__load_buffer_state
112 #endif
113
114 #ifdef yy_switch_to_buffer
115 #define octave__switch_to_buffer_ALREADY_DEFINED
116 #else
117 #define yy_switch_to_buffer octave__switch_to_buffer
118 #endif
119
120 #ifdef yypush_buffer_state
121 #define octave_push_buffer_state_ALREADY_DEFINED
122 #else
123 #define yypush_buffer_state octave_push_buffer_state
124 #endif
125
126 #ifdef yypop_buffer_state
127 #define octave_pop_buffer_state_ALREADY_DEFINED
128 #else
129 #define yypop_buffer_state octave_pop_buffer_state
130 #endif
131
132 #ifdef yyensure_buffer_stack
133 #define octave_ensure_buffer_stack_ALREADY_DEFINED
134 #else
135 #define yyensure_buffer_stack octave_ensure_buffer_stack
136 #endif
137
138 #ifdef yylex
139 #define octave_lex_ALREADY_DEFINED
140 #else
141 #define yylex octave_lex
142 #endif
143
144 #ifdef yyrestart
145 #define octave_restart_ALREADY_DEFINED
146 #else
147 #define yyrestart octave_restart
148 #endif
149
150 #ifdef yylex_init
151 #define octave_lex_init_ALREADY_DEFINED
152 #else
153 #define yylex_init octave_lex_init
154 #endif
155
156 #ifdef yylex_init_extra
157 #define octave_lex_init_extra_ALREADY_DEFINED
158 #else
159 #define yylex_init_extra octave_lex_init_extra
160 #endif
161
162 #ifdef yylex_destroy
163 #define octave_lex_destroy_ALREADY_DEFINED
164 #else
165 #define yylex_destroy octave_lex_destroy
166 #endif
167
168 #ifdef yyget_debug
169 #define octave_get_debug_ALREADY_DEFINED
170 #else
171 #define yyget_debug octave_get_debug
172 #endif
173
174 #ifdef yyset_debug
175 #define octave_set_debug_ALREADY_DEFINED
176 #else
177 #define yyset_debug octave_set_debug
178 #endif
179
180 #ifdef yyget_extra
181 #define octave_get_extra_ALREADY_DEFINED
182 #else
183 #define yyget_extra octave_get_extra
184 #endif
185
186 #ifdef yyset_extra
187 #define octave_set_extra_ALREADY_DEFINED
188 #else
189 #define yyset_extra octave_set_extra
190 #endif
191
192 #ifdef yyget_in
193 #define octave_get_in_ALREADY_DEFINED
194 #else
195 #define yyget_in octave_get_in
196 #endif
197
198 #ifdef yyset_in
199 #define octave_set_in_ALREADY_DEFINED
200 #else
201 #define yyset_in octave_set_in
202 #endif
203
204 #ifdef yyget_out
205 #define octave_get_out_ALREADY_DEFINED
206 #else
207 #define yyget_out octave_get_out
208 #endif
209
210 #ifdef yyset_out
211 #define octave_set_out_ALREADY_DEFINED
212 #else
213 #define yyset_out octave_set_out
214 #endif
215
216 #ifdef yyget_leng
217 #define octave_get_leng_ALREADY_DEFINED
218 #else
219 #define yyget_leng octave_get_leng
220 #endif
221
222 #ifdef yyget_text
223 #define octave_get_text_ALREADY_DEFINED
224 #else
225 #define yyget_text octave_get_text
226 #endif
227
228 #ifdef yyget_lineno
229 #define octave_get_lineno_ALREADY_DEFINED
230 #else
231 #define yyget_lineno octave_get_lineno
232 #endif
233
234 #ifdef yyset_lineno
235 #define octave_set_lineno_ALREADY_DEFINED
236 #else
237 #define yyset_lineno octave_set_lineno
238 #endif
239
240 #ifdef yyget_column
241 #define octave_get_column_ALREADY_DEFINED
242 #else
243 #define yyget_column octave_get_column
244 #endif
245
246 #ifdef yyset_column
247 #define octave_set_column_ALREADY_DEFINED
248 #else
249 #define yyset_column octave_set_column
250 #endif
251
252 #ifdef yywrap
253 #define octave_wrap_ALREADY_DEFINED
254 #else
255 #define yywrap octave_wrap
256 #endif
257
258 #ifdef yyget_lval
259 #define octave_get_lval_ALREADY_DEFINED
260 #else
261 #define yyget_lval octave_get_lval
262 #endif
263
264 #ifdef yyset_lval
265 #define octave_set_lval_ALREADY_DEFINED
266 #else
267 #define yyset_lval octave_set_lval
268 #endif
269
270 #ifdef yyalloc
271 #define octave_alloc_ALREADY_DEFINED
272 #else
273 #define yyalloc octave_alloc
274 #endif
275
276 #ifdef yyrealloc
277 #define octave_realloc_ALREADY_DEFINED
278 #else
279 #define yyrealloc octave_realloc
280 #endif
281
282 #ifdef yyfree
283 #define octave_free_ALREADY_DEFINED
284 #else
285 #define yyfree octave_free
286 #endif
287
288 /* First, we deal with platform-specific or compiler-specific issues. */
289
290 /* begin standard C headers. */
291 #include <stdio.h>
292 #include <string.h>
293 #include <errno.h>
294 #include <stdlib.h>
295
296 /* end standard C headers. */
297
298 /* flex integer type definitions */
299
300 #ifndef FLEXINT_H
301 #define FLEXINT_H
302
303 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
304
305 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
306
307 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
308 * if you want the limit (max/min) macros for int types.
309 */
310 #ifndef __STDC_LIMIT_MACROS
311 #define __STDC_LIMIT_MACROS 1
312 #endif
313
314 #include <inttypes.h>
315 typedef int8_t flex_int8_t;
316 typedef uint8_t flex_uint8_t;
317 typedef int16_t flex_int16_t;
318 typedef uint16_t flex_uint16_t;
319 typedef int32_t flex_int32_t;
320 typedef uint32_t flex_uint32_t;
321 #else
322 typedef signed char flex_int8_t;
323 typedef short int flex_int16_t;
324 typedef int flex_int32_t;
325 typedef unsigned char flex_uint8_t;
326 typedef unsigned short int flex_uint16_t;
327 typedef unsigned int flex_uint32_t;
328
329 /* Limits of integral types. */
330 #ifndef INT8_MIN
331 #define INT8_MIN (-128)
332 #endif
333 #ifndef INT16_MIN
334 #define INT16_MIN (-32767-1)
335 #endif
336 #ifndef INT32_MIN
337 #define INT32_MIN (-2147483647-1)
338 #endif
339 #ifndef INT8_MAX
340 #define INT8_MAX (127)
341 #endif
342 #ifndef INT16_MAX
343 #define INT16_MAX (32767)
344 #endif
345 #ifndef INT32_MAX
346 #define INT32_MAX (2147483647)
347 #endif
348 #ifndef UINT8_MAX
349 #define UINT8_MAX (255U)
350 #endif
351 #ifndef UINT16_MAX
352 #define UINT16_MAX (65535U)
353 #endif
354 #ifndef UINT32_MAX
355 #define UINT32_MAX (4294967295U)
356 #endif
357
358 #ifndef SIZE_MAX
359 #define SIZE_MAX (~(size_t)0)
360 #endif
361
362 #endif /* ! C99 */
363
364 #endif /* ! FLEXINT_H */
365
366 /* begin standard C++ headers. */
367
368 /* TODO: this is always defined, so inline it */
369 #define yyconst const
370
371 #if defined(__GNUC__) && __GNUC__ >= 3
372 #define yynoreturn __attribute__((__noreturn__))
373 #else
374 #define yynoreturn
375 #endif
376
377 /* Returned upon end-of-file. */
378 #define YY_NULL 0
379
380 /* Promotes a possibly negative, possibly signed char to an
381 * integer in range [0..255] for use as an array index.
382 */
383 #define YY_SC_TO_UI(c) ((YY_CHAR) (c))
384
385 /* An opaque pointer. */
386 #ifndef YY_TYPEDEF_YY_SCANNER_T
387 #define YY_TYPEDEF_YY_SCANNER_T
388 typedef void* yyscan_t;
389 #endif
390
391 /* For convenience, these vars (plus the bison vars far below)
392 are macros in the reentrant scanner. */
393 #define yyin yyg->yyin_r
394 #define yyout yyg->yyout_r
395 #define yyextra yyg->yyextra_r
396 #define yyleng yyg->yyleng_r
397 #define yytext yyg->yytext_r
398 #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
399 #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
400 #define yy_flex_debug yyg->yy_flex_debug_r
401
402 /* Enter a start condition. This macro really ought to take a parameter,
403 * but we do it the disgusting crufty way forced on us by the ()-less
404 * definition of BEGIN.
405 */
406 #define BEGIN yyg->yy_start = 1 + 2 *
407 /* Translate the current start state into a value that can be later handed
408 * to BEGIN to return to the state. The YYSTATE alias is for lex
409 * compatibility.
410 */
411 #define YY_START ((yyg->yy_start - 1) / 2)
412 #define YYSTATE YY_START
413 /* Action number for EOF rule of a given start state. */
414 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
415 /* Special action meaning "start processing a new file". */
416 #define YY_NEW_FILE yyrestart( yyin , yyscanner )
417 #define YY_END_OF_BUFFER_CHAR 0
418
419 /* Size of default input buffer. */
420 #ifndef YY_BUF_SIZE
421 #ifdef __ia64__
422 /* On IA-64, the buffer size is 16k, not 8k.
423 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
424 * Ditto for the __ia64__ case accordingly.
425 */
426 #define YY_BUF_SIZE 32768
427 #else
428 #define YY_BUF_SIZE 16384
429 #endif /* __ia64__ */
430 #endif
431
432 /* The state buf must be large enough to hold one state per character in the main buffer.
433 */
434 #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
435
436 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
437 #define YY_TYPEDEF_YY_BUFFER_STATE
438 typedef struct yy_buffer_state *YY_BUFFER_STATE;
439 #endif
440
441 #ifndef YY_TYPEDEF_YY_SIZE_T
442 #define YY_TYPEDEF_YY_SIZE_T
443 typedef size_t yy_size_t;
444 #endif
445
446 #define EOB_ACT_CONTINUE_SCAN 0
447 #define EOB_ACT_END_OF_FILE 1
448 #define EOB_ACT_LAST_MATCH 2
449
450 #define YY_LESS_LINENO(n)
451 #define YY_LINENO_REWIND_TO(ptr)
452
453 /* Return all but the first "n" matched characters back to the input stream. */
454 #define yyless(n) \
455 do \
456 { \
457 /* Undo effects of setting up yytext. */ \
458 int yyless_macro_arg = (n); \
459 YY_LESS_LINENO(yyless_macro_arg);\
460 *yy_cp = yyg->yy_hold_char; \
461 YY_RESTORE_YY_MORE_OFFSET \
462 yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
463 YY_DO_BEFORE_ACTION; /* set up yytext again */ \
464 } \
465 while ( 0 )
466 #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
467
468 #ifndef YY_STRUCT_YY_BUFFER_STATE
469 #define YY_STRUCT_YY_BUFFER_STATE
470 struct yy_buffer_state
471 {
472 FILE *yy_input_file;
473
474 char *yy_ch_buf; /* input buffer */
475 char *yy_buf_pos; /* current position in input buffer */
476
477 /* Size of input buffer in bytes, not including room for EOB
478 * characters.
479 */
480 int yy_buf_size;
481
482 /* Number of characters read into yy_ch_buf, not including EOB
483 * characters.
484 */
485 int yy_n_chars;
486
487 /* Whether we "own" the buffer - i.e., we know we created it,
488 * and can realloc() it to grow it, and should free() it to
489 * delete it.
490 */
491 int yy_is_our_buffer;
492
493 /* Whether this is an "interactive" input source; if so, and
494 * if we're using stdio for input, then we want to use getc()
495 * instead of fread(), to make sure we stop fetching input after
496 * each newline.
497 */
498 int yy_is_interactive;
499
500 /* Whether we're considered to be at the beginning of a line.
501 * If so, '^' rules will be active on the next match, otherwise
502 * not.
503 */
504 int yy_at_bol;
505
506 int yy_bs_lineno; /**< The line count. */
507 int yy_bs_column; /**< The column count. */
508
509 /* Whether to try to fill the input buffer when we reach the
510 * end of it.
511 */
512 int yy_fill_buffer;
513
514 int yy_buffer_status;
515
516 #define YY_BUFFER_NEW 0
517 #define YY_BUFFER_NORMAL 1
518 /* When an EOF's been seen but there's still some text to process
519 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
520 * shouldn't try reading from the input source any more. We might
521 * still have a bunch of tokens to match, though, because of
522 * possible backing-up.
523 *
524 * When we actually see the EOF, we change the status to "new"
525 * (via yyrestart()), so that the user can continue scanning by
526 * just pointing yyin at a new input file.
527 */
528 #define YY_BUFFER_EOF_PENDING 2
529
530 };
531 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
532
533 /* We provide macros for accessing buffer states in case in the
534 * future we want to put the buffer states in a more general
535 * "scanner state".
536 *
537 * Returns the top of the stack, or NULL.
538 */
539 #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
540 ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
541 : NULL)
542 /* Same as previous macro, but useful when we know that the buffer stack is not
543 * NULL or when we need an lvalue. For internal use only.
544 */
545 #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
546
547 void yyrestart ( FILE *input_file , yyscan_t yyscanner );
548 void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
549 YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size , yyscan_t yyscanner );
550 void yy_delete_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
551 void yy_flush_buffer ( YY_BUFFER_STATE b , yyscan_t yyscanner );
552 void yypush_buffer_state ( YY_BUFFER_STATE new_buffer , yyscan_t yyscanner );
553 void yypop_buffer_state ( yyscan_t yyscanner );
554
555 static void yyensure_buffer_stack ( yyscan_t yyscanner );
556 static void yy_load_buffer_state ( yyscan_t yyscanner );
557 static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file , yyscan_t yyscanner );
558 #define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER , yyscanner)
559
560 YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size , yyscan_t yyscanner );
561 YY_BUFFER_STATE yy_scan_string ( const char *yy_str , yyscan_t yyscanner );
562 YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len , yyscan_t yyscanner );
563
564 void *yyalloc ( yy_size_t , yyscan_t yyscanner );
565 void *yyrealloc ( void *, yy_size_t , yyscan_t yyscanner );
566 void yyfree ( void * , yyscan_t yyscanner );
567
568 #define yy_new_buffer yy_create_buffer
569 #define yy_set_interactive(is_interactive) \
570 { \
571 if ( ! YY_CURRENT_BUFFER ){ \
572 yyensure_buffer_stack (yyscanner); \
573 YY_CURRENT_BUFFER_LVALUE = \
574 yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
575 } \
576 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
577 }
578 #define yy_set_bol(at_bol) \
579 { \
580 if ( ! YY_CURRENT_BUFFER ){\
581 yyensure_buffer_stack (yyscanner); \
582 YY_CURRENT_BUFFER_LVALUE = \
583 yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner); \
584 } \
585 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
586 }
587 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
588
589 /* Begin user sect3 */
590
591 #define octave_wrap(yyscanner) (/*CONSTCOND*/1)
592 #define YY_SKIP_YYWRAP
593 typedef flex_uint8_t YY_CHAR;
594
595 typedef int yy_state_type;
596
597 #define yytext_ptr yytext_r
598
599 static yy_state_type yy_get_previous_state ( yyscan_t yyscanner );
600 static yy_state_type yy_try_NUL_trans ( yy_state_type current_state , yyscan_t yyscanner);
601 static int yy_get_next_buffer ( yyscan_t yyscanner );
602 static void yynoreturn yy_fatal_error ( const char* msg , yyscan_t yyscanner );
603
604 /* Done after the current pattern has been matched and before the
605 * corresponding action - sets up yytext.
606 */
607 #define YY_DO_BEFORE_ACTION \
608 yyg->yytext_ptr = yy_bp; \
609 yyleng = (int) (yy_cp - yy_bp); \
610 yyg->yy_hold_char = *yy_cp; \
611 *yy_cp = '\0'; \
612 yyg->yy_c_buf_p = yy_cp;
613 #define YY_NUM_RULES 123
614 #define YY_END_OF_BUFFER 124
615 /* This struct is not used in this scanner,
616 but its presence is necessary. */
617 struct yy_trans_info
618 {
619 flex_int32_t yy_verify;
620 flex_int32_t yy_nxt;
621 };
622 static const flex_int16_t yy_accept[308] =
623 { 0,
624 0, 0, 5, 5, 10, 10, 0, 0, 0, 0,
625 0, 0, 0, 0, 0, 0, 0, 0, 124, 122,
626 54, 64, 64, 95, 66, 122, 59, 80, 65, 100,
627 101, 84, 92, 96, 93, 102, 85, 53, 53, 67,
628 91, 82, 103, 83, 122, 62, 15, 86, 16, 87,
629 59, 59, 120, 81, 121, 94, 54, 122, 9, 8,
630 3, 3, 7, 123, 5, 6, 4, 9, 10, 11,
631 11, 102, 13, 14, 10, 1, 1, 123, 20, 20,
632 123, 123, 24, 24, 24, 24, 24, 24, 41, 42,
633 42, 26, 40, 123, 45, 46, 46, 44, 50, 48,
634
635 50, 47, 50, 54, 0, 64, 77, 0, 21, 21,
636 0, 59, 0, 0, 89, 118, 88, 106, 98, 104,
637 99, 105, 97, 70, 68, 69, 0, 71, 53, 72,
638 73, 107, 53, 53, 0, 0, 51, 0, 75, 76,
639 79, 0, 61, 0, 63, 0, 56, 56, 0, 108,
640 114, 59, 59, 119, 90, 78, 54, 0, 0, 9,
641 8, 3, 0, 3, 5, 6, 0, 10, 11, 0,
642 10, 1, 0, 20, 20, 0, 0, 0, 0, 0,
643 0, 24, 0, 23, 23, 0, 0, 0, 41, 42,
644 25, 0, 39, 39, 38, 38, 27, 29, 30, 31,
645
646 32, 33, 34, 35, 39, 45, 46, 43, 48, 50,
647 0, 47, 0, 0, 0, 0, 0, 60, 115, 74,
648 111, 109, 110, 0, 112, 53, 0, 113, 116, 52,
649 53, 53, 0, 53, 53, 0, 61, 0, 0, 63,
650 0, 0, 57, 57, 59, 0, 17, 17, 0, 0,
651 0, 18, 18, 0, 19, 19, 0, 22, 22, 0,
652 0, 37, 37, 27, 28, 0, 47, 0, 0, 0,
653 60, 0, 117, 0, 55, 55, 0, 53, 53, 53,
654 0, 61, 0, 63, 0, 58, 0, 2, 2, 0,
655 12, 12, 0, 36, 36, 27, 47, 0, 49, 49,
656
657 0, 60, 53, 61, 63, 60, 0
658 } ;
659
660 static const YY_CHAR yy_ec[256] =
661 { 0,
662 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
663 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
665 1, 2, 5, 6, 7, 8, 7, 9, 10, 11,
666 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
667 21, 21, 21, 21, 21, 22, 22, 23, 24, 25,
668 26, 27, 28, 29, 30, 31, 30, 32, 32, 30,
669 8, 8, 33, 33, 8, 8, 8, 8, 8, 8,
670 8, 8, 8, 8, 8, 8, 8, 34, 8, 8,
671 35, 36, 37, 38, 39, 1, 40, 41, 30, 32,
672
673 42, 43, 44, 8, 33, 33, 8, 8, 8, 45,
674 8, 8, 8, 46, 47, 48, 8, 49, 8, 50,
675 8, 8, 51, 52, 53, 54, 1, 1, 1, 1,
676 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
677 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
679 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
680 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
681 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
682 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
683
684 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
689 1, 1, 1, 1, 1
690 } ;
691
692 static const YY_CHAR yy_meta[55] =
693 { 0,
694 1, 2, 3, 3, 1, 4, 5, 6, 1, 7,
695 5, 5, 1, 1, 5, 1, 8, 1, 9, 9,
696 9, 9, 1, 5, 1, 1, 1, 1, 10, 11,
697 11, 11, 12, 6, 5, 13, 5, 1, 12, 11,
698 11, 11, 11, 6, 6, 6, 6, 6, 6, 6,
699 5, 1, 5, 1
700 } ;
701
702 static const flex_int16_t yy_base[348] =
703 { 0,
704 0, 53, 59, 111, 55, 83, 823, 822, 64, 75,
705 91, 95, 121, 127, 101, 137, 164, 0, 824, 1050,
706 73, 1050, 820, 796, 1050, 85, 132, 47, 1050, 1050,
707 1050, 90, 93, 1050, 65, 209, 792, 231, 205, 1050,
708 1050, 789, 787, 786, 809, 801, 1050, 230, 1050, 773,
709 240, 242, 1050, 80, 1050, 753, 135, 217, 0, 773,
710 1050, 771, 1050, 147, 232, 223, 1050, 710, 151, 1050,
711 723, 707, 1050, 1050, 152, 1050, 720, 152, 1050, 719,
712 283, 271, 1050, 247, 718, 237, 259, 274, 0, 1050,
713 714, 710, 698, 324, 0, 1050, 711, 702, 1050, 709,
714
715 707, 143, 689, 286, 276, 1050, 1050, 288, 1050, 702,
716 287, 292, 702, 701, 1050, 1050, 675, 1050, 1050, 1050,
717 1050, 1050, 1050, 126, 674, 673, 675, 664, 278, 663,
718 662, 1050, 365, 0, 276, 315, 1050, 0, 1050, 1050,
719 1050, 592, 301, 591, 306, 344, 1050, 589, 298, 1050,
720 1050, 351, 360, 1050, 1050, 1050, 305, 310, 336, 0,
721 589, 1050, 302, 587, 331, 318, 570, 347, 1050, 569,
722 350, 1050, 329, 1050, 582, 356, 387, 390, 407, 374,
723 392, 1050, 402, 1050, 581, 410, 410, 416, 0, 1050,
724 1050, 563, 1050, 419, 1050, 576, 405, 1050, 1050, 1050,
725
726 1050, 1050, 1050, 1050, 0, 0, 1050, 1050, 559, 1050,
727 339, 398, 553, 474, 485, 414, 482, 425, 1050, 453,
728 1050, 1050, 1050, 425, 1050, 413, 437, 1050, 1050, 1050,
729 443, 447, 428, 450, 441, 437, 471, 466, 475, 476,
730 458, 433, 1050, 441, 479, 495, 1050, 438, 491, 497,
731 500, 1050, 427, 503, 1050, 399, 507, 1050, 385, 510,
732 513, 1050, 376, 499, 0, 348, 519, 519, 522, 523,
733 524, 317, 1050, 524, 1050, 255, 510, 523, 527, 205,
734 222, 533, 141, 535, 552, 1050, 530, 1050, 126, 554,
735 1050, 106, 568, 1050, 98, 1050, 536, 561, 1050, 81,
736
737 62, 557, 556, 565, 566, 571, 1050, 595, 608, 621,
738 634, 647, 660, 673, 685, 696, 707, 719, 732, 745,
739 758, 771, 783, 796, 808, 819, 830, 834, 844, 855,
740 867, 872, 882, 893, 904, 916, 921, 932, 943, 955,
741 968, 980, 992, 1004, 1015, 1026, 1037
742 } ;
743
744 static const flex_int16_t yy_def[348] =
745 { 0,
746 307, 1, 308, 308, 1, 1, 309, 309, 310, 310,
747 311, 311, 312, 312, 313, 313, 307, 17, 307, 307,
748 307, 307, 307, 307, 307, 314, 315, 307, 307, 307,
749 307, 307, 307, 307, 307, 307, 307, 307, 38, 307,
750 307, 307, 307, 307, 316, 317, 307, 307, 307, 307,
751 315, 315, 307, 307, 307, 307, 307, 314, 318, 307,
752 307, 307, 307, 319, 307, 307, 307, 307, 307, 307,
753 307, 36, 307, 307, 307, 307, 307, 320, 307, 307,
754 320, 320, 307, 307, 307, 321, 307, 321, 322, 307,
755 307, 307, 307, 323, 324, 307, 307, 307, 307, 307,
756
757 307, 325, 307, 307, 314, 307, 307, 314, 307, 307,
758 307, 315, 326, 327, 307, 307, 307, 307, 307, 307,
759 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
760 307, 307, 307, 39, 307, 307, 307, 328, 307, 307,
761 307, 316, 329, 317, 330, 307, 307, 307, 331, 307,
762 307, 315, 315, 307, 307, 307, 307, 314, 314, 318,
763 307, 307, 319, 307, 307, 307, 307, 307, 307, 307,
764 307, 307, 320, 307, 307, 320, 320, 320, 320, 307,
765 321, 307, 321, 307, 307, 307, 321, 321, 322, 307,
766 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
767
768 307, 307, 307, 307, 332, 324, 307, 307, 307, 307,
769 307, 325, 333, 307, 326, 334, 327, 335, 307, 307,
770 307, 307, 307, 336, 307, 307, 307, 307, 307, 307,
771 307, 307, 307, 307, 337, 307, 329, 338, 307, 330,
772 339, 331, 307, 307, 315, 314, 307, 307, 340, 341,
773 320, 307, 307, 320, 307, 307, 321, 307, 307, 307,
774 307, 307, 307, 307, 332, 333, 342, 343, 334, 307,
775 335, 344, 307, 336, 307, 307, 307, 307, 307, 337,
776 338, 345, 339, 346, 307, 307, 340, 307, 307, 341,
777 307, 307, 307, 307, 307, 307, 342, 343, 307, 307,
778
779 344, 347, 307, 345, 346, 347, 0, 307, 307, 307,
780 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
781 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
782 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
783 307, 307, 307, 307, 307, 307, 307
784 } ;
785
786 static const flex_int16_t yy_nxt[1105] =
787 { 0,
788 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
789 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
790 39, 39, 40, 41, 42, 43, 44, 45, 46, 27,
791 27, 27, 27, 27, 47, 48, 49, 50, 27, 27,
792 27, 27, 27, 51, 27, 27, 52, 27, 27, 27,
793 53, 54, 55, 56, 57, 115, 69, 70, 71, 58,
794 60, 61, 62, 301, 63, 64, 79, 80, 63, 65,
795 66, 72, 116, 67, 104, 68, 81, 79, 80, 105,
796 121, 82, 67, 299, 75, 70, 71, 109, 110, 58,
797 122, 73, 84, 65, 85, 66, 87, 86, 85, 72,
798
799 294, 88, 117, 96, 97, 154, 119, 74, 291, 65,
800 98, 66, 60, 61, 62, 118, 63, 64, 120, 73,
801 63, 65, 66, 90, 91, 67, 92, 68, 288, 90,
802 91, 155, 92, 111, 67, 74, 157, 93, 220, 96,
803 97, 158, 283, 93, 211, 65, 98, 66, 113, 162,
804 164, 221, 168, 171, 174, 175, 94, 105, 158, 213,
805 114, 65, 94, 66, 99, 100, 99, 101, 99, 99,
806 99, 102, 99, 99, 99, 99, 99, 99, 99, 99,
807 103, 99, 99, 99, 99, 99, 99, 99, 99, 99,
808 99, 99, 99, 102, 102, 102, 102, 102, 99, 99,
809
810 99, 99, 102, 102, 102, 102, 102, 102, 102, 102,
811 102, 102, 102, 102, 99, 99, 99, 99, 123, 109,
812 110, 124, 125, 281, 126, 127, 128, 129, 129, 129,
813 129, 146, 147, 148, 166, 307, 149, 137, 307, 184,
814 185, 111, 165, 111, 130, 307, 131, 133, 180, 134,
815 134, 134, 134, 181, 307, 150, 113, 275, 113, 166,
816 186, 135, 136, 137, 138, 187, 165, 159, 114, 134,
817 114, 135, 136, 174, 175, 166, 184, 185, 109, 110,
818 138, 152, 165, 153, 176, 174, 175, 104, 111, 177,
819 109, 110, 105, 111, 232, 232, 226, 226, 226, 226,
820
821 243, 244, 236, 113, 162, 164, 157, 239, 113, 227,
822 137, 158, 109, 110, 232, 114, 226, 238, 301, 227,
823 114, 178, 241, 179, 188, 194, 195, 196, 233, 166,
824 233, 174, 175, 234, 234, 234, 234, 246, 247, 248,
825 211, 165, 197, 197, 197, 146, 147, 148, 168, 266,
826 149, 171, 111, 105, 166, 213, 158, 176, 174, 175,
827 159, 111, 177, 198, 199, 165, 200, 113, 201, 202,
828 166, 203, 204, 205, 230, 180, 113, 230, 262, 114,
829 181, 165, 230, 231, 231, 231, 231, 258, 114, 174,
830 175, 251, 252, 253, 184, 185, 136, 137, 245, 211,
831
832 230, 255, 230, 231, 184, 185, 136, 245, 254, 255,
833 256, 186, 184, 185, 213, 111, 187, 257, 258, 259,
834 261, 262, 263, 264, 264, 264, 270, 275, 276, 252,
835 113, 226, 226, 226, 226, 243, 244, 178, 236, 179,
836 247, 272, 114, 243, 227, 137, 234, 234, 234, 234,
837 277, 226, 277, 238, 227, 278, 278, 278, 278, 283,
838 188, 231, 231, 231, 231, 232, 232, 281, 279, 279,
839 279, 279, 236, 137, 136, 137, 239, 239, 273, 137,
840 285, 231, 137, 217, 136, 232, 215, 238, 279, 286,
841 268, 241, 241, 288, 289, 113, 246, 247, 248, 291,
842
843 292, 251, 252, 253, 254, 255, 256, 114, 257, 258,
844 259, 293, 294, 295, 261, 262, 263, 296, 296, 296,
845 211, 299, 300, 111, 270, 270, 275, 276, 278, 278,
846 278, 278, 288, 289, 236, 213, 239, 211, 113, 272,
847 272, 303, 303, 303, 303, 279, 279, 279, 279, 238,
848 114, 241, 213, 285, 266, 137, 291, 292, 270, 137,
849 209, 303, 286, 299, 300, 279, 236, 239, 113, 293,
850 294, 295, 270, 272, 303, 303, 303, 303, 195, 260,
851 114, 238, 241, 184, 174, 250, 249, 272, 137, 162,
852 161, 147, 144, 142, 303, 59, 59, 59, 59, 59,
853
854 59, 59, 59, 59, 59, 59, 59, 59, 76, 76,
855 76, 76, 76, 76, 76, 76, 76, 76, 76, 76,
856 76, 78, 78, 78, 78, 78, 78, 78, 78, 78,
857 78, 78, 78, 78, 83, 83, 83, 83, 83, 83,
858 83, 83, 83, 83, 83, 83, 83, 89, 89, 89,
859 89, 89, 89, 89, 89, 89, 89, 89, 89, 89,
860 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
861 95, 95, 95, 108, 108, 108, 108, 108, 108, 108,
862 108, 108, 108, 108, 108, 108, 112, 229, 228, 225,
863 112, 224, 112, 112, 112, 112, 112, 143, 223, 222,
864
865 219, 143, 217, 215, 109, 214, 143, 143, 145, 210,
866 209, 208, 145, 207, 192, 191, 190, 145, 145, 160,
867 182, 174, 172, 170, 160, 169, 167, 160, 160, 160,
868 160, 160, 163, 163, 163, 163, 163, 163, 163, 163,
869 163, 163, 163, 163, 163, 173, 173, 173, 173, 173,
870 173, 173, 173, 173, 173, 173, 173, 173, 183, 183,
871 183, 183, 183, 183, 183, 183, 183, 183, 183, 183,
872 183, 189, 189, 162, 161, 189, 189, 189, 156, 189,
873 189, 189, 189, 193, 193, 193, 193, 193, 193, 193,
874 193, 193, 193, 193, 193, 193, 206, 206, 151, 206,
875
876 206, 206, 144, 206, 206, 206, 206, 206, 206, 212,
877 142, 141, 140, 212, 139, 212, 212, 132, 212, 212,
878 216, 107, 106, 307, 216, 77, 77, 307, 307, 216,
879 216, 218, 307, 307, 307, 218, 307, 307, 307, 307,
880 218, 218, 235, 307, 235, 237, 307, 307, 307, 237,
881 307, 237, 237, 307, 237, 237, 240, 307, 307, 307,
882 240, 307, 240, 240, 307, 240, 240, 242, 242, 242,
883 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
884 265, 307, 265, 267, 307, 307, 307, 267, 307, 307,
885 307, 307, 267, 267, 269, 307, 307, 307, 269, 307,
886
887 269, 269, 269, 269, 269, 271, 307, 307, 307, 271,
888 307, 271, 271, 307, 271, 271, 274, 274, 274, 274,
889 274, 274, 274, 274, 274, 274, 274, 274, 274, 280,
890 307, 280, 280, 282, 307, 307, 307, 282, 307, 307,
891 307, 307, 282, 282, 284, 307, 307, 307, 284, 307,
892 307, 307, 307, 284, 284, 287, 287, 287, 287, 287,
893 287, 287, 287, 287, 287, 287, 287, 287, 290, 290,
894 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,
895 290, 297, 307, 307, 307, 297, 307, 297, 297, 307,
896 297, 297, 298, 298, 298, 298, 298, 298, 298, 298,
897
898 298, 298, 298, 298, 298, 302, 307, 307, 307, 302,
899 307, 307, 307, 307, 302, 302, 304, 307, 307, 307,
900 304, 307, 304, 304, 307, 304, 304, 305, 307, 307,
901 307, 305, 307, 305, 305, 307, 305, 305, 306, 307,
902 307, 307, 306, 307, 306, 306, 307, 306, 306, 19,
903 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
904 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
905 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
906 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
907 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
908
909 307, 307, 307, 307
910 } ;
911
912 static const flex_int16_t yy_chk[1105] =
913 { 0,
914 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
915 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
916 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
917 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
918 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
919 1, 1, 1, 1, 2, 28, 5, 5, 5, 2,
920 3, 3, 3, 301, 3, 3, 9, 9, 3, 3,
921 3, 5, 28, 3, 21, 3, 10, 10, 10, 21,
922 35, 10, 3, 300, 6, 6, 6, 26, 26, 6,
923 35, 5, 11, 3, 11, 3, 12, 11, 12, 6,
924
925 295, 12, 32, 15, 15, 54, 33, 5, 292, 3,
926 15, 3, 4, 4, 4, 32, 4, 4, 33, 6,
927 4, 4, 4, 13, 13, 4, 13, 4, 289, 14,
928 14, 54, 14, 27, 4, 6, 57, 13, 124, 16,
929 16, 57, 283, 14, 102, 4, 16, 4, 27, 64,
930 64, 124, 69, 75, 78, 78, 13, 69, 75, 102,
931 27, 4, 14, 4, 17, 17, 17, 17, 17, 17,
932 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
933 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
934 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
935
936 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
937 17, 17, 17, 17, 17, 17, 17, 17, 36, 58,
938 58, 36, 36, 281, 36, 36, 36, 36, 36, 36,
939 36, 48, 48, 48, 66, 39, 48, 280, 39, 86,
940 86, 51, 65, 52, 36, 39, 36, 38, 84, 38,
941 38, 38, 38, 84, 39, 48, 51, 276, 52, 66,
942 87, 38, 38, 38, 38, 87, 65, 58, 51, 38,
943 52, 38, 38, 82, 82, 66, 88, 88, 105, 105,
944 38, 51, 65, 52, 81, 81, 81, 104, 111, 81,
945 108, 108, 104, 112, 135, 135, 129, 129, 129, 129,
946
947 149, 149, 143, 111, 163, 163, 157, 145, 112, 129,
948 129, 157, 158, 158, 135, 111, 129, 143, 272, 129,
949 112, 82, 145, 82, 88, 94, 94, 94, 136, 166,
950 136, 173, 173, 136, 136, 136, 136, 159, 159, 159,
951 211, 165, 94, 94, 94, 146, 146, 146, 168, 266,
952 146, 171, 152, 168, 166, 211, 171, 176, 176, 176,
953 158, 153, 176, 94, 94, 165, 94, 152, 94, 94,
954 166, 94, 94, 94, 133, 180, 153, 133, 263, 152,
955 180, 165, 133, 133, 133, 133, 133, 259, 153, 177,
956 177, 178, 178, 178, 181, 181, 133, 133, 152, 212,
957
958 133, 256, 133, 133, 183, 183, 133, 153, 179, 179,
959 179, 186, 187, 187, 212, 216, 186, 188, 188, 188,
960 194, 194, 194, 197, 197, 197, 218, 224, 224, 253,
961 216, 226, 226, 226, 226, 242, 242, 177, 236, 177,
962 248, 218, 216, 244, 226, 226, 233, 233, 233, 233,
963 227, 226, 227, 236, 226, 227, 227, 227, 227, 241,
964 187, 231, 231, 231, 231, 232, 232, 238, 234, 234,
965 234, 234, 237, 235, 231, 231, 239, 240, 220, 232,
966 245, 231, 234, 217, 231, 232, 215, 237, 234, 245,
967 214, 239, 240, 249, 249, 245, 246, 246, 246, 250,
968
969 250, 251, 251, 251, 254, 254, 254, 245, 257, 257,
970 257, 260, 260, 260, 261, 261, 261, 264, 264, 264,
971 267, 268, 268, 269, 270, 271, 274, 274, 277, 277,
972 277, 277, 287, 287, 282, 267, 284, 297, 269, 270,
973 271, 278, 278, 278, 278, 279, 279, 279, 279, 282,
974 269, 284, 297, 285, 213, 278, 290, 290, 302, 279,
975 209, 278, 285, 298, 298, 279, 304, 305, 285, 293,
976 293, 293, 306, 302, 303, 303, 303, 303, 196, 192,
977 285, 304, 305, 185, 175, 170, 167, 306, 303, 164,
978 161, 148, 144, 142, 303, 308, 308, 308, 308, 308,
979
980 308, 308, 308, 308, 308, 308, 308, 308, 309, 309,
981 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,
982 309, 310, 310, 310, 310, 310, 310, 310, 310, 310,
983 310, 310, 310, 310, 311, 311, 311, 311, 311, 311,
984 311, 311, 311, 311, 311, 311, 311, 312, 312, 312,
985 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
986 313, 313, 313, 313, 313, 313, 313, 313, 313, 313,
987 313, 313, 313, 314, 314, 314, 314, 314, 314, 314,
988 314, 314, 314, 314, 314, 314, 315, 131, 130, 128,
989 315, 127, 315, 315, 315, 315, 315, 316, 126, 125,
990
991 117, 316, 114, 113, 110, 103, 316, 316, 317, 101,
992 100, 98, 317, 97, 93, 92, 91, 317, 317, 318,
993 85, 80, 77, 72, 318, 71, 68, 318, 318, 318,
994 318, 318, 319, 319, 319, 319, 319, 319, 319, 319,
995 319, 319, 319, 319, 319, 320, 320, 320, 320, 320,
996 320, 320, 320, 320, 320, 320, 320, 320, 321, 321,
997 321, 321, 321, 321, 321, 321, 321, 321, 321, 321,
998 321, 322, 322, 62, 60, 322, 322, 322, 56, 322,
999 322, 322, 322, 323, 323, 323, 323, 323, 323, 323,
1000 323, 323, 323, 323, 323, 323, 324, 324, 50, 324,
1001
1002 324, 324, 46, 324, 324, 324, 324, 324, 324, 325,
1003 45, 44, 43, 325, 42, 325, 325, 37, 325, 325,
1004 326, 24, 23, 19, 326, 8, 7, 0, 0, 326,
1005 326, 327, 0, 0, 0, 327, 0, 0, 0, 0,
1006 327, 327, 328, 0, 328, 329, 0, 0, 0, 329,
1007 0, 329, 329, 0, 329, 329, 330, 0, 0, 0,
1008 330, 0, 330, 330, 0, 330, 330, 331, 331, 331,
1009 331, 331, 331, 331, 331, 331, 331, 331, 331, 331,
1010 332, 0, 332, 333, 0, 0, 0, 333, 0, 0,
1011 0, 0, 333, 333, 334, 0, 0, 0, 334, 0,
1012
1013 334, 334, 334, 334, 334, 335, 0, 0, 0, 335,
1014 0, 335, 335, 0, 335, 335, 336, 336, 336, 336,
1015 336, 336, 336, 336, 336, 336, 336, 336, 336, 337,
1016 0, 337, 337, 338, 0, 0, 0, 338, 0, 0,
1017 0, 0, 338, 338, 339, 0, 0, 0, 339, 0,
1018 0, 0, 0, 339, 339, 340, 340, 340, 340, 340,
1019 340, 340, 340, 340, 340, 340, 340, 340, 341, 341,
1020 341, 341, 341, 341, 341, 341, 341, 341, 341, 341,
1021 341, 342, 0, 0, 0, 342, 0, 342, 342, 0,
1022 342, 342, 343, 343, 343, 343, 343, 343, 343, 343,
1023
1024 343, 343, 343, 343, 343, 344, 0, 0, 0, 344,
1025 0, 0, 0, 0, 344, 344, 345, 0, 0, 0,
1026 345, 0, 345, 345, 0, 345, 345, 346, 0, 0,
1027 0, 346, 0, 346, 346, 0, 346, 346, 347, 0,
1028 0, 0, 347, 0, 347, 347, 0, 347, 347, 307,
1029 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
1030 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
1031 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
1032 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
1033 307, 307, 307, 307, 307, 307, 307, 307, 307, 307,
1034
1035 307, 307, 307, 307
1036 } ;
1037
1038 /* The intent behind this definition is that it'll catch
1039 * any uses of REJECT which flex missed.
1040 */
1041 #define REJECT reject_used_but_not_detected
1042 #define yymore() yymore_used_but_not_detected
1043 #define YY_MORE_ADJ 0
1044 #define YY_RESTORE_YY_MORE_OFFSET
1045 #line 1 "../libinterp/parse-tree/lex.ll"
1046 /*
1047
1048 We are using the pure parser interface and the reentrant lexer interface
1049 but the Octave parser and lexer are NOT properly reentrant because both
1050 still use many global variables. It should be safe to create a parser
1051 object and call it while another parser object is active (to parse a
1052 callback function while the main interactive parser is waiting for
1053 input, for example) if you take care to properly save and restore
1054 (typically with an unwind_protect object) relevant global values before
1055 and after the nested call.
1056
1057 */
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 #line 91 "../libinterp/parse-tree/lex.ll"
1068
1069 #include <cctype>
1070 #include <cstring>
1071
1072 #include <iostream>
1073 #include <set>
1074 #include <sstream>
1075 #include <string>
1076 #include <stack>
1077
1078 #include "cmd-edit.h"
1079 #include "lo-mappers.h"
1080 #include "quit.h"
1081 #include "unistd-wrappers.h"
1082
1083 // These would be alphabetical, but oct-parse.h must be included before
1084 // oct-gperf.h and oct-parse.h must be included after token.h and the tree
1085 // class declarations. We can't include oct-parse.h in oct-gperf.h
1086 // because it may not be protected to allow it to be included multiple
1087 // times.
1088
1089 #include "Cell.h"
1090 #include "defun.h"
1091 #include "error.h"
1092 #include "errwarn.h"
1093 #include "input.h"
1094 #include "interpreter.h"
1095 #include "lex.h"
1096 #include "octave.h"
1097 #include "ov.h"
1098 #include "parse.h"
1099 #include "pt-all.h"
1100 #include "symtab.h"
1101 #include "token.h"
1102 #include "utils.h"
1103 #include "variables.h"
1104 #include "oct-parse.h"
1105 #include "oct-gperf.h"
1106
1107 // FIXME: with bison 3.x, OCTAVE_STYPE appears in the generated
1108 // oct-parse.h file, but there is no definition for YYSTYPE, which is
1109 // needed by the code that is generated by flex. I can't seem to find a
1110 // way to tell flex to use OCTAVE_STYPE instead of YYSTYPE in the code
1111 // it generates, or to tell bison to provide the definition of YYSTYPE
1112 // in the generated oct-parse.h file.
1113
1114 #if defined (OCTAVE_STYPE_IS_DECLARED) && ! defined YYSTYPE
1115 # define YYSTYPE OCTAVE_STYPE
1116 #endif
1117
1118 #define YY_NO_UNISTD_H 1
1119 #define isatty octave_isatty_wrapper
1120
1121 #if ! (defined (FLEX_SCANNER) \
1122 && defined (YY_FLEX_MAJOR_VERSION) && YY_FLEX_MAJOR_VERSION >= 2 \
1123 && defined (YY_FLEX_MINOR_VERSION) && YY_FLEX_MINOR_VERSION >= 5)
1124 #error lex.l requires flex version 2.5.4 or later
1125 #endif
1126
1127 #define YY_EXTRA_TYPE octave::base_lexer *
1128 #define curr_lexer yyextra
1129
1130 // Arrange to get input via readline.
1131
1132 #if defined (YY_INPUT)
1133 # undef YY_INPUT
1134 #endif
1135 #define YY_INPUT(buf, result, max_size) \
1136 result = curr_lexer->fill_flex_buffer (buf, max_size)
1137
1138 // Try to avoid crashing out completely on fatal scanner errors.
1139
1140 #if defined (YY_FATAL_ERROR)
1141 # undef YY_FATAL_ERROR
1142 #endif
1143 #define YY_FATAL_ERROR(msg) \
1144 (yyget_extra (yyscanner))->fatal_error (msg)
1145
1146 #define CMD_OR_OP(PATTERN, TOK, COMPAT) \
1147 do \
1148 { \
1149 curr_lexer->lexer_debug (PATTERN); \
1150 \
1151 if (curr_lexer->looks_like_command_arg ()) \
1152 { \
1153 yyless (0); \
1154 curr_lexer->push_start_state (COMMAND_START); \
1155 } \
1156 else \
1157 return curr_lexer->handle_op (TOK, false, COMPAT); \
1158 } \
1159 while (0)
1160
1161 #define CMD_OR_COMPUTED_ASSIGN_OP(PATTERN, TOK) \
1162 do \
1163 { \
1164 curr_lexer->lexer_debug (PATTERN); \
1165 \
1166 if (curr_lexer->previous_token_may_be_command () \
1167 && curr_lexer->space_follows_previous_token ()) \
1168 { \
1169 yyless (0); \
1170 curr_lexer->push_start_state (COMMAND_START); \
1171 } \
1172 else \
1173 return curr_lexer->handle_op (TOK, false, false); \
1174 } \
1175 while (0)
1176
1177 #define CMD_OR_UNARY_OP(PATTERN, TOK, COMPAT) \
1178 do \
1179 { \
1180 curr_lexer->lexer_debug (PATTERN); \
1181 \
1182 if (curr_lexer->previous_token_may_be_command ()) \
1183 { \
1184 if (curr_lexer->looks_like_command_arg ()) \
1185 { \
1186 yyless (0); \
1187 curr_lexer->push_start_state (COMMAND_START); \
1188 } \
1189 else \
1190 return curr_lexer->handle_op (TOK, false, COMPAT); \
1191 } \
1192 else \
1193 { \
1194 if (curr_lexer->maybe_unput_comma_before_unary_op (TOK)) \
1195 { \
1196 yyless (0); \
1197 curr_lexer->xunput (','); \
1198 } \
1199 else \
1200 return curr_lexer->handle_op (TOK, false, COMPAT); \
1201 } \
1202 } \
1203 while (0)
1204
1205 #define HANDLE_EOB_OR_EOF(STATUS) \
1206 do \
1207 { \
1208 if (curr_lexer->is_push_lexer ()) \
1209 { \
1210 if (curr_lexer->at_end_of_buffer ()) \
1211 return STATUS; \
1212 \
1213 if (curr_lexer->at_end_of_file ()) \
1214 return curr_lexer->handle_end_of_input (); \
1215 } \
1216 } \
1217 while (0)
1218
1219 // If we are at the end of the buffer, ask for more input.
1220 // If we are at the end of the file, deal with it.
1221 // Otherwise, just keep going with the text from the current buffer.
1222 #define HANDLE_STRING_CONTINUATION \
1223 do \
1224 { \
1225 curr_lexer->m_filepos.next_line (); \
1226 \
1227 HANDLE_EOB_OR_EOF (-1); \
1228 } \
1229 while (0)
1230
1231 #define HANDLE_IDENTIFIER(pattern, get_set) \
1232 do \
1233 { \
1234 curr_lexer->lexer_debug (pattern); \
1235 \
1236 int tok = curr_lexer->previous_token_value (); \
1237 \
1238 if (curr_lexer->whitespace_is_significant () \
1239 && curr_lexer->space_follows_previous_token () \
1240 && ! (tok == '[' || tok == '{' \
1241 || curr_lexer->previous_token_is_binop ())) \
1242 { \
1243 yyless (0); \
1244 curr_lexer->xunput (','); \
1245 } \
1246 else \
1247 { \
1248 if (! curr_lexer->m_looking_at_decl_list \
1249 && curr_lexer->previous_token_may_be_command ()) \
1250 { \
1251 yyless (0); \
1252 curr_lexer->push_start_state (COMMAND_START); \
1253 } \
1254 else \
1255 { \
1256 if (get_set) \
1257 { \
1258 yyless (3); \
1259 curr_lexer->m_filepos.increment_column (3); \
1260 curr_lexer->m_maybe_classdef_get_set_method = false; \
1261 } \
1262 \
1263 return curr_lexer->handle_identifier (); \
1264 } \
1265 } \
1266 } \
1267 while (0)
1268
1269 static inline bool
is_space_or_tab(char c)1270 is_space_or_tab (char c)
1271 {
1272 return c == ' ' || c == '\t';
1273 }
1274
1275 static inline bool
is_space_or_tab_or_eol(char c)1276 is_space_or_tab_or_eol (char c)
1277 {
1278 return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1279 }
1280
1281 namespace octave
1282 {
iskeyword(const std::string & s)1283 bool iskeyword (const std::string& s)
1284 {
1285 // Parsing function names like "set.property_name" inside
1286 // classdef-style class definitions is simplified by handling the
1287 // "set" and "get" portions of the names using the same mechanism
1288 // as is used for keywords. However, they are not really keywords
1289 // in the language, so omit them from the list of possible
1290 // keywords. Likewise for "enumeration", "events", "methods", and
1291 // "properties".
1292
1293 return (octave_kw_hash::in_word_set (s.c_str (), s.length ()) != nullptr
1294 && ! (s == "set" || s == "get"
1295 || s == "enumeration" || s == "events"
1296 || s == "methods" || s == "properties"));
1297 }
1298 }
1299
1300 #line 1301 "libinterp/parse-tree/lex.cc"
1301 #line 1302 "libinterp/parse-tree/lex.cc"
1302
1303 #define INITIAL 0
1304 #define COMMAND_START 1
1305 #define MATRIX_START 2
1306 #define INPUT_FILE_START 3
1307 #define BLOCK_COMMENT_START 4
1308 #define LINE_COMMENT_START 5
1309 #define DQ_STRING_START 6
1310 #define SQ_STRING_START 7
1311 #define FQ_IDENT_START 8
1312
1313 #ifndef YY_NO_UNISTD_H
1314 /* Special case for "unistd.h", since it is non-ANSI. We include it way
1315 * down here because we want the user's section 1 to have been scanned first.
1316 * The user has a chance to override it with an option.
1317 */
1318 #include <unistd.h>
1319 #endif
1320
1321 #ifndef YY_EXTRA_TYPE
1322 #define YY_EXTRA_TYPE void *
1323 #endif
1324
1325 /* Holds the entire state of the reentrant scanner. */
1326 struct yyguts_t
1327 {
1328
1329 /* User-defined. Not touched by flex. */
1330 YY_EXTRA_TYPE yyextra_r;
1331
1332 /* The rest are the same as the globals declared in the non-reentrant scanner. */
1333 FILE *yyin_r, *yyout_r;
1334 size_t yy_buffer_stack_top; /**< index of top of stack. */
1335 size_t yy_buffer_stack_max; /**< capacity of stack. */
1336 YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
1337 char yy_hold_char;
1338 int yy_n_chars;
1339 int yyleng_r;
1340 char *yy_c_buf_p;
1341 int yy_init;
1342 int yy_start;
1343 int yy_did_buffer_switch_on_eof;
1344 int yy_start_stack_ptr;
1345 int yy_start_stack_depth;
1346 int *yy_start_stack;
1347 yy_state_type yy_last_accepting_state;
1348 char* yy_last_accepting_cpos;
1349
1350 int yylineno_r;
1351 int yy_flex_debug_r;
1352
1353 char *yytext_r;
1354 int yy_more_flag;
1355 int yy_more_len;
1356
1357 YYSTYPE * yylval_r;
1358
1359 }; /* end struct yyguts_t */
1360
1361 static int yy_init_globals ( yyscan_t yyscanner );
1362
1363 /* This must go here because YYSTYPE and YYLTYPE are included
1364 * from bison output in section 1.*/
1365 # define yylval yyg->yylval_r
1366
1367 int yylex_init (yyscan_t* scanner);
1368
1369 int yylex_init_extra ( YY_EXTRA_TYPE user_defined, yyscan_t* scanner);
1370
1371 /* Accessor methods to globals.
1372 These are made visible to non-reentrant scanners for convenience. */
1373
1374 int yylex_destroy ( yyscan_t yyscanner );
1375
1376 int yyget_debug ( yyscan_t yyscanner );
1377
1378 void yyset_debug ( int debug_flag , yyscan_t yyscanner );
1379
1380 YY_EXTRA_TYPE yyget_extra ( yyscan_t yyscanner );
1381
1382 void yyset_extra ( YY_EXTRA_TYPE user_defined , yyscan_t yyscanner );
1383
1384 FILE *yyget_in ( yyscan_t yyscanner );
1385
1386 void yyset_in ( FILE * _in_str , yyscan_t yyscanner );
1387
1388 FILE *yyget_out ( yyscan_t yyscanner );
1389
1390 void yyset_out ( FILE * _out_str , yyscan_t yyscanner );
1391
1392 int yyget_leng ( yyscan_t yyscanner );
1393
1394 char *yyget_text ( yyscan_t yyscanner );
1395
1396 int yyget_lineno ( yyscan_t yyscanner );
1397
1398 void yyset_lineno ( int _line_number , yyscan_t yyscanner );
1399
1400 int yyget_column ( yyscan_t yyscanner );
1401
1402 void yyset_column ( int _column_no , yyscan_t yyscanner );
1403
1404 YYSTYPE * yyget_lval ( yyscan_t yyscanner );
1405
1406 void yyset_lval ( YYSTYPE * yylval_param , yyscan_t yyscanner );
1407
1408 /* Macros after this point can all be overridden by user definitions in
1409 * section 1.
1410 */
1411
1412 #ifndef YY_SKIP_YYWRAP
1413 #ifdef __cplusplus
1414 extern "C" int yywrap ( yyscan_t yyscanner );
1415 #else
1416 extern int yywrap ( yyscan_t yyscanner );
1417 #endif
1418 #endif
1419
1420 #ifndef YY_NO_UNPUT
1421
1422 static void yyunput ( int c, char *buf_ptr , yyscan_t yyscanner);
1423
1424 #endif
1425
1426 #ifndef yytext_ptr
1427 static void yy_flex_strncpy ( char *, const char *, int , yyscan_t yyscanner);
1428 #endif
1429
1430 #ifdef YY_NEED_STRLEN
1431 static int yy_flex_strlen ( const char * , yyscan_t yyscanner);
1432 #endif
1433
1434 #ifndef YY_NO_INPUT
1435 #ifdef __cplusplus
1436 static int yyinput ( yyscan_t yyscanner );
1437 #else
1438 static int input ( yyscan_t yyscanner );
1439 #endif
1440
1441 #endif
1442
1443 /* Amount of stuff to slurp up with each read. */
1444 #ifndef YY_READ_BUF_SIZE
1445 #ifdef __ia64__
1446 /* On IA-64, the buffer size is 16k, not 8k */
1447 #define YY_READ_BUF_SIZE 16384
1448 #else
1449 #define YY_READ_BUF_SIZE 8192
1450 #endif /* __ia64__ */
1451 #endif
1452
1453 /* Copy whatever the last rule matched to the standard output. */
1454 #ifndef ECHO
1455 /* This used to be an fputs(), but since the string might contain NUL's,
1456 * we now use fwrite().
1457 */
1458 #define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)
1459 #endif
1460
1461 /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
1462 * is returned in "result".
1463 */
1464 #ifndef YY_INPUT
1465 #define YY_INPUT(buf,result,max_size) \
1466 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
1467 { \
1468 int c = '*'; \
1469 int n; \
1470 for ( n = 0; n < max_size && \
1471 (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
1472 buf[n] = (char) c; \
1473 if ( c == '\n' ) \
1474 buf[n++] = (char) c; \
1475 if ( c == EOF && ferror( yyin ) ) \
1476 YY_FATAL_ERROR( "input in flex scanner failed" ); \
1477 result = n; \
1478 } \
1479 else \
1480 { \
1481 errno=0; \
1482 while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \
1483 { \
1484 if( errno != EINTR) \
1485 { \
1486 YY_FATAL_ERROR( "input in flex scanner failed" ); \
1487 break; \
1488 } \
1489 errno=0; \
1490 clearerr(yyin); \
1491 } \
1492 }\
1493 \
1494
1495 #endif
1496
1497 /* No semi-colon after return; correct usage is to write "yyterminate();" -
1498 * we don't want an extra ';' after the "return" because that will cause
1499 * some compilers to complain about unreachable statements.
1500 */
1501 #ifndef yyterminate
1502 #define yyterminate() return YY_NULL
1503 #endif
1504
1505 /* Number of entries by which start-condition stack grows. */
1506 #ifndef YY_START_STACK_INCR
1507 #define YY_START_STACK_INCR 25
1508 #endif
1509
1510 /* Report a fatal error. */
1511 #ifndef YY_FATAL_ERROR
1512 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
1513 #endif
1514
1515 /* end tables serialization structures and prototypes */
1516
1517 /* Default declaration of generated scanner - a define so the user can
1518 * easily add parameters.
1519 */
1520 #ifndef YY_DECL
1521 #define YY_DECL_IS_OURS 1
1522
1523 extern int yylex \
1524 (YYSTYPE * yylval_param , yyscan_t yyscanner);
1525
1526 #define YY_DECL int yylex \
1527 (YYSTYPE * yylval_param , yyscan_t yyscanner)
1528 #endif /* !YY_DECL */
1529
1530 /* Code executed at the beginning of each rule, after yytext and yyleng
1531 * have been set up.
1532 */
1533 #ifndef YY_USER_ACTION
1534 #define YY_USER_ACTION
1535 #endif
1536
1537 /* Code executed at the end of each rule. */
1538 #ifndef YY_BREAK
1539 #define YY_BREAK /*LINTED*/break;
1540 #endif
1541
1542 #define YY_RULE_SETUP \
1543 if ( yyleng > 0 ) \
1544 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
1545 (yytext[yyleng - 1] == '\n'); \
1546 YY_USER_ACTION
1547
1548 /** The main scanner function which does all the work.
1549 */
1550 YY_DECL
1551 {
1552 yy_state_type yy_current_state;
1553 char *yy_cp, *yy_bp;
1554 int yy_act;
1555 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
1556
1557 yylval = yylval_param;
1558
1559 if ( !yyg->yy_init )
1560 {
1561 yyg->yy_init = 1;
1562
1563 #ifdef YY_USER_INIT
1564 YY_USER_INIT;
1565 #endif
1566
1567 if ( ! yyg->yy_start )
1568 yyg->yy_start = 1; /* first start state */
1569
1570 if ( ! yyin )
1571 yyin = stdin;
1572
1573 if ( ! yyout )
1574 yyout = stdout;
1575
1576 if ( ! YY_CURRENT_BUFFER ) {
1577 yyensure_buffer_stack (yyscanner);
1578 YY_CURRENT_BUFFER_LVALUE =
1579 yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
1580 }
1581
1582 yy_load_buffer_state( yyscanner );
1583 }
1584
1585 {
1586 #line 342 "../libinterp/parse-tree/lex.ll"
1587
1588
1589
1590 #line 346 "../libinterp/parse-tree/lex.ll"
1591 // Make script and function files start with an invalid token. This makes
1592 // the parser go down a special path.
1593
1594
1595 #line 1596 "libinterp/parse-tree/lex.cc"
1596
1597 while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
1598 {
1599 yy_cp = yyg->yy_c_buf_p;
1600
1601 /* Support of yytext. */
1602 *yy_cp = yyg->yy_hold_char;
1603
1604 /* yy_bp points to the position in yy_ch_buf of the start of
1605 * the current run.
1606 */
1607 yy_bp = yy_cp;
1608
1609 yy_current_state = yyg->yy_start;
1610 yy_current_state += YY_AT_BOL();
1611 yy_match:
1612 do
1613 {
1614 YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
1615 if ( yy_accept[yy_current_state] )
1616 {
1617 yyg->yy_last_accepting_state = yy_current_state;
1618 yyg->yy_last_accepting_cpos = yy_cp;
1619 }
1620 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1621 {
1622 yy_current_state = (int) yy_def[yy_current_state];
1623 if ( yy_current_state >= 308 )
1624 yy_c = yy_meta[yy_c];
1625 }
1626 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
1627 ++yy_cp;
1628 }
1629 while ( yy_base[yy_current_state] != 1050 );
1630
1631 yy_find_action:
1632 yy_act = yy_accept[yy_current_state];
1633 if ( yy_act == 0 )
1634 { /* have to back up */
1635 yy_cp = yyg->yy_last_accepting_cpos;
1636 yy_current_state = yyg->yy_last_accepting_state;
1637 yy_act = yy_accept[yy_current_state];
1638 }
1639
1640 YY_DO_BEFORE_ACTION;
1641
1642 do_action: /* This label is used only to access EOF actions. */
1643
1644 switch ( yy_act )
1645 { /* beginning of action switch */
1646 case 0: /* must back up */
1647 /* undo the effects of YY_DO_BEFORE_ACTION */
1648 *yy_cp = yyg->yy_hold_char;
1649 yy_cp = yyg->yy_last_accepting_cpos;
1650 yy_current_state = yyg->yy_last_accepting_state;
1651 goto yy_find_action;
1652
1653 case 1:
1654 /* rule 1 can match eol */
1655 YY_RULE_SETUP
1656 #line 350 "../libinterp/parse-tree/lex.ll"
1657 {
1658 curr_lexer->lexer_debug ("<INPUT_FILE_START>{ANY_INCLUDING_NL}");
1659
1660 curr_lexer->xunput (yytext[0]);
1661
1662 // May be reset later if we see "function" or "classdef" appears
1663 // as the first token.
1664 curr_lexer->m_reading_script_file = true;
1665
1666 curr_lexer->pop_start_state ();
1667
1668 return curr_lexer->show_token (INPUT_FILE);
1669 }
1670 YY_BREAK
1671 case YY_STATE_EOF(INPUT_FILE_START):
1672 #line 364 "../libinterp/parse-tree/lex.ll"
1673 {
1674 curr_lexer->lexer_debug ("<INPUT_FILE_START><<EOF>>");
1675
1676 // May be reset later if we see "function" or "classdef" appears
1677 // as the first token.
1678 curr_lexer->m_reading_script_file = true;
1679
1680 curr_lexer->pop_start_state ();
1681
1682 return curr_lexer->show_token (INPUT_FILE);
1683 }
1684 YY_BREAK
1685
1686 // Help and other command-style functions.
1687
1688
1689 // Commands can be continued on a second line using the ellipsis.
1690 // If an argument is in construction, it is completed.
1691
1692 case 2:
1693 /* rule 2 can match eol */
1694 YY_RULE_SETUP
1695 #line 385 "../libinterp/parse-tree/lex.ll"
1696 {
1697 curr_lexer->lexer_debug ("<COMMAND_START>(\\.\\.\\.){ANY_EXCEPT_NL}*{NL}");
1698
1699 if (! curr_lexer->m_string_text.empty ())
1700 {
1701 yyless (0);
1702 curr_lexer->m_tok_end = curr_lexer->m_filepos;
1703 return curr_lexer->finish_command_arg ();
1704 }
1705
1706 HANDLE_STRING_CONTINUATION;
1707 }
1708 YY_BREAK
1709
1710 // Commands normally end at the end of a line or a semicolon.
1711
1712 case 3:
1713 /* rule 3 can match eol */
1714 YY_RULE_SETUP
1715 #line 402 "../libinterp/parse-tree/lex.ll"
1716 {
1717 curr_lexer->lexer_debug ("<COMMAND_START>({CCHAR}{ANY_EXCEPT_NL}*)?{NL}");
1718
1719 if (! curr_lexer->m_string_text.empty ())
1720 {
1721 yyless (0);
1722 curr_lexer->m_tok_end = curr_lexer->m_filepos;
1723 return curr_lexer->finish_command_arg ();
1724 }
1725
1726 curr_lexer->update_token_positions (yyleng);
1727
1728 curr_lexer->m_filepos.next_line ();
1729 curr_lexer->m_looking_for_object_index = false;
1730 curr_lexer->m_at_beginning_of_statement = true;
1731 curr_lexer->pop_start_state ();
1732
1733 return curr_lexer->handle_token ('\n');
1734 }
1735 YY_BREAK
1736 case 4:
1737 YY_RULE_SETUP
1738 #line 422 "../libinterp/parse-tree/lex.ll"
1739 {
1740 curr_lexer->lexer_debug ("<COMMAND_START>[\\,\\;]");
1741
1742 if (yytext[0] != ',' || curr_lexer->m_command_arg_paren_count == 0)
1743 {
1744 if (! curr_lexer->m_string_text.empty ())
1745 {
1746 yyless (0);
1747 curr_lexer->m_tok_end = curr_lexer->m_filepos;
1748 return curr_lexer->finish_command_arg ();
1749 }
1750
1751 curr_lexer->update_token_positions (yyleng);
1752
1753 curr_lexer->m_looking_for_object_index = false;
1754 curr_lexer->m_at_beginning_of_statement = true;
1755 curr_lexer->pop_start_state ();
1756
1757 return curr_lexer->handle_token (yytext[0]);
1758 }
1759 else
1760 {
1761 curr_lexer->m_string_text += yytext;
1762 curr_lexer->m_filepos.increment_column (yyleng);
1763 }
1764 }
1765 YY_BREAK
1766
1767 // Unbalanced parentheses serve as pseudo-quotes: they are included in
1768 // the final argument string, but they cause parentheses and quotes to
1769 // be slurped into that argument as well.
1770
1771 case 5:
1772 YY_RULE_SETUP
1773 #line 455 "../libinterp/parse-tree/lex.ll"
1774 {
1775 curr_lexer->lexer_debug ("<COMMAND_START>[\\(\\[\\{]+");
1776
1777 curr_lexer->m_command_arg_paren_count += yyleng;
1778 curr_lexer->m_string_text += yytext;
1779 curr_lexer->m_filepos.increment_column (yyleng);
1780 }
1781 YY_BREAK
1782 case 6:
1783 YY_RULE_SETUP
1784 #line 463 "../libinterp/parse-tree/lex.ll"
1785 {
1786 curr_lexer->lexer_debug ("<COMMAND_START>[\\)\\]\\}]+");
1787
1788 curr_lexer->m_command_arg_paren_count -= yyleng;
1789 curr_lexer->m_string_text += yytext;
1790 curr_lexer->m_filepos.increment_column (yyleng);
1791 }
1792 YY_BREAK
1793
1794 // Handle quoted strings. Quoted strings that are not separated by
1795 // whitespace from other argument text are combined with that previous
1796 // text. For instance,
1797 //
1798 // command 'text1'"text2"
1799 //
1800 // has a single argument text1text2, not two separate arguments.
1801 // That's why we must test to see if we are in command argument mode
1802 // when processing the end of a string.
1803
1804 case 7:
1805 YY_RULE_SETUP
1806 #line 483 "../libinterp/parse-tree/lex.ll"
1807 {
1808 curr_lexer->lexer_debug ("<COMMAND_START>[\\\"\\']");
1809
1810 if (curr_lexer->m_command_arg_paren_count == 0)
1811 curr_lexer->begin_string (yytext[0] == '"'
1812 ? DQ_STRING_START : SQ_STRING_START);
1813 else
1814 curr_lexer->m_string_text += yytext;
1815
1816 curr_lexer->m_filepos.increment_column (yyleng);
1817 }
1818 YY_BREAK
1819
1820 // In standard command argument processing, whitespace separates
1821 // arguments. In the presence of unbalanced parentheses, it is
1822 // incorporated into the argument.
1823
1824 case 8:
1825 YY_RULE_SETUP
1826 #line 501 "../libinterp/parse-tree/lex.ll"
1827 {
1828 curr_lexer->lexer_debug ("<COMMAND_START>{S}*");
1829
1830 if (curr_lexer->m_command_arg_paren_count == 0)
1831 {
1832 if (! curr_lexer->m_string_text.empty ())
1833 {
1834 yyless (0);
1835 curr_lexer->m_tok_end = curr_lexer->m_filepos;
1836 return curr_lexer->finish_command_arg ();
1837 }
1838 }
1839 else
1840 curr_lexer->m_string_text += yytext;
1841
1842 curr_lexer->m_filepos.increment_column (yyleng);
1843 }
1844 YY_BREAK
1845
1846 // Everything else is slurped into the command arguments.
1847
1848 case 9:
1849 YY_RULE_SETUP
1850 #line 523 "../libinterp/parse-tree/lex.ll"
1851 {
1852 curr_lexer->lexer_debug ("<COMMAND_START>([\\.]|[^#% \\t\\r\\n\\.\\,\\;\\\"\\'\\(\\[\\{\\}\\]\\)]*");
1853
1854 curr_lexer->m_string_text += yytext;
1855 curr_lexer->m_filepos.increment_column (yyleng);
1856 }
1857 YY_BREAK
1858
1859 // Whitespace inside matrix lists.
1860
1861 case 10:
1862 YY_RULE_SETUP
1863 #line 534 "../libinterp/parse-tree/lex.ll"
1864 {
1865 curr_lexer->lexer_debug ("<MATRIX_START>{S}*");
1866
1867 curr_lexer->m_filepos.increment_column (yyleng);
1868
1869 curr_lexer->mark_previous_token_trailing_space ();
1870 }
1871 YY_BREAK
1872 case 11:
1873 /* rule 11 can match eol */
1874 YY_RULE_SETUP
1875 #line 542 "../libinterp/parse-tree/lex.ll"
1876 {
1877 curr_lexer->lexer_debug ("<MATRIX_START>{NL}");
1878
1879 curr_lexer->m_filepos.next_line ();
1880
1881 if (curr_lexer->m_nesting_level.is_paren ())
1882 curr_lexer->warn_language_extension ("bare newline inside parentheses");
1883 else
1884 {
1885 int tok = curr_lexer->previous_token_value ();
1886
1887 if (! (tok == ';' || tok == '[' || tok == '{'))
1888 curr_lexer->xunput (';');
1889 }
1890 }
1891 YY_BREAK
1892
1893 // Continuation lines in matrix constants are handled as whitespace.
1894 // Allow arbitrary text after the continuation marker.
1895
1896 case 12:
1897 /* rule 12 can match eol */
1898 YY_RULE_SETUP
1899 #line 563 "../libinterp/parse-tree/lex.ll"
1900 {
1901 curr_lexer->lexer_debug ("<MATRIX_START>\\.\\.\\.{ANY_EXCEPT_NL}*{NL}");
1902
1903 curr_lexer->handle_continuation ();
1904
1905 // Even if there wasn't a space before or after the continuation
1906 // marker, treat the continuation as if it were. But since it will
1907 // be transformed to a separator later anyway, there's no need to
1908 // actually unput a space on the input stream.
1909
1910 curr_lexer->mark_previous_token_trailing_space ();
1911 }
1912 YY_BREAK
1913
1914 // For this and the next two rules, we're looking at ']', and we
1915 // need to know if the next token is '=' or '=='.
1916 //
1917 // It would have been so much easier if the delimiters were simply
1918 // different for the expression on the left hand side of the equals
1919 // operator.
1920 //
1921 // It's also a pain in the ass to decide whether to insert a comma
1922 // after seeing a ']' character...
1923
1924 // FIXME: we need to handle block comments here.
1925
1926 case 13:
1927 YY_RULE_SETUP
1928 #line 590 "../libinterp/parse-tree/lex.ll"
1929 {
1930 curr_lexer->lexer_debug ("<MATRIX_START>\\]");
1931
1932 curr_lexer->update_token_positions (yyleng);
1933 return curr_lexer->handle_close_bracket (']');
1934 }
1935 YY_BREAK
1936
1937 // FIXME: we need to handle block comments here.
1938
1939 case 14:
1940 YY_RULE_SETUP
1941 #line 601 "../libinterp/parse-tree/lex.ll"
1942 {
1943 curr_lexer->lexer_debug ("<MATRIX_START>\\}*");
1944
1945 curr_lexer->update_token_positions (yyleng);
1946 return curr_lexer->handle_close_bracket ('}');
1947 }
1948 YY_BREAK
1949 case 15:
1950 YY_RULE_SETUP
1951 #line 608 "../libinterp/parse-tree/lex.ll"
1952 {
1953 curr_lexer->lexer_debug ("\\[");
1954
1955 bool unput_comma = false;
1956
1957 if (curr_lexer->whitespace_is_significant ()
1958 && curr_lexer->space_follows_previous_token ())
1959 {
1960 int tok = curr_lexer->previous_token_value ();
1961
1962 if (! (tok == '[' || tok == '{'
1963 || curr_lexer->previous_token_is_binop ()))
1964 unput_comma = true;
1965 }
1966
1967 if (unput_comma)
1968 {
1969 yyless (0);
1970 curr_lexer->xunput (',');
1971 }
1972 else
1973 {
1974 curr_lexer->update_token_positions (yyleng);
1975
1976 curr_lexer->m_nesting_level.bracket ();
1977
1978 curr_lexer->m_looking_at_object_index.push_front (false);
1979
1980 curr_lexer->m_looking_for_object_index = false;
1981 curr_lexer->m_at_beginning_of_statement = false;
1982
1983 if (curr_lexer->m_defining_func
1984 && ! curr_lexer->m_parsed_function_name.top ())
1985 curr_lexer->m_looking_at_return_list = true;
1986 else
1987 curr_lexer->m_looking_at_matrix_or_assign_lhs = true;
1988
1989 curr_lexer->m_bracketflag++;
1990
1991 curr_lexer->push_start_state (MATRIX_START);
1992
1993 return curr_lexer->count_token ('[');
1994 }
1995 }
1996 YY_BREAK
1997 case 16:
1998 YY_RULE_SETUP
1999 #line 653 "../libinterp/parse-tree/lex.ll"
2000 {
2001 curr_lexer->lexer_debug ("\\]");
2002
2003 curr_lexer->update_token_positions (yyleng);
2004
2005 curr_lexer->m_nesting_level.remove ();
2006
2007 curr_lexer->m_looking_at_object_index.pop_front ();
2008
2009 curr_lexer->m_looking_for_object_index = true;
2010 curr_lexer->m_at_beginning_of_statement = false;
2011
2012 return curr_lexer->handle_token (']');
2013 }
2014 YY_BREAK
2015
2016 // Gobble comments. Both BLOCK_COMMENT_START and LINE_COMMENT_START
2017 // are exclusive start states. We try to grab a continuous series of
2018 // line-oriented comments as a single collection of comments.
2019
2020
2021 // Start of a block comment. Since comment start states are exclusive,
2022 // this pattern will not match a block comment that immediately follows
2023 // a line-oriented comment. All we need to do is push the matched text
2024 // back on the input stream and push the new start state.
2025
2026 case 17:
2027 /* rule 17 can match eol */
2028 YY_RULE_SETUP
2029 #line 681 "../libinterp/parse-tree/lex.ll"
2030 {
2031 curr_lexer->lexer_debug ("^{S}*{CCHAR}\\{{S}*{NL}");
2032
2033 yyless (0);
2034
2035 curr_lexer->push_start_state (BLOCK_COMMENT_START);
2036 }
2037 YY_BREAK
2038 case 18:
2039 /* rule 18 can match eol */
2040 YY_RULE_SETUP
2041 #line 689 "../libinterp/parse-tree/lex.ll"
2042 {
2043 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>^{S}*{CCHAR}\\{{S}*{NL}");
2044
2045 curr_lexer->m_filepos.next_line ();
2046
2047 if (curr_lexer->m_block_comment_nesting_level)
2048 curr_lexer->m_comment_text = "\n";
2049
2050 curr_lexer->m_block_comment_nesting_level++;
2051
2052 HANDLE_EOB_OR_EOF (-1);
2053 }
2054 YY_BREAK
2055
2056 // End of a block comment. If this block comment is nested inside
2057 // another, wait for the outermost block comment to be closed before
2058 // storing the comment.
2059
2060 // NOTE: This pattern must appear before the one below. Both may match
2061 // the same text and this one should take precedence over the one that
2062 // follows.
2063
2064 case 19:
2065 /* rule 19 can match eol */
2066 YY_RULE_SETUP
2067 #line 712 "../libinterp/parse-tree/lex.ll"
2068 {
2069 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>^{S}*{CCHAR}\\}{S}*{NL}");
2070
2071 curr_lexer->m_filepos.next_line ();
2072
2073 if (curr_lexer->m_block_comment_nesting_level > 1)
2074 curr_lexer->m_comment_text = "\n";
2075 else
2076 curr_lexer->finish_comment (octave::comment_elt::block);
2077
2078 curr_lexer->m_block_comment_nesting_level--;
2079
2080 int status = -1;
2081
2082 if (curr_lexer->m_block_comment_nesting_level == 0)
2083 {
2084 status = -2;
2085
2086 curr_lexer->pop_start_state ();
2087 }
2088
2089 HANDLE_EOB_OR_EOF (status);
2090 }
2091 YY_BREAK
2092
2093 // Body of a block comment.
2094
2095 case 20:
2096 /* rule 20 can match eol */
2097 YY_RULE_SETUP
2098 #line 740 "../libinterp/parse-tree/lex.ll"
2099 {
2100 curr_lexer->lexer_debug ("<BLOCK_COMMENT_START>{ANY_EXCEPT_NL}*{NL}");
2101
2102 curr_lexer->m_filepos.next_line ();
2103 curr_lexer->m_comment_text += yytext;
2104
2105 HANDLE_EOB_OR_EOF (-1);
2106 }
2107 YY_BREAK
2108
2109 // Full-line or end-of-line comment.
2110
2111 case 21:
2112 /* rule 21 can match eol */
2113 YY_RULE_SETUP
2114 #line 753 "../libinterp/parse-tree/lex.ll"
2115 {
2116 curr_lexer->lexer_debug ("{S}*{CCHAR}{ANY_EXCEPT_NL}*{NL}");
2117
2118 curr_lexer->push_start_state (LINE_COMMENT_START);
2119 yyless (0);
2120 }
2121 YY_BREAK
2122
2123 // Beginning of a block comment while we are looking at a series of
2124 // line-oriented comments. Finish previous comment, push current
2125 // text back on input stream, and switch start states.
2126
2127 // NOTE: This pattern must appear before the one below. Both may match
2128 // the same text and this one should take precedence over the one that
2129 // follows.
2130
2131 case 22:
2132 /* rule 22 can match eol */
2133 YY_RULE_SETUP
2134 #line 770 "../libinterp/parse-tree/lex.ll"
2135 {
2136 curr_lexer->lexer_debug ("<LINE_COMMENT_START>^{S}*{CCHAR}\\{{S}*{NL}");
2137
2138 if (! curr_lexer->m_comment_text.empty ())
2139 curr_lexer->finish_comment (octave::comment_elt::full_line);
2140
2141 curr_lexer->pop_start_state ();
2142 curr_lexer->push_start_state (BLOCK_COMMENT_START);
2143 yyless (0);
2144 }
2145 YY_BREAK
2146
2147 // Line-oriented comment. If we are at the beginning of a line, this is
2148 // part of a series of full-line comments. Otherwise, this is an end of
2149 // line comment. We don't need to parse the matched text to determine
2150 // whether we are looking at the start of a block comment as that
2151 // pattern is handled above.
2152
2153 // NOTE: This pattern must appear before the one below. Both may match
2154 // the same text and this one should take precedence over the one that
2155 // follows.
2156
2157 case 23:
2158 /* rule 23 can match eol */
2159 YY_RULE_SETUP
2160 #line 793 "../libinterp/parse-tree/lex.ll"
2161 {
2162 curr_lexer->lexer_debug ("<LINE_COMMENT_START>{S}*{CCHAR}{ANY_EXCEPT_NL}*{NL}");
2163
2164 // Grab text of comment without leading space or comment
2165 // characters.
2166
2167 std::size_t i = 0;
2168 while (i < yyleng && is_space_or_tab (yytext[i]))
2169 i++;
2170
2171 bool have_space = (i > 0);
2172
2173 while (i < yyleng && (yytext[i] == '#' || yytext[i] == '%'))
2174 i++;
2175
2176 curr_lexer->m_comment_text += &yytext[i];
2177
2178 if (curr_lexer->m_filepos.column () == 1)
2179 {
2180 curr_lexer->m_filepos.next_line ();
2181 }
2182 else
2183 {
2184 // End of line comment.
2185
2186 if (have_space)
2187 curr_lexer->mark_previous_token_trailing_space ();
2188
2189 curr_lexer->finish_comment (octave::comment_elt::end_of_line);
2190
2191 curr_lexer->pop_start_state ();
2192
2193 // Push the newline character back on the input and skip
2194 // incrementing the line count so we don't have to duplicate
2195 // all the possible actions that happen with newlines here.
2196
2197 curr_lexer->xunput ('\n');
2198
2199 // The next action should recognize a newline character and set
2200 // the input column back to 1, but we should try to keep the
2201 // input column location accurate anyway, so update here.
2202 curr_lexer->m_filepos.increment_column (yyleng);
2203 }
2204 }
2205 YY_BREAK
2206
2207 // End of a series of full-line because some other character was
2208 // found on the input stream.
2209
2210 case 24:
2211 /* rule 24 can match eol */
2212 YY_RULE_SETUP
2213 #line 843 "../libinterp/parse-tree/lex.ll"
2214 {
2215 curr_lexer->lexer_debug ("<LINE_COMMENT_START>{ANY_INCLUDING_NL}");
2216
2217 if (yytext[0] == '\001')
2218 {
2219 // We are here because we are using the push parser/lexer
2220 // interface and we hit the end of the input buffer or file.
2221 // The special ASCII 1 marker is added to the input by
2222 // push_lexer::fill_flex_buffer.
2223
2224 if (curr_lexer->pending_token_count () > 0)
2225 {
2226 // We are in the middle of parsing a command, expresison,
2227 // etc., so set the return status so that if we are at the
2228 // end of the buffer we'll continue looking for more input,
2229 // possibly buffering a series of line oriented comments as
2230 // a single block.
2231
2232 HANDLE_EOB_OR_EOF (-1);
2233 }
2234 else
2235 {
2236 // We are not in the process of parsing a command,
2237 // expression, etc., so end any current sequence of comments
2238 // with this full line comment, pop the start state and
2239 // return as if we have just finished parsing a complete
2240 // statement.
2241
2242 curr_lexer->finish_comment (octave::comment_elt::full_line);
2243
2244 curr_lexer->pop_start_state ();
2245
2246 HANDLE_EOB_OR_EOF (-2);
2247 }
2248 }
2249 else
2250 {
2251 // End any current sequence of comments, pop the start state,
2252 // and unput the pending input character that ended the series
2253 // of comments.
2254
2255 curr_lexer->finish_comment (octave::comment_elt::full_line);
2256
2257 curr_lexer->pop_start_state ();
2258
2259 curr_lexer->xunput (yytext[0]);
2260 }
2261 }
2262 YY_BREAK
2263
2264 // End of file will also end a series of full-line comments.
2265
2266 case YY_STATE_EOF(LINE_COMMENT_START):
2267 #line 896 "../libinterp/parse-tree/lex.ll"
2268 {
2269 curr_lexer->lexer_debug ("<LINE_COMMENT_START><<EOF>>");
2270
2271 curr_lexer->finish_comment (octave::comment_elt::full_line);
2272
2273 curr_lexer->pop_start_state ();
2274 }
2275 YY_BREAK
2276
2277 // Double-quoted character strings.
2278
2279 case 25:
2280 YY_RULE_SETUP
2281 #line 908 "../libinterp/parse-tree/lex.ll"
2282 {
2283 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\"\\\"");
2284
2285 curr_lexer->m_filepos.increment_column (yyleng);
2286 curr_lexer->m_string_text += '"';
2287 }
2288 YY_BREAK
2289 case 26:
2290 YY_RULE_SETUP
2291 #line 915 "../libinterp/parse-tree/lex.ll"
2292 {
2293 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\"");
2294
2295 // m_tok_beg was set when we started parsing the string.
2296 curr_lexer->m_tok_end = curr_lexer->m_filepos;
2297 curr_lexer->m_filepos.increment_column ();
2298
2299 curr_lexer->pop_start_state ();
2300
2301 if (curr_lexer->start_state() != COMMAND_START)
2302 {
2303 curr_lexer->m_looking_for_object_index = true;
2304 curr_lexer->m_at_beginning_of_statement = false;
2305
2306 curr_lexer->push_token (new octave::token (DQ_STRING,
2307 curr_lexer->m_string_text,
2308 curr_lexer->m_tok_beg,
2309 curr_lexer->m_tok_end));
2310
2311 curr_lexer->m_string_text = "";
2312
2313 return curr_lexer->count_token_internal (DQ_STRING);
2314 }
2315 }
2316 YY_BREAK
2317 case 27:
2318 YY_RULE_SETUP
2319 #line 940 "../libinterp/parse-tree/lex.ll"
2320 {
2321 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\[0-7]{1,3}");
2322
2323 curr_lexer->update_token_positions (yyleng);
2324
2325 unsigned int result;
2326 sscanf (yytext+1, "%o", &result);
2327
2328 if (result > 0xff)
2329 {
2330 // Use location of octal digits for error token.
2331 octave::token *tok
2332 = new octave::token (LEXICAL_ERROR,
2333 "invalid octal escape sequence in character string",
2334 curr_lexer->m_tok_beg, curr_lexer->m_tok_end);
2335
2336 curr_lexer->push_token (tok);
2337
2338 return curr_lexer->count_token_internal (LEXICAL_ERROR);
2339 }
2340 else
2341 curr_lexer->m_string_text += static_cast<unsigned char> (result);
2342 }
2343 YY_BREAK
2344 case 28:
2345 YY_RULE_SETUP
2346 #line 964 "../libinterp/parse-tree/lex.ll"
2347 {
2348 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\x[0-9a-fA-F]+");
2349
2350 curr_lexer->m_filepos.increment_column (yyleng);
2351
2352 unsigned int result;
2353 sscanf (yytext+2, "%x", &result);
2354
2355 // Truncate the value silently instead of checking the range like
2356 // we do for octal above. This is to match C/C++ where any number
2357 // of digits is allowed but the value is implementation-defined if
2358 // it exceeds the range of the character type.
2359 curr_lexer->m_string_text += static_cast<unsigned char> (result);
2360 }
2361 YY_BREAK
2362 case 29:
2363 YY_RULE_SETUP
2364 #line 979 "../libinterp/parse-tree/lex.ll"
2365 {
2366 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\a\"");
2367
2368 curr_lexer->m_filepos.increment_column (yyleng);
2369 curr_lexer->m_string_text += '\a';
2370 }
2371 YY_BREAK
2372 case 30:
2373 YY_RULE_SETUP
2374 #line 986 "../libinterp/parse-tree/lex.ll"
2375 {
2376 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\b\"");
2377
2378 curr_lexer->m_filepos.increment_column (yyleng);
2379 curr_lexer->m_string_text += '\b';
2380 }
2381 YY_BREAK
2382 case 31:
2383 YY_RULE_SETUP
2384 #line 993 "../libinterp/parse-tree/lex.ll"
2385 {
2386 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\f\"");
2387
2388 curr_lexer->m_filepos.increment_column (yyleng);
2389 curr_lexer->m_string_text += '\f';
2390 }
2391 YY_BREAK
2392 case 32:
2393 YY_RULE_SETUP
2394 #line 1000 "../libinterp/parse-tree/lex.ll"
2395 {
2396 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\n\"");
2397
2398 curr_lexer->m_filepos.increment_column (yyleng);
2399 curr_lexer->m_string_text += '\n';
2400 }
2401 YY_BREAK
2402 case 33:
2403 YY_RULE_SETUP
2404 #line 1007 "../libinterp/parse-tree/lex.ll"
2405 {
2406 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\r\"");
2407
2408 curr_lexer->m_filepos.increment_column (yyleng);
2409 curr_lexer->m_string_text += '\r';
2410 }
2411 YY_BREAK
2412 case 34:
2413 YY_RULE_SETUP
2414 #line 1014 "../libinterp/parse-tree/lex.ll"
2415 {
2416 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\t\"");
2417
2418 curr_lexer->m_filepos.increment_column (yyleng);
2419 curr_lexer->m_string_text += '\t';
2420 }
2421 YY_BREAK
2422 case 35:
2423 YY_RULE_SETUP
2424 #line 1021 "../libinterp/parse-tree/lex.ll"
2425 {
2426 curr_lexer->lexer_debug ("<DQ_STRING_START>\"\\\\v\"");
2427
2428 curr_lexer->m_filepos.increment_column (yyleng);
2429 curr_lexer->m_string_text += '\v';
2430 }
2431 YY_BREAK
2432 case 36:
2433 /* rule 36 can match eol */
2434 YY_RULE_SETUP
2435 #line 1028 "../libinterp/parse-tree/lex.ll"
2436 {
2437 curr_lexer->lexer_debug ("<DQ_STRING_START>(\\.\\.\\.){S}*{NL}");
2438
2439 static const char *msg = "'...' continuations in double-quoted character strings are obsolete and will not be allowed in a future version of Octave; please use '\\' instead";
2440
2441 std::string nm = curr_lexer->m_fcn_file_full_name;
2442
2443 if (nm.empty ())
2444 warning_with_id ("Octave:deprecated-syntax", "%s", msg);
2445 else
2446 warning_with_id ("Octave:deprecated-syntax",
2447 "%s; near line %d of file '%s'", msg,
2448 curr_lexer->m_filepos.line (), nm.c_str ());
2449
2450 HANDLE_STRING_CONTINUATION;
2451 }
2452 YY_BREAK
2453 case 37:
2454 /* rule 37 can match eol */
2455 YY_RULE_SETUP
2456 #line 1045 "../libinterp/parse-tree/lex.ll"
2457 {
2458 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\{S}+{NL}");
2459
2460 static const char *msg = "white space and comments after continuation markers in double-quoted character strings are obsolete and will not be allowed in a future version of Octave";
2461
2462 std::string nm = curr_lexer->m_fcn_file_full_name;
2463
2464 if (nm.empty ())
2465 warning_with_id ("Octave:deprecated-syntax", "%s", msg);
2466 else
2467 warning_with_id ("Octave:deprecated-syntax",
2468 "%s; near line %d of file '%s'", msg,
2469 curr_lexer->m_filepos.line (), nm.c_str ());
2470
2471 HANDLE_STRING_CONTINUATION;
2472 }
2473 YY_BREAK
2474 case 38:
2475 /* rule 38 can match eol */
2476 YY_RULE_SETUP
2477 #line 1062 "../libinterp/parse-tree/lex.ll"
2478 {
2479 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\{NL}");
2480
2481 HANDLE_STRING_CONTINUATION;
2482 }
2483 YY_BREAK
2484 case 39:
2485 YY_RULE_SETUP
2486 #line 1068 "../libinterp/parse-tree/lex.ll"
2487 {
2488 curr_lexer->lexer_debug ("<DQ_STRING_START>\\\\.");
2489
2490 curr_lexer->m_filepos.increment_column (yyleng);
2491 curr_lexer->m_string_text += yytext[1];
2492 }
2493 YY_BREAK
2494 case 40:
2495 YY_RULE_SETUP
2496 #line 1075 "../libinterp/parse-tree/lex.ll"
2497 {
2498 curr_lexer->lexer_debug ("<DQ_STRING_START>\\.");
2499
2500 curr_lexer->m_filepos.increment_column ();
2501 curr_lexer->m_string_text += yytext[0];
2502 }
2503 YY_BREAK
2504 case 41:
2505 YY_RULE_SETUP
2506 #line 1082 "../libinterp/parse-tree/lex.ll"
2507 {
2508 curr_lexer->lexer_debug ("<DQ_STRING_START>[^\\.\\\\\\r\\n\\\"]+");
2509
2510 curr_lexer->m_filepos.increment_column (yyleng);
2511 curr_lexer->m_string_text += yytext;
2512 }
2513 YY_BREAK
2514 case 42:
2515 /* rule 42 can match eol */
2516 YY_RULE_SETUP
2517 #line 1089 "../libinterp/parse-tree/lex.ll"
2518 {
2519 curr_lexer->lexer_debug ("<DQ_STRING_START>{NL}");
2520
2521 // Use current file position for error token.
2522 octave::token *tok
2523 = new octave::token (LEXICAL_ERROR,
2524 "unterminated character string constant",
2525 curr_lexer->m_filepos, curr_lexer->m_filepos);
2526
2527 curr_lexer->push_token (tok);
2528
2529 curr_lexer->m_filepos.next_line ();
2530
2531 return curr_lexer->count_token_internal (LEXICAL_ERROR);
2532 }
2533 YY_BREAK
2534
2535 // Single-quoted character strings.
2536
2537 case 43:
2538 YY_RULE_SETUP
2539 #line 1109 "../libinterp/parse-tree/lex.ll"
2540 {
2541 curr_lexer->lexer_debug ("<SQ_STRING_START>\\'\\'");
2542
2543 curr_lexer->m_filepos.increment_column (yyleng);
2544 curr_lexer->m_string_text += '\'';
2545 }
2546 YY_BREAK
2547 case 44:
2548 YY_RULE_SETUP
2549 #line 1116 "../libinterp/parse-tree/lex.ll"
2550 {
2551 curr_lexer->lexer_debug ("<SQ_STRING_START>\\'");
2552
2553 // m_tok_beg was set when we started parsing the string.
2554 curr_lexer->m_tok_end = curr_lexer->m_filepos;
2555 curr_lexer->m_filepos.increment_column ();
2556
2557 curr_lexer->pop_start_state ();
2558
2559 if (curr_lexer->start_state() != COMMAND_START)
2560 {
2561 curr_lexer->m_looking_for_object_index = true;
2562 curr_lexer->m_at_beginning_of_statement = false;
2563
2564 curr_lexer->push_token (new octave::token (SQ_STRING,
2565 curr_lexer->m_string_text,
2566 curr_lexer->m_tok_beg,
2567 curr_lexer->m_tok_end));
2568
2569 curr_lexer->m_string_text = "";
2570
2571 return curr_lexer->count_token_internal (SQ_STRING);
2572 }
2573 }
2574 YY_BREAK
2575 case 45:
2576 YY_RULE_SETUP
2577 #line 1141 "../libinterp/parse-tree/lex.ll"
2578 {
2579 curr_lexer->lexer_debug ("<SQ_STRING_START>[^\\'\\n\\r]+");
2580
2581 curr_lexer->m_filepos.increment_column (yyleng);
2582 curr_lexer->m_string_text += yytext;
2583 }
2584 YY_BREAK
2585 case 46:
2586 /* rule 46 can match eol */
2587 YY_RULE_SETUP
2588 #line 1148 "../libinterp/parse-tree/lex.ll"
2589 {
2590 curr_lexer->lexer_debug ("<SQ_STRING_START>{NL}");
2591
2592 // Use current file position for error token.
2593 octave::token *tok
2594 = new octave::token (LEXICAL_ERROR,
2595 "unterminated character string constant",
2596 curr_lexer->m_filepos, curr_lexer->m_filepos);
2597
2598 curr_lexer->push_token (tok);
2599
2600 curr_lexer->m_filepos.next_line ();
2601
2602 return curr_lexer->count_token_internal (LEXICAL_ERROR);
2603 }
2604 YY_BREAK
2605
2606 // Fully-qualified identifiers (used for classdef).
2607
2608 case 47:
2609 YY_RULE_SETUP
2610 #line 1168 "../libinterp/parse-tree/lex.ll"
2611 {
2612 curr_lexer->lexer_debug ("<FQ_IDENT_START>{FQIDENT}{S}*");
2613
2614 curr_lexer->pop_start_state ();
2615
2616 curr_lexer->update_token_positions (yyleng);
2617
2618 int id_tok = curr_lexer->handle_fq_identifier ();
2619
2620 if (id_tok >= 0)
2621 {
2622 curr_lexer->m_looking_for_object_index = true;
2623
2624 return curr_lexer->count_token_internal (id_tok);
2625 }
2626 }
2627 YY_BREAK
2628 case 48:
2629 YY_RULE_SETUP
2630 #line 1185 "../libinterp/parse-tree/lex.ll"
2631 {
2632 curr_lexer->lexer_debug ("<FQ_IDENT_START>{S}+");
2633
2634 curr_lexer->m_filepos.increment_column (yyleng);
2635
2636 curr_lexer->mark_previous_token_trailing_space ();
2637 }
2638 YY_BREAK
2639 case 49:
2640 /* rule 49 can match eol */
2641 YY_RULE_SETUP
2642 #line 1193 "../libinterp/parse-tree/lex.ll"
2643 {
2644 curr_lexer->lexer_debug ("<FQ_IDENT_START>(\\.\\.\\.){ANY_EXCEPT_NL}*{NL}");
2645
2646 curr_lexer->m_filepos.next_line ();
2647 }
2648 YY_BREAK
2649 case 50:
2650 /* rule 50 can match eol */
2651 YY_RULE_SETUP
2652 #line 1199 "../libinterp/parse-tree/lex.ll"
2653 {
2654 curr_lexer->lexer_debug ("<FQ_IDENT_START>{ANY_INCLUDING_NL}");
2655
2656 // If input doesn't match FQIDENT, return char and go to previous
2657 // start state.
2658
2659 yyless (0);
2660 curr_lexer->pop_start_state ();
2661 }
2662 YY_BREAK
2663
2664 // Imaginary numbers.
2665
2666 case 51:
2667 YY_RULE_SETUP
2668 #line 1213 "../libinterp/parse-tree/lex.ll"
2669 {
2670 curr_lexer->lexer_debug ("{NUMBER}{Im}");
2671
2672 if (curr_lexer->previous_token_may_be_command ()
2673 && curr_lexer->space_follows_previous_token ())
2674 {
2675 yyless (0);
2676 curr_lexer->push_start_state (COMMAND_START);
2677 }
2678 else
2679 {
2680 int tok = curr_lexer->previous_token_value ();
2681
2682 if (curr_lexer->whitespace_is_significant ()
2683 && curr_lexer->space_follows_previous_token ()
2684 && ! (tok == '[' || tok == '{'
2685 || curr_lexer->previous_token_is_binop ()))
2686 {
2687 yyless (0);
2688 curr_lexer->xunput (',');
2689 }
2690 else
2691 {
2692 curr_lexer->handle_number ();
2693 return curr_lexer->count_token_internal (IMAG_NUM);
2694 }
2695 }
2696 }
2697 YY_BREAK
2698
2699 // Real numbers. Don't grab the '.' part of a dot operator as part of
2700 // the constant.
2701
2702 case 52:
2703 *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
2704 yyg->yy_c_buf_p = yy_cp -= 2;
2705 YY_DO_BEFORE_ACTION; /* set up yytext again */
2706 #line 1248 "../libinterp/parse-tree/lex.ll"
2707 case 53:
2708 YY_RULE_SETUP
2709 #line 1248 "../libinterp/parse-tree/lex.ll"
2710 {
2711 curr_lexer->lexer_debug ("{D}{D_}*/\\.[\\*/\\\\^\\']|{NUMBER}");
2712
2713 if (curr_lexer->previous_token_may_be_command ()
2714 && curr_lexer->space_follows_previous_token ())
2715 {
2716 yyless (0);
2717 curr_lexer->push_start_state (COMMAND_START);
2718 }
2719 else
2720 {
2721 int tok = curr_lexer->previous_token_value ();
2722
2723 if (curr_lexer->whitespace_is_significant ()
2724 && curr_lexer->space_follows_previous_token ()
2725 && ! (tok == '[' || tok == '{'
2726 || curr_lexer->previous_token_is_binop ()))
2727 {
2728 yyless (0);
2729 curr_lexer->xunput (',');
2730 }
2731 else
2732 {
2733 curr_lexer->handle_number ();
2734 return curr_lexer->count_token_internal (NUM);
2735 }
2736 }
2737 }
2738 YY_BREAK
2739
2740 // Eat whitespace. Whitespace inside matrix constants is handled by
2741 // the <MATRIX_START> start state code above.
2742
2743 case 54:
2744 YY_RULE_SETUP
2745 #line 1282 "../libinterp/parse-tree/lex.ll"
2746 {
2747 curr_lexer->m_filepos.increment_column (yyleng);
2748
2749 curr_lexer->mark_previous_token_trailing_space ();
2750 }
2751 YY_BREAK
2752
2753 // Continuation lines. Allow arbitrary text after continuations.
2754
2755 case 55:
2756 /* rule 55 can match eol */
2757 YY_RULE_SETUP
2758 #line 1292 "../libinterp/parse-tree/lex.ll"
2759 {
2760 curr_lexer->lexer_debug ("\\.\\.\\.{ANY_EXCEPT_NL}*{NL}");
2761
2762 curr_lexer->handle_continuation ();
2763 }
2764 YY_BREAK
2765
2766 // Deprecated C preprocessor style continuation markers.
2767
2768 case 56:
2769 /* rule 56 can match eol */
2770 #line 1303 "../libinterp/parse-tree/lex.ll"
2771 case 57:
2772 /* rule 57 can match eol */
2773 YY_RULE_SETUP
2774 #line 1303 "../libinterp/parse-tree/lex.ll"
2775 {
2776 curr_lexer->lexer_debug ("\\\\{S}*{NL}|\\\\{S}*{CCHAR}{ANY_EXCEPT_NL}*{NL}");
2777
2778 static const char *msg = "using continuation marker \\ outside of double quoted strings is deprecated and will be removed from a future version of Octave, use ... instead";
2779
2780 std::string nm = curr_lexer->m_fcn_file_full_name;
2781
2782 if (nm.empty ())
2783 warning_with_id ("Octave:deprecated-syntax", "%s", msg);
2784 else
2785 warning_with_id ("Octave:deprecated-syntax",
2786 "%s; near line %d of file '%s'", msg,
2787 curr_lexer->m_filepos.line (), nm.c_str ());
2788
2789 curr_lexer->handle_continuation ();
2790 }
2791 YY_BREAK
2792
2793 // End of file.
2794
2795 case YY_STATE_EOF(INITIAL):
2796 case YY_STATE_EOF(COMMAND_START):
2797 case YY_STATE_EOF(MATRIX_START):
2798 case YY_STATE_EOF(BLOCK_COMMENT_START):
2799 case YY_STATE_EOF(DQ_STRING_START):
2800 case YY_STATE_EOF(SQ_STRING_START):
2801 case YY_STATE_EOF(FQ_IDENT_START):
2802 #line 1324 "../libinterp/parse-tree/lex.ll"
2803 {
2804 return curr_lexer->handle_end_of_input ();
2805 }
2806 YY_BREAK
2807
2808 // Identifiers.
2809
2810 // Don't allow get and set to be recognized as keywords if they are
2811 // followed by "(".
2812
2813 case 58:
2814 YY_RULE_SETUP
2815 #line 1335 "../libinterp/parse-tree/lex.ll"
2816 {
2817 HANDLE_IDENTIFIER ("(set|get){S}*\\(", true);
2818 }
2819 YY_BREAK
2820 case 59:
2821 YY_RULE_SETUP
2822 #line 1339 "../libinterp/parse-tree/lex.ll"
2823 {
2824 HANDLE_IDENTIFIER ("{IDENT}", false);
2825 }
2826 YY_BREAK
2827
2828 // Superclass method identifiers.
2829
2830 case 60:
2831 YY_RULE_SETUP
2832 #line 1347 "../libinterp/parse-tree/lex.ll"
2833 {
2834 curr_lexer->lexer_debug ("{FQIDENT}{S}*@{S}*{FQIDENT}");
2835
2836 if (curr_lexer->previous_token_may_be_command ())
2837 {
2838 yyless (0);
2839 curr_lexer->push_start_state (COMMAND_START);
2840 }
2841 else
2842 {
2843 if (curr_lexer->m_at_beginning_of_statement)
2844 {
2845 std::string txt = yytext;
2846
2847 std::size_t at_or_dot_pos = txt.find_first_of ("@.");
2848
2849 if (at_or_dot_pos != std::string::npos)
2850 {
2851 std::size_t spc_pos = txt.find_first_of (" \t");
2852
2853 if (spc_pos != std::string::npos && spc_pos < at_or_dot_pos)
2854 {
2855 yyless (spc_pos);
2856 curr_lexer->m_filepos.increment_column (spc_pos);
2857
2858 return curr_lexer->handle_identifier ();
2859 }
2860 }
2861 }
2862
2863 curr_lexer->m_looking_for_object_index = true;
2864 curr_lexer->m_at_beginning_of_statement = false;
2865
2866 return curr_lexer->handle_superclass_identifier ();
2867 }
2868 }
2869 YY_BREAK
2870
2871 // Metaclass query
2872
2873 case 61:
2874 YY_RULE_SETUP
2875 #line 1388 "../libinterp/parse-tree/lex.ll"
2876 {
2877 curr_lexer->lexer_debug ("\\?{S}*{FQIDENT}");
2878
2879 if (curr_lexer->previous_token_may_be_command ()
2880 && curr_lexer->space_follows_previous_token ())
2881 {
2882 yyless (0);
2883 curr_lexer->push_start_state (COMMAND_START);
2884 }
2885 else
2886 {
2887 curr_lexer->update_token_positions (yyleng);
2888
2889 int id_tok = curr_lexer->handle_meta_identifier ();
2890
2891 if (id_tok >= 0)
2892 {
2893 curr_lexer->m_looking_for_object_index = true;
2894
2895 return curr_lexer->count_token_internal (id_tok);
2896 }
2897 }
2898 }
2899 YY_BREAK
2900 case 62:
2901 #line 1413 "../libinterp/parse-tree/lex.ll"
2902 case 63:
2903 YY_RULE_SETUP
2904 #line 1413 "../libinterp/parse-tree/lex.ll"
2905 {
2906 curr_lexer->lexer_debug ("\\@|\\@{S}*{FQIDENT}");
2907
2908 if (curr_lexer->previous_token_may_be_command ()
2909 && curr_lexer->space_follows_previous_token ())
2910 {
2911 yyless (0);
2912 curr_lexer->push_start_state (COMMAND_START);
2913 }
2914 else
2915 {
2916 int tok_val = curr_lexer->previous_token_value ();
2917
2918 if (curr_lexer->whitespace_is_significant ()
2919 && curr_lexer->space_follows_previous_token ()
2920 && ! (tok_val == '[' || tok_val == '{'
2921 || curr_lexer->previous_token_is_binop ()))
2922 {
2923 yyless (0);
2924 curr_lexer->xunput (',');
2925 }
2926 else
2927 {
2928 curr_lexer->update_token_positions (yyleng);
2929
2930 curr_lexer->m_at_beginning_of_statement = false;
2931
2932 std::string ident = yytext;
2933
2934 if (ident == "@")
2935 {
2936 curr_lexer->m_looking_at_function_handle++;
2937 curr_lexer->m_looking_for_object_index = false;
2938
2939 return curr_lexer->count_token ('@');
2940 }
2941 else
2942 {
2943 ident = ident.substr (1);
2944 ident.erase (std::remove_if (ident.begin (), ident.end (),
2945 is_space_or_tab), ident.end ());
2946
2947 octave::token *tok;
2948
2949 if (octave::iskeyword (ident))
2950 tok = new octave::token (LEXICAL_ERROR,
2951 "function handles may not refer to keywords",
2952 curr_lexer->m_tok_beg,
2953 curr_lexer->m_tok_end);
2954 else
2955 {
2956 curr_lexer->m_looking_for_object_index = true;
2957
2958 tok = new octave::token (FCN_HANDLE, ident,
2959 curr_lexer->m_tok_beg,
2960 curr_lexer->m_tok_end);
2961 }
2962
2963 curr_lexer->push_token (tok);
2964
2965 return curr_lexer->count_token_internal (tok->token_value ());
2966 }
2967 }
2968 }
2969 }
2970 YY_BREAK
2971
2972 // A new line character. New line characters inside matrix constants
2973 // are handled by the <MATRIX_START> start state code above. If closest
2974 // nesting is inside parentheses, don't return a row separator.
2975
2976 case 64:
2977 /* rule 64 can match eol */
2978 YY_RULE_SETUP
2979 #line 1485 "../libinterp/parse-tree/lex.ll"
2980 {
2981 curr_lexer->lexer_debug ("{NL}");
2982
2983 if (curr_lexer->m_nesting_level.is_paren ())
2984 {
2985 curr_lexer->m_filepos.next_line ();
2986
2987 curr_lexer->m_at_beginning_of_statement = false;
2988 curr_lexer->warn_language_extension
2989 ("bare newline inside parentheses");
2990 }
2991 else if (curr_lexer->m_nesting_level.none ()
2992 || curr_lexer->m_nesting_level.is_anon_fcn_body ())
2993 {
2994 curr_lexer->update_token_positions (yyleng);
2995 curr_lexer->m_filepos.next_line ();
2996
2997 curr_lexer->m_at_beginning_of_statement = true;
2998
2999 return curr_lexer->count_token ('\n');
3000 }
3001 else if (curr_lexer->m_nesting_level.is_bracket_or_brace ())
3002 {
3003 curr_lexer->update_token_positions (yyleng);
3004 curr_lexer->m_filepos.next_line ();
3005
3006 // Use current file position for error token.
3007 octave::token *tok
3008 = new octave::token (LEXICAL_ERROR,
3009 "unexpected internal lexer error",
3010 curr_lexer->m_filepos, curr_lexer->m_filepos);
3011
3012 curr_lexer->push_token (tok);
3013
3014 return curr_lexer->count_token_internal (LEXICAL_ERROR);
3015 }
3016 }
3017 YY_BREAK
3018
3019 // Single quote can either be the beginning of a string or a transpose
3020 // operator.
3021
3022 case 65:
3023 YY_RULE_SETUP
3024 #line 1528 "../libinterp/parse-tree/lex.ll"
3025 {
3026 curr_lexer->lexer_debug ("'");
3027
3028 if (curr_lexer->previous_token_may_be_command ()
3029 && curr_lexer->space_follows_previous_token ())
3030 {
3031 curr_lexer->m_filepos.increment_column ();
3032 curr_lexer->push_start_state (COMMAND_START);
3033 curr_lexer->begin_string (SQ_STRING_START);
3034 }
3035 else if (curr_lexer->m_at_beginning_of_statement)
3036 {
3037 curr_lexer->m_filepos.increment_column ();
3038 curr_lexer->begin_string (SQ_STRING_START);
3039 }
3040 else
3041 {
3042 int tok = curr_lexer->previous_token_value ();
3043
3044 if (curr_lexer->whitespace_is_significant ())
3045 {
3046 if (curr_lexer->space_follows_previous_token ())
3047 {
3048 if (tok == '[' || tok == '{'
3049 || curr_lexer->previous_token_is_binop ())
3050 {
3051 curr_lexer->m_filepos.increment_column ();
3052 curr_lexer->begin_string (SQ_STRING_START);
3053 }
3054 else
3055 {
3056 yyless (0);
3057 curr_lexer->xunput (',');
3058 }
3059 }
3060 else
3061 {
3062 if (tok == '[' || tok == '{'
3063 || curr_lexer->previous_token_is_binop ()
3064 || curr_lexer->previous_token_is_keyword ())
3065 {
3066 curr_lexer->m_filepos.increment_column ();
3067 curr_lexer->begin_string (SQ_STRING_START);
3068 }
3069 else
3070 {
3071 curr_lexer->m_filepos.increment_column ();
3072 return curr_lexer->count_token (HERMITIAN);
3073 }
3074 }
3075 }
3076 else
3077 {
3078 if (! tok || tok == '[' || tok == '{' || tok == '('
3079 || curr_lexer->previous_token_is_binop ()
3080 || curr_lexer->previous_token_is_keyword ())
3081 {
3082 curr_lexer->m_filepos.increment_column ();
3083 curr_lexer->begin_string (SQ_STRING_START);
3084 }
3085 else
3086 {
3087 curr_lexer->m_filepos.increment_column ();
3088 return curr_lexer->count_token (HERMITIAN);
3089 }
3090 }
3091 }
3092 }
3093 YY_BREAK
3094
3095 // Double quotes always begin strings.
3096
3097 case 66:
3098 YY_RULE_SETUP
3099 #line 1601 "../libinterp/parse-tree/lex.ll"
3100 {
3101 curr_lexer->lexer_debug ("\\\"");
3102
3103 if (curr_lexer->previous_token_may_be_command ()
3104 && curr_lexer->space_follows_previous_token ())
3105 {
3106 curr_lexer->m_filepos.increment_column ();
3107 curr_lexer->push_start_state (COMMAND_START);
3108 curr_lexer->begin_string (DQ_STRING_START);
3109 }
3110 else
3111 {
3112 int tok = curr_lexer->previous_token_value ();
3113
3114 if (curr_lexer->whitespace_is_significant ())
3115 {
3116 if (curr_lexer->space_follows_previous_token ())
3117 {
3118 if (tok == '[' || tok == '{'
3119 || curr_lexer->previous_token_is_binop ())
3120 {
3121 curr_lexer->m_filepos.increment_column ();
3122 curr_lexer->begin_string (DQ_STRING_START);
3123 }
3124 else
3125 {
3126 yyless (0);
3127 curr_lexer->xunput (',');
3128 }
3129 }
3130 else
3131 {
3132 curr_lexer->m_filepos.increment_column ();
3133 curr_lexer->begin_string (DQ_STRING_START);
3134 }
3135 }
3136 else
3137 {
3138 curr_lexer->m_filepos.increment_column ();
3139 curr_lexer->begin_string (DQ_STRING_START);
3140 }
3141 }
3142 }
3143 YY_BREAK
3144
3145 // Other operators.
3146
3147 case 67:
3148 YY_RULE_SETUP
3149 #line 1649 "../libinterp/parse-tree/lex.ll"
3150 { CMD_OR_OP (":", ':', true); }
3151 YY_BREAK
3152 case 68:
3153 YY_RULE_SETUP
3154 #line 1650 "../libinterp/parse-tree/lex.ll"
3155 { CMD_OR_OP (".+", EPLUS, false); }
3156 YY_BREAK
3157 case 69:
3158 YY_RULE_SETUP
3159 #line 1651 "../libinterp/parse-tree/lex.ll"
3160 { CMD_OR_OP (".-", EMINUS, false); }
3161 YY_BREAK
3162 case 70:
3163 YY_RULE_SETUP
3164 #line 1652 "../libinterp/parse-tree/lex.ll"
3165 { CMD_OR_OP (".*", EMUL, true); }
3166 YY_BREAK
3167 case 71:
3168 YY_RULE_SETUP
3169 #line 1653 "../libinterp/parse-tree/lex.ll"
3170 { CMD_OR_OP ("./", EDIV, true); }
3171 YY_BREAK
3172 case 72:
3173 YY_RULE_SETUP
3174 #line 1654 "../libinterp/parse-tree/lex.ll"
3175 { CMD_OR_OP (".\\", ELEFTDIV, true); }
3176 YY_BREAK
3177 case 73:
3178 YY_RULE_SETUP
3179 #line 1655 "../libinterp/parse-tree/lex.ll"
3180 { CMD_OR_OP (".^", EPOW, true); }
3181 YY_BREAK
3182 case 74:
3183 YY_RULE_SETUP
3184 #line 1656 "../libinterp/parse-tree/lex.ll"
3185 { CMD_OR_OP (".**", EPOW, false); }
3186 YY_BREAK
3187 case 75:
3188 YY_RULE_SETUP
3189 #line 1657 "../libinterp/parse-tree/lex.ll"
3190 { CMD_OR_OP ("<=", EXPR_LE, true); }
3191 YY_BREAK
3192 case 76:
3193 YY_RULE_SETUP
3194 #line 1658 "../libinterp/parse-tree/lex.ll"
3195 { CMD_OR_OP ("==", EXPR_EQ, true); }
3196 YY_BREAK
3197 case 77:
3198 YY_RULE_SETUP
3199 #line 1659 "../libinterp/parse-tree/lex.ll"
3200 { CMD_OR_OP ("!=", EXPR_NE, false); }
3201 YY_BREAK
3202 case 78:
3203 YY_RULE_SETUP
3204 #line 1660 "../libinterp/parse-tree/lex.ll"
3205 { CMD_OR_OP ("~=", EXPR_NE, true); }
3206 YY_BREAK
3207 case 79:
3208 YY_RULE_SETUP
3209 #line 1661 "../libinterp/parse-tree/lex.ll"
3210 { CMD_OR_OP (">=", EXPR_GE, true); }
3211 YY_BREAK
3212 case 80:
3213 YY_RULE_SETUP
3214 #line 1662 "../libinterp/parse-tree/lex.ll"
3215 { CMD_OR_OP ("&", EXPR_AND, true); }
3216 YY_BREAK
3217 case 81:
3218 YY_RULE_SETUP
3219 #line 1663 "../libinterp/parse-tree/lex.ll"
3220 { CMD_OR_OP ("|", EXPR_OR, true); }
3221 YY_BREAK
3222 case 82:
3223 YY_RULE_SETUP
3224 #line 1664 "../libinterp/parse-tree/lex.ll"
3225 { CMD_OR_OP ("<", EXPR_LT, true); }
3226 YY_BREAK
3227 case 83:
3228 YY_RULE_SETUP
3229 #line 1665 "../libinterp/parse-tree/lex.ll"
3230 { CMD_OR_OP (">", EXPR_GT, true); }
3231 YY_BREAK
3232 case 84:
3233 YY_RULE_SETUP
3234 #line 1666 "../libinterp/parse-tree/lex.ll"
3235 { CMD_OR_OP ("*", '*', true); }
3236 YY_BREAK
3237 case 85:
3238 YY_RULE_SETUP
3239 #line 1667 "../libinterp/parse-tree/lex.ll"
3240 { CMD_OR_OP ("/", '/', true); }
3241 YY_BREAK
3242
3243 // In Matlab, '\' may also trigger command syntax.
3244
3245 case 86:
3246 YY_RULE_SETUP
3247 #line 1673 "../libinterp/parse-tree/lex.ll"
3248 {
3249 curr_lexer->lexer_debug ("\\");
3250
3251 return curr_lexer->handle_op (LEFTDIV);
3252 }
3253 YY_BREAK
3254 case 87:
3255 YY_RULE_SETUP
3256 #line 1679 "../libinterp/parse-tree/lex.ll"
3257 { CMD_OR_OP ("^", POW, true); }
3258 YY_BREAK
3259 case 88:
3260 YY_RULE_SETUP
3261 #line 1680 "../libinterp/parse-tree/lex.ll"
3262 { CMD_OR_OP ("**", POW, false); }
3263 YY_BREAK
3264 case 89:
3265 YY_RULE_SETUP
3266 #line 1681 "../libinterp/parse-tree/lex.ll"
3267 { CMD_OR_OP ("&&", EXPR_AND_AND, true); }
3268 YY_BREAK
3269 case 90:
3270 YY_RULE_SETUP
3271 #line 1682 "../libinterp/parse-tree/lex.ll"
3272 { CMD_OR_OP ("||", EXPR_OR_OR, true); }
3273 YY_BREAK
3274 case 91:
3275 YY_RULE_SETUP
3276 #line 1684 "../libinterp/parse-tree/lex.ll"
3277 {
3278 curr_lexer->lexer_debug (";");
3279
3280 bool at_beginning_of_statement
3281 = (! (curr_lexer->whitespace_is_significant ()
3282 || curr_lexer->m_looking_at_object_index.front ()));
3283
3284 return curr_lexer->handle_op (';', at_beginning_of_statement);
3285 }
3286 YY_BREAK
3287 case 92:
3288 YY_RULE_SETUP
3289 #line 1694 "../libinterp/parse-tree/lex.ll"
3290 { CMD_OR_UNARY_OP ("+", '+', true); }
3291 YY_BREAK
3292 case 93:
3293 YY_RULE_SETUP
3294 #line 1695 "../libinterp/parse-tree/lex.ll"
3295 { CMD_OR_UNARY_OP ("-", '-', true); }
3296 YY_BREAK
3297 case 94:
3298 YY_RULE_SETUP
3299 #line 1697 "../libinterp/parse-tree/lex.ll"
3300 { CMD_OR_UNARY_OP ("~", EXPR_NOT, true); }
3301 YY_BREAK
3302 case 95:
3303 YY_RULE_SETUP
3304 #line 1698 "../libinterp/parse-tree/lex.ll"
3305 { CMD_OR_UNARY_OP ("!", EXPR_NOT, false); }
3306 YY_BREAK
3307 case 96:
3308 YY_RULE_SETUP
3309 #line 1700 "../libinterp/parse-tree/lex.ll"
3310 {
3311 curr_lexer->lexer_debug (",");
3312
3313 bool at_beginning_of_statement
3314 = (! (curr_lexer->whitespace_is_significant ()
3315 || curr_lexer->m_looking_at_object_index.front ()));
3316
3317 return curr_lexer->handle_op (',', at_beginning_of_statement);
3318 }
3319 YY_BREAK
3320 case 97:
3321 YY_RULE_SETUP
3322 #line 1710 "../libinterp/parse-tree/lex.ll"
3323 {
3324 curr_lexer->lexer_debug (".'");
3325
3326 return curr_lexer->handle_op (TRANSPOSE);
3327 }
3328 YY_BREAK
3329 case 98:
3330 YY_RULE_SETUP
3331 #line 1716 "../libinterp/parse-tree/lex.ll"
3332 { CMD_OR_UNARY_OP ("++", PLUS_PLUS, false); }
3333 YY_BREAK
3334 case 99:
3335 YY_RULE_SETUP
3336 #line 1717 "../libinterp/parse-tree/lex.ll"
3337 { CMD_OR_UNARY_OP ("--", MINUS_MINUS, false); }
3338 YY_BREAK
3339 case 100:
3340 YY_RULE_SETUP
3341 #line 1719 "../libinterp/parse-tree/lex.ll"
3342 {
3343 curr_lexer->lexer_debug ("(");
3344
3345 bool unput_comma = false;
3346
3347 if (curr_lexer->whitespace_is_significant ()
3348 && curr_lexer->space_follows_previous_token ())
3349 {
3350 int tok = curr_lexer->previous_token_value ();
3351
3352 if (! (tok == '[' || tok == '{'
3353 || curr_lexer->previous_token_is_binop ()))
3354 unput_comma = true;
3355 }
3356
3357 if (unput_comma)
3358 {
3359 yyless (0);
3360 curr_lexer->xunput (',');
3361 }
3362 else
3363 {
3364 curr_lexer->update_token_positions (yyleng);
3365
3366 // If we are looking for an object index, then push TRUE for
3367 // m_looking_at_object_index. Otherwise, just push whatever state
3368 // is current (so that we can pop it off the stack when we find
3369 // the matching close paren).
3370
3371 curr_lexer->m_looking_at_object_index.push_front
3372 (curr_lexer->m_looking_for_object_index);
3373
3374 curr_lexer->m_looking_at_indirect_ref = false;
3375 curr_lexer->m_looking_for_object_index = false;
3376 curr_lexer->m_at_beginning_of_statement = false;
3377
3378 curr_lexer->m_nesting_level.paren ();
3379
3380 return curr_lexer->handle_token ('(');
3381 }
3382 }
3383 YY_BREAK
3384 case 101:
3385 YY_RULE_SETUP
3386 #line 1761 "../libinterp/parse-tree/lex.ll"
3387 {
3388 curr_lexer->lexer_debug (")");
3389
3390 curr_lexer->update_token_positions (yyleng);
3391
3392 curr_lexer->m_nesting_level.remove ();
3393
3394 curr_lexer->m_looking_at_object_index.pop_front ();
3395
3396 curr_lexer->m_looking_for_object_index = true;
3397 curr_lexer->m_at_beginning_of_statement = false;
3398
3399 if (curr_lexer->m_looking_at_anon_fcn_args)
3400 {
3401 curr_lexer->m_looking_at_anon_fcn_args = false;
3402 curr_lexer->m_nesting_level.anon_fcn_body ();
3403 }
3404
3405 return curr_lexer->count_token (')');
3406 }
3407 YY_BREAK
3408 case 102:
3409 YY_RULE_SETUP
3410 #line 1782 "../libinterp/parse-tree/lex.ll"
3411 {
3412 curr_lexer->lexer_debug (".");
3413
3414 if (curr_lexer->previous_token_may_be_command ()
3415 && curr_lexer->space_follows_previous_token ())
3416 {
3417 yyless (0);
3418 curr_lexer->push_start_state (COMMAND_START);
3419 }
3420 else
3421 {
3422 curr_lexer->update_token_positions (yyleng);
3423
3424 curr_lexer->m_looking_for_object_index = false;
3425 curr_lexer->m_at_beginning_of_statement = false;
3426
3427 return curr_lexer->handle_token ('.');
3428 }
3429 }
3430 YY_BREAK
3431
3432 // = and op= operators.
3433
3434 case 103:
3435 YY_RULE_SETUP
3436 #line 1806 "../libinterp/parse-tree/lex.ll"
3437 {
3438 curr_lexer->lexer_debug ("=");
3439
3440 curr_lexer->maybe_mark_previous_token_as_variable ();
3441
3442 return curr_lexer->handle_op ('=');
3443 }
3444 YY_BREAK
3445 case 104:
3446 YY_RULE_SETUP
3447 #line 1814 "../libinterp/parse-tree/lex.ll"
3448 { CMD_OR_COMPUTED_ASSIGN_OP ("+=", ADD_EQ); }
3449 YY_BREAK
3450 case 105:
3451 YY_RULE_SETUP
3452 #line 1815 "../libinterp/parse-tree/lex.ll"
3453 { CMD_OR_COMPUTED_ASSIGN_OP ("-=", SUB_EQ); }
3454 YY_BREAK
3455 case 106:
3456 YY_RULE_SETUP
3457 #line 1816 "../libinterp/parse-tree/lex.ll"
3458 { CMD_OR_COMPUTED_ASSIGN_OP ("*=", MUL_EQ); }
3459 YY_BREAK
3460 case 107:
3461 YY_RULE_SETUP
3462 #line 1817 "../libinterp/parse-tree/lex.ll"
3463 { CMD_OR_COMPUTED_ASSIGN_OP ("/=", DIV_EQ); }
3464 YY_BREAK
3465 case 108:
3466 YY_RULE_SETUP
3467 #line 1818 "../libinterp/parse-tree/lex.ll"
3468 { CMD_OR_COMPUTED_ASSIGN_OP ("\\=", LEFTDIV_EQ); }
3469 YY_BREAK
3470 case 109:
3471 YY_RULE_SETUP
3472 #line 1819 "../libinterp/parse-tree/lex.ll"
3473 { CMD_OR_COMPUTED_ASSIGN_OP (".+=", ADD_EQ); }
3474 YY_BREAK
3475 case 110:
3476 YY_RULE_SETUP
3477 #line 1820 "../libinterp/parse-tree/lex.ll"
3478 { CMD_OR_COMPUTED_ASSIGN_OP (".-=", SUB_EQ); }
3479 YY_BREAK
3480 case 111:
3481 YY_RULE_SETUP
3482 #line 1821 "../libinterp/parse-tree/lex.ll"
3483 { CMD_OR_COMPUTED_ASSIGN_OP (".*=", EMUL_EQ); }
3484 YY_BREAK
3485 case 112:
3486 YY_RULE_SETUP
3487 #line 1822 "../libinterp/parse-tree/lex.ll"
3488 { CMD_OR_COMPUTED_ASSIGN_OP ("./=", EDIV_EQ); }
3489 YY_BREAK
3490 case 113:
3491 YY_RULE_SETUP
3492 #line 1823 "../libinterp/parse-tree/lex.ll"
3493 { CMD_OR_COMPUTED_ASSIGN_OP (".\\=", ELEFTDIV_EQ); }
3494 YY_BREAK
3495 case 114:
3496 YY_RULE_SETUP
3497 #line 1824 "../libinterp/parse-tree/lex.ll"
3498 { CMD_OR_COMPUTED_ASSIGN_OP ("^=", POW_EQ); }
3499 YY_BREAK
3500 case 115:
3501 YY_RULE_SETUP
3502 #line 1825 "../libinterp/parse-tree/lex.ll"
3503 { CMD_OR_COMPUTED_ASSIGN_OP ("^=", POW_EQ); }
3504 YY_BREAK
3505 case 116:
3506 YY_RULE_SETUP
3507 #line 1826 "../libinterp/parse-tree/lex.ll"
3508 { CMD_OR_COMPUTED_ASSIGN_OP (".^=", EPOW_EQ); }
3509 YY_BREAK
3510 case 117:
3511 YY_RULE_SETUP
3512 #line 1827 "../libinterp/parse-tree/lex.ll"
3513 { CMD_OR_COMPUTED_ASSIGN_OP (".^=", EPOW_EQ); }
3514 YY_BREAK
3515 case 118:
3516 YY_RULE_SETUP
3517 #line 1828 "../libinterp/parse-tree/lex.ll"
3518 { CMD_OR_COMPUTED_ASSIGN_OP ("&=", AND_EQ); }
3519 YY_BREAK
3520 case 119:
3521 YY_RULE_SETUP
3522 #line 1829 "../libinterp/parse-tree/lex.ll"
3523 { CMD_OR_COMPUTED_ASSIGN_OP ("|=", OR_EQ); }
3524 YY_BREAK
3525
3526 // In Matlab, '{' may also trigger command syntax.
3527
3528 case 120:
3529 YY_RULE_SETUP
3530 #line 1835 "../libinterp/parse-tree/lex.ll"
3531 {
3532 curr_lexer->lexer_debug ("{");
3533
3534 bool unput_comma = false;
3535
3536 if (curr_lexer->whitespace_is_significant ()
3537 && curr_lexer->space_follows_previous_token ())
3538 {
3539 int tok = curr_lexer->previous_token_value ();
3540
3541 if (! (tok == '[' || tok == '{'
3542 || curr_lexer->previous_token_is_binop ()))
3543 unput_comma = true;
3544 }
3545
3546 if (unput_comma)
3547 {
3548 yyless (0);
3549 curr_lexer->xunput (',');
3550 }
3551 else
3552 {
3553 curr_lexer->m_nesting_level.brace ();
3554
3555 curr_lexer->m_looking_at_object_index.push_front
3556 (curr_lexer->m_looking_for_object_index);
3557
3558 curr_lexer->m_filepos.increment_column (yyleng);
3559 curr_lexer->m_looking_for_object_index = false;
3560 curr_lexer->m_at_beginning_of_statement = false;
3561
3562 curr_lexer->m_braceflag++;
3563
3564 curr_lexer->push_start_state (MATRIX_START);
3565
3566 return curr_lexer->count_token ('{');
3567 }
3568 }
3569 YY_BREAK
3570 case 121:
3571 YY_RULE_SETUP
3572 #line 1874 "../libinterp/parse-tree/lex.ll"
3573 {
3574 curr_lexer->lexer_debug ("}");
3575
3576 curr_lexer->update_token_positions (yyleng);
3577
3578 curr_lexer->m_looking_at_object_index.pop_front ();
3579
3580 curr_lexer->m_looking_for_object_index = true;
3581 curr_lexer->m_at_beginning_of_statement = false;
3582
3583 curr_lexer->m_nesting_level.remove ();
3584
3585 return curr_lexer->handle_token ('}');
3586 }
3587 YY_BREAK
3588
3589 // Unrecognized input is a lexical error.
3590
3591 case 122:
3592 YY_RULE_SETUP
3593 #line 1893 "../libinterp/parse-tree/lex.ll"
3594 {
3595 curr_lexer->lexer_debug (".");
3596
3597 curr_lexer->xunput (yytext[0]);
3598
3599 int c = curr_lexer->text_yyinput ();
3600
3601 if (c == 1)
3602 return -1;
3603 else if (c == EOF)
3604 return curr_lexer->handle_end_of_input ();
3605 else
3606 {
3607 std::ostringstream buf;
3608
3609 buf << "invalid character '"
3610 << octave::undo_string_escape (static_cast<char> (c))
3611 << "' (ASCII " << c << ")";
3612
3613 // Use current file position for error token.
3614 octave::token *tok
3615 = new octave::token (LEXICAL_ERROR, buf.str (),
3616 curr_lexer->m_filepos, curr_lexer->m_filepos);
3617
3618 curr_lexer->push_token (tok);
3619
3620 curr_lexer->m_filepos.increment_column ();
3621
3622 return curr_lexer->count_token_internal (LEXICAL_ERROR);
3623 }
3624 }
3625 YY_BREAK
3626
3627 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
3628 // Disable these warnings for flex code.
3629 # pragma GCC diagnostic ignored "-Wold-style-cast"
3630 # pragma GCC diagnostic ignored "-Wunused-parameter"
3631 #endif
3632
3633 case 123:
3634 YY_RULE_SETUP
3635 #line 1933 "../libinterp/parse-tree/lex.ll"
3636 ECHO;
3637 YY_BREAK
3638 #line 3639 "libinterp/parse-tree/lex.cc"
3639
3640 case YY_END_OF_BUFFER:
3641 {
3642 /* Amount of text matched not including the EOB char. */
3643 int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
3644
3645 /* Undo the effects of YY_DO_BEFORE_ACTION. */
3646 *yy_cp = yyg->yy_hold_char;
3647 YY_RESTORE_YY_MORE_OFFSET
3648
3649 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
3650 {
3651 /* We're scanning a new file or input source. It's
3652 * possible that this happened because the user
3653 * just pointed yyin at a new source and called
3654 * yylex(). If so, then we have to assure
3655 * consistency between YY_CURRENT_BUFFER and our
3656 * globals. Here is the right place to do so, because
3657 * this is the first action (other than possibly a
3658 * back-up) that will match for the new input source.
3659 */
3660 yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
3661 YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
3662 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
3663 }
3664
3665 /* Note that here we test for yy_c_buf_p "<=" to the position
3666 * of the first EOB in the buffer, since yy_c_buf_p will
3667 * already have been incremented past the NUL character
3668 * (since all states make transitions on EOB to the
3669 * end-of-buffer state). Contrast this with the test
3670 * in input().
3671 */
3672 if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
3673 { /* This was really a NUL. */
3674 yy_state_type yy_next_state;
3675
3676 yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
3677
3678 yy_current_state = yy_get_previous_state( yyscanner );
3679
3680 /* Okay, we're now positioned to make the NUL
3681 * transition. We couldn't have
3682 * yy_get_previous_state() go ahead and do it
3683 * for us because it doesn't know how to deal
3684 * with the possibility of jamming (and we don't
3685 * want to build jamming into it because then it
3686 * will run more slowly).
3687 */
3688
3689 yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
3690
3691 yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
3692
3693 if ( yy_next_state )
3694 {
3695 /* Consume the NUL. */
3696 yy_cp = ++yyg->yy_c_buf_p;
3697 yy_current_state = yy_next_state;
3698 goto yy_match;
3699 }
3700
3701 else
3702 {
3703 yy_cp = yyg->yy_c_buf_p;
3704 goto yy_find_action;
3705 }
3706 }
3707
3708 else switch ( yy_get_next_buffer( yyscanner ) )
3709 {
3710 case EOB_ACT_END_OF_FILE:
3711 {
3712 yyg->yy_did_buffer_switch_on_eof = 0;
3713
3714 if ( yywrap( yyscanner ) )
3715 {
3716 /* Note: because we've taken care in
3717 * yy_get_next_buffer() to have set up
3718 * yytext, we can now set up
3719 * yy_c_buf_p so that if some total
3720 * hoser (like flex itself) wants to
3721 * call the scanner after we return the
3722 * YY_NULL, it'll still work - another
3723 * YY_NULL will get returned.
3724 */
3725 yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
3726
3727 yy_act = YY_STATE_EOF(YY_START);
3728 goto do_action;
3729 }
3730
3731 else
3732 {
3733 if ( ! yyg->yy_did_buffer_switch_on_eof )
3734 YY_NEW_FILE;
3735 }
3736 break;
3737 }
3738
3739 case EOB_ACT_CONTINUE_SCAN:
3740 yyg->yy_c_buf_p =
3741 yyg->yytext_ptr + yy_amount_of_matched_text;
3742
3743 yy_current_state = yy_get_previous_state( yyscanner );
3744
3745 yy_cp = yyg->yy_c_buf_p;
3746 yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
3747 goto yy_match;
3748
3749 case EOB_ACT_LAST_MATCH:
3750 yyg->yy_c_buf_p =
3751 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
3752
3753 yy_current_state = yy_get_previous_state( yyscanner );
3754
3755 yy_cp = yyg->yy_c_buf_p;
3756 yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
3757 goto yy_find_action;
3758 }
3759 break;
3760 }
3761
3762 default:
3763 YY_FATAL_ERROR(
3764 "fatal flex scanner internal error--no action found" );
3765 } /* end of action switch */
3766 } /* end of scanning one token */
3767 } /* end of user's declarations */
3768 } /* end of yylex */
3769
3770 /* yy_get_next_buffer - try to read in a new buffer
3771 *
3772 * Returns a code representing an action:
3773 * EOB_ACT_LAST_MATCH -
3774 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
3775 * EOB_ACT_END_OF_FILE - end of file
3776 */
3777 static int yy_get_next_buffer (yyscan_t yyscanner)
3778 {
3779 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
3780 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
3781 char *source = yyg->yytext_ptr;
3782 int number_to_move, i;
3783 int ret_val;
3784
3785 if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
3786 YY_FATAL_ERROR(
3787 "fatal flex scanner internal error--end of buffer missed" );
3788
3789 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
3790 { /* Don't try to fill the buffer, so this is an EOF. */
3791 if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
3792 {
3793 /* We matched a single character, the EOB, so
3794 * treat this as a final EOF.
3795 */
3796 return EOB_ACT_END_OF_FILE;
3797 }
3798
3799 else
3800 {
3801 /* We matched some text prior to the EOB, first
3802 * process it.
3803 */
3804 return EOB_ACT_LAST_MATCH;
3805 }
3806 }
3807
3808 /* Try to read more data. */
3809
3810 /* First move last chars to start of buffer. */
3811 number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr - 1);
3812
3813 for ( i = 0; i < number_to_move; ++i )
3814 *(dest++) = *(source++);
3815
3816 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
3817 /* don't do the read, it's not guaranteed to return an EOF,
3818 * just force an EOF
3819 */
3820 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
3821
3822 else
3823 {
3824 int num_to_read =
3825 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
3826
3827 while ( num_to_read <= 0 )
3828 { /* Not enough room in the buffer - grow it. */
3829
3830 /* just a shorter name for the current buffer */
3831 YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
3832
3833 int yy_c_buf_p_offset =
3834 (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
3835
3836 if ( b->yy_is_our_buffer )
3837 {
3838 int new_size = b->yy_buf_size * 2;
3839
3840 if ( new_size <= 0 )
3841 b->yy_buf_size += b->yy_buf_size / 8;
3842 else
3843 b->yy_buf_size *= 2;
3844
3845 b->yy_ch_buf = (char *)
3846 /* Include room in for 2 EOB chars. */
3847 yyrealloc( (void *) b->yy_ch_buf,
3848 (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
3849 }
3850 else
3851 /* Can't grow it, we don't own it. */
3852 b->yy_ch_buf = NULL;
3853
3854 if ( ! b->yy_ch_buf )
3855 YY_FATAL_ERROR(
3856 "fatal error - scanner input buffer overflow" );
3857
3858 yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
3859
3860 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
3861 number_to_move - 1;
3862
3863 }
3864
3865 if ( num_to_read > YY_READ_BUF_SIZE )
3866 num_to_read = YY_READ_BUF_SIZE;
3867
3868 /* Read in more data. */
3869 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
3870 yyg->yy_n_chars, num_to_read );
3871
3872 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
3873 }
3874
3875 if ( yyg->yy_n_chars == 0 )
3876 {
3877 if ( number_to_move == YY_MORE_ADJ )
3878 {
3879 ret_val = EOB_ACT_END_OF_FILE;
3880 yyrestart( yyin , yyscanner);
3881 }
3882
3883 else
3884 {
3885 ret_val = EOB_ACT_LAST_MATCH;
3886 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
3887 YY_BUFFER_EOF_PENDING;
3888 }
3889 }
3890
3891 else
3892 ret_val = EOB_ACT_CONTINUE_SCAN;
3893
3894 if ((yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
3895 /* Extend the array by 50%, plus the number we really need. */
3896 int new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
3897 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(
3898 (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size , yyscanner );
3899 if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
3900 YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
3901 /* "- 2" to take care of EOB's */
3902 YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);
3903 }
3904
3905 yyg->yy_n_chars += number_to_move;
3906 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
3907 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
3908
3909 yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
3910
3911 return ret_val;
3912 }
3913
3914 /* yy_get_previous_state - get the state just before the EOB char was reached */
3915
yy_get_previous_state(yyscan_t yyscanner)3916 static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
3917 {
3918 yy_state_type yy_current_state;
3919 char *yy_cp;
3920 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
3921
3922 yy_current_state = yyg->yy_start;
3923 yy_current_state += YY_AT_BOL();
3924
3925 for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
3926 {
3927 YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
3928 if ( yy_accept[yy_current_state] )
3929 {
3930 yyg->yy_last_accepting_state = yy_current_state;
3931 yyg->yy_last_accepting_cpos = yy_cp;
3932 }
3933 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
3934 {
3935 yy_current_state = (int) yy_def[yy_current_state];
3936 if ( yy_current_state >= 308 )
3937 yy_c = yy_meta[yy_c];
3938 }
3939 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
3940 }
3941
3942 return yy_current_state;
3943 }
3944
3945 /* yy_try_NUL_trans - try to make a transition on the NUL character
3946 *
3947 * synopsis
3948 * next_state = yy_try_NUL_trans( current_state );
3949 */
yy_try_NUL_trans(yy_state_type yy_current_state,yyscan_t yyscanner)3950 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
3951 {
3952 int yy_is_jam;
3953 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
3954 char *yy_cp = yyg->yy_c_buf_p;
3955
3956 YY_CHAR yy_c = 1;
3957 if ( yy_accept[yy_current_state] )
3958 {
3959 yyg->yy_last_accepting_state = yy_current_state;
3960 yyg->yy_last_accepting_cpos = yy_cp;
3961 }
3962 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
3963 {
3964 yy_current_state = (int) yy_def[yy_current_state];
3965 if ( yy_current_state >= 308 )
3966 yy_c = yy_meta[yy_c];
3967 }
3968 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
3969 yy_is_jam = (yy_current_state == 307);
3970
3971 (void)yyg;
3972 return yy_is_jam ? 0 : yy_current_state;
3973 }
3974
3975 #ifndef YY_NO_UNPUT
3976
yyunput(int c,char * yy_bp,yyscan_t yyscanner)3977 static void yyunput (int c, char * yy_bp , yyscan_t yyscanner)
3978 {
3979 char *yy_cp;
3980 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
3981
3982 yy_cp = yyg->yy_c_buf_p;
3983
3984 /* undo effects of setting up yytext */
3985 *yy_cp = yyg->yy_hold_char;
3986
3987 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
3988 { /* need to shift things up to make room */
3989 /* +2 for EOB chars. */
3990 int number_to_move = yyg->yy_n_chars + 2;
3991 char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
3992 YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
3993 char *source =
3994 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
3995
3996 while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
3997 *--dest = *--source;
3998
3999 yy_cp += (int) (dest - source);
4000 yy_bp += (int) (dest - source);
4001 YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
4002 yyg->yy_n_chars = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
4003
4004 if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
4005 YY_FATAL_ERROR( "flex scanner push-back overflow" );
4006 }
4007
4008 *--yy_cp = (char) c;
4009
4010 yyg->yytext_ptr = yy_bp;
4011 yyg->yy_hold_char = *yy_cp;
4012 yyg->yy_c_buf_p = yy_cp;
4013 }
4014
4015 #endif
4016
4017 #ifndef YY_NO_INPUT
4018 #ifdef __cplusplus
yyinput(yyscan_t yyscanner)4019 static int yyinput (yyscan_t yyscanner)
4020 #else
4021 static int input (yyscan_t yyscanner)
4022 #endif
4023
4024 {
4025 int c;
4026 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4027
4028 *yyg->yy_c_buf_p = yyg->yy_hold_char;
4029
4030 if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
4031 {
4032 /* yy_c_buf_p now points to the character we want to return.
4033 * If this occurs *before* the EOB characters, then it's a
4034 * valid NUL; if not, then we've hit the end of the buffer.
4035 */
4036 if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
4037 /* This was really a NUL. */
4038 *yyg->yy_c_buf_p = '\0';
4039
4040 else
4041 { /* need more input */
4042 int offset = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr);
4043 ++yyg->yy_c_buf_p;
4044
4045 switch ( yy_get_next_buffer( yyscanner ) )
4046 {
4047 case EOB_ACT_LAST_MATCH:
4048 /* This happens because yy_g_n_b()
4049 * sees that we've accumulated a
4050 * token and flags that we need to
4051 * try matching the token before
4052 * proceeding. But for input(),
4053 * there's no matching to consider.
4054 * So convert the EOB_ACT_LAST_MATCH
4055 * to EOB_ACT_END_OF_FILE.
4056 */
4057
4058 /* Reset buffer status. */
4059 yyrestart( yyin , yyscanner);
4060
4061 /*FALLTHROUGH*/
4062
4063 case EOB_ACT_END_OF_FILE:
4064 {
4065 if ( yywrap( yyscanner ) )
4066 return 0;
4067
4068 if ( ! yyg->yy_did_buffer_switch_on_eof )
4069 YY_NEW_FILE;
4070 #ifdef __cplusplus
4071 return yyinput(yyscanner);
4072 #else
4073 return input(yyscanner);
4074 #endif
4075 }
4076
4077 case EOB_ACT_CONTINUE_SCAN:
4078 yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
4079 break;
4080 }
4081 }
4082 }
4083
4084 c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
4085 *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
4086 yyg->yy_hold_char = *++yyg->yy_c_buf_p;
4087
4088 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
4089
4090 return c;
4091 }
4092 #endif /* ifndef YY_NO_INPUT */
4093
4094 /** Immediately switch to a different input stream.
4095 * @param input_file A readable stream.
4096 * @param yyscanner The scanner object.
4097 * @note This function does not reset the start condition to @c INITIAL .
4098 */
yyrestart(FILE * input_file,yyscan_t yyscanner)4099 void yyrestart (FILE * input_file , yyscan_t yyscanner)
4100 {
4101 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4102
4103 if ( ! YY_CURRENT_BUFFER ){
4104 yyensure_buffer_stack (yyscanner);
4105 YY_CURRENT_BUFFER_LVALUE =
4106 yy_create_buffer( yyin, YY_BUF_SIZE , yyscanner);
4107 }
4108
4109 yy_init_buffer( YY_CURRENT_BUFFER, input_file , yyscanner);
4110 yy_load_buffer_state( yyscanner );
4111 }
4112
4113 /** Switch to a different input buffer.
4114 * @param new_buffer The new input buffer.
4115 * @param yyscanner The scanner object.
4116 */
yy_switch_to_buffer(YY_BUFFER_STATE new_buffer,yyscan_t yyscanner)4117 void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
4118 {
4119 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4120
4121 /* TODO. We should be able to replace this entire function body
4122 * with
4123 * yypop_buffer_state();
4124 * yypush_buffer_state(new_buffer);
4125 */
4126 yyensure_buffer_stack (yyscanner);
4127 if ( YY_CURRENT_BUFFER == new_buffer )
4128 return;
4129
4130 if ( YY_CURRENT_BUFFER )
4131 {
4132 /* Flush out information for old buffer. */
4133 *yyg->yy_c_buf_p = yyg->yy_hold_char;
4134 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
4135 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
4136 }
4137
4138 YY_CURRENT_BUFFER_LVALUE = new_buffer;
4139 yy_load_buffer_state( yyscanner );
4140
4141 /* We don't actually know whether we did this switch during
4142 * EOF (yywrap()) processing, but the only time this flag
4143 * is looked at is after yywrap() is called, so it's safe
4144 * to go ahead and always set it.
4145 */
4146 yyg->yy_did_buffer_switch_on_eof = 1;
4147 }
4148
yy_load_buffer_state(yyscan_t yyscanner)4149 static void yy_load_buffer_state (yyscan_t yyscanner)
4150 {
4151 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4152 yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
4153 yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
4154 yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
4155 yyg->yy_hold_char = *yyg->yy_c_buf_p;
4156 }
4157
4158 /** Allocate and initialize an input buffer state.
4159 * @param file A readable stream.
4160 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
4161 * @param yyscanner The scanner object.
4162 * @return the allocated buffer state.
4163 */
yy_create_buffer(FILE * file,int size,yyscan_t yyscanner)4164 YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
4165 {
4166 YY_BUFFER_STATE b;
4167
4168 b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
4169 if ( ! b )
4170 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
4171
4172 b->yy_buf_size = size;
4173
4174 /* yy_ch_buf has to be 2 characters longer than the size given because
4175 * we need to put in 2 end-of-buffer characters.
4176 */
4177 b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) , yyscanner );
4178 if ( ! b->yy_ch_buf )
4179 YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
4180
4181 b->yy_is_our_buffer = 1;
4182
4183 yy_init_buffer( b, file , yyscanner);
4184
4185 return b;
4186 }
4187
4188 /** Destroy the buffer.
4189 * @param b a buffer created with yy_create_buffer()
4190 * @param yyscanner The scanner object.
4191 */
yy_delete_buffer(YY_BUFFER_STATE b,yyscan_t yyscanner)4192 void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
4193 {
4194 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4195
4196 if ( ! b )
4197 return;
4198
4199 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
4200 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
4201
4202 if ( b->yy_is_our_buffer )
4203 yyfree( (void *) b->yy_ch_buf , yyscanner );
4204
4205 yyfree( (void *) b , yyscanner );
4206 }
4207
4208 /* Initializes or reinitializes a buffer.
4209 * This function is sometimes called more than once on the same buffer,
4210 * such as during a yyrestart() or at EOF.
4211 */
yy_init_buffer(YY_BUFFER_STATE b,FILE * file,yyscan_t yyscanner)4212 static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
4213
4214 {
4215 int oerrno = errno;
4216 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4217
4218 yy_flush_buffer( b , yyscanner);
4219
4220 b->yy_input_file = file;
4221 b->yy_fill_buffer = 1;
4222
4223 /* If b is the current buffer, then yy_init_buffer was _probably_
4224 * called from yyrestart() or through yy_get_next_buffer.
4225 * In that case, we don't want to reset the lineno or column.
4226 */
4227 if (b != YY_CURRENT_BUFFER){
4228 b->yy_bs_lineno = 1;
4229 b->yy_bs_column = 0;
4230 }
4231
4232 b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
4233
4234 errno = oerrno;
4235 }
4236
4237 /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
4238 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
4239 * @param yyscanner The scanner object.
4240 */
yy_flush_buffer(YY_BUFFER_STATE b,yyscan_t yyscanner)4241 void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
4242 {
4243 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4244 if ( ! b )
4245 return;
4246
4247 b->yy_n_chars = 0;
4248
4249 /* We always need two end-of-buffer characters. The first causes
4250 * a transition to the end-of-buffer state. The second causes
4251 * a jam in that state.
4252 */
4253 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
4254 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
4255
4256 b->yy_buf_pos = &b->yy_ch_buf[0];
4257
4258 b->yy_at_bol = 1;
4259 b->yy_buffer_status = YY_BUFFER_NEW;
4260
4261 if ( b == YY_CURRENT_BUFFER )
4262 yy_load_buffer_state( yyscanner );
4263 }
4264
4265 /** Pushes the new state onto the stack. The new state becomes
4266 * the current state. This function will allocate the stack
4267 * if necessary.
4268 * @param new_buffer The new state.
4269 * @param yyscanner The scanner object.
4270 */
yypush_buffer_state(YY_BUFFER_STATE new_buffer,yyscan_t yyscanner)4271 void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
4272 {
4273 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4274 if (new_buffer == NULL)
4275 return;
4276
4277 yyensure_buffer_stack(yyscanner);
4278
4279 /* This block is copied from yy_switch_to_buffer. */
4280 if ( YY_CURRENT_BUFFER )
4281 {
4282 /* Flush out information for old buffer. */
4283 *yyg->yy_c_buf_p = yyg->yy_hold_char;
4284 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
4285 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
4286 }
4287
4288 /* Only push if top exists. Otherwise, replace top. */
4289 if (YY_CURRENT_BUFFER)
4290 yyg->yy_buffer_stack_top++;
4291 YY_CURRENT_BUFFER_LVALUE = new_buffer;
4292
4293 /* copied from yy_switch_to_buffer. */
4294 yy_load_buffer_state( yyscanner );
4295 yyg->yy_did_buffer_switch_on_eof = 1;
4296 }
4297
4298 /** Removes and deletes the top of the stack, if present.
4299 * The next element becomes the new top.
4300 * @param yyscanner The scanner object.
4301 */
yypop_buffer_state(yyscan_t yyscanner)4302 void yypop_buffer_state (yyscan_t yyscanner)
4303 {
4304 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4305 if (!YY_CURRENT_BUFFER)
4306 return;
4307
4308 yy_delete_buffer(YY_CURRENT_BUFFER , yyscanner);
4309 YY_CURRENT_BUFFER_LVALUE = NULL;
4310 if (yyg->yy_buffer_stack_top > 0)
4311 --yyg->yy_buffer_stack_top;
4312
4313 if (YY_CURRENT_BUFFER) {
4314 yy_load_buffer_state( yyscanner );
4315 yyg->yy_did_buffer_switch_on_eof = 1;
4316 }
4317 }
4318
4319 /* Allocates the stack if it does not exist.
4320 * Guarantees space for at least one push.
4321 */
yyensure_buffer_stack(yyscan_t yyscanner)4322 static void yyensure_buffer_stack (yyscan_t yyscanner)
4323 {
4324 yy_size_t num_to_alloc;
4325 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4326
4327 if (!yyg->yy_buffer_stack) {
4328
4329 /* First allocation is just for 2 elements, since we don't know if this
4330 * scanner will even need a stack. We use 2 instead of 1 to avoid an
4331 * immediate realloc on the next call.
4332 */
4333 num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
4334 yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
4335 (num_to_alloc * sizeof(struct yy_buffer_state*)
4336 , yyscanner);
4337 if ( ! yyg->yy_buffer_stack )
4338 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
4339
4340 memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
4341
4342 yyg->yy_buffer_stack_max = num_to_alloc;
4343 yyg->yy_buffer_stack_top = 0;
4344 return;
4345 }
4346
4347 if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
4348
4349 /* Increase the buffer to prepare for a possible push. */
4350 yy_size_t grow_size = 8 /* arbitrary grow size */;
4351
4352 num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
4353 yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
4354 (yyg->yy_buffer_stack,
4355 num_to_alloc * sizeof(struct yy_buffer_state*)
4356 , yyscanner);
4357 if ( ! yyg->yy_buffer_stack )
4358 YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
4359
4360 /* zero only the new slots.*/
4361 memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
4362 yyg->yy_buffer_stack_max = num_to_alloc;
4363 }
4364 }
4365
4366 /** Setup the input buffer state to scan directly from a user-specified character buffer.
4367 * @param base the character buffer
4368 * @param size the size in bytes of the character buffer
4369 * @param yyscanner The scanner object.
4370 * @return the newly allocated buffer state object.
4371 */
yy_scan_buffer(char * base,yy_size_t size,yyscan_t yyscanner)4372 YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
4373 {
4374 YY_BUFFER_STATE b;
4375
4376 if ( size < 2 ||
4377 base[size-2] != YY_END_OF_BUFFER_CHAR ||
4378 base[size-1] != YY_END_OF_BUFFER_CHAR )
4379 /* They forgot to leave room for the EOB's. */
4380 return NULL;
4381
4382 b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) , yyscanner );
4383 if ( ! b )
4384 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
4385
4386 b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */
4387 b->yy_buf_pos = b->yy_ch_buf = base;
4388 b->yy_is_our_buffer = 0;
4389 b->yy_input_file = NULL;
4390 b->yy_n_chars = b->yy_buf_size;
4391 b->yy_is_interactive = 0;
4392 b->yy_at_bol = 1;
4393 b->yy_fill_buffer = 0;
4394 b->yy_buffer_status = YY_BUFFER_NEW;
4395
4396 yy_switch_to_buffer( b , yyscanner );
4397
4398 return b;
4399 }
4400
4401 /** Setup the input buffer state to scan a string. The next call to yylex() will
4402 * scan from a @e copy of @a str.
4403 * @param yystr a NUL-terminated string to scan
4404 * @param yyscanner The scanner object.
4405 * @return the newly allocated buffer state object.
4406 * @note If you want to scan bytes that may contain NUL values, then use
4407 * yy_scan_bytes() instead.
4408 */
yy_scan_string(const char * yystr,yyscan_t yyscanner)4409 YY_BUFFER_STATE yy_scan_string (const char * yystr , yyscan_t yyscanner)
4410 {
4411
4412 return yy_scan_bytes( yystr, (int) strlen(yystr) , yyscanner);
4413 }
4414
4415 /** Setup the input buffer state to scan the given bytes. The next call to yylex() will
4416 * scan from a @e copy of @a bytes.
4417 * @param yybytes the byte buffer to scan
4418 * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
4419 * @param yyscanner The scanner object.
4420 * @return the newly allocated buffer state object.
4421 */
yy_scan_bytes(const char * yybytes,int _yybytes_len,yyscan_t yyscanner)4422 YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len , yyscan_t yyscanner)
4423 {
4424 YY_BUFFER_STATE b;
4425 char *buf;
4426 yy_size_t n;
4427 int i;
4428
4429 /* Get memory for full buffer, including space for trailing EOB's. */
4430 n = (yy_size_t) (_yybytes_len + 2);
4431 buf = (char *) yyalloc( n , yyscanner );
4432 if ( ! buf )
4433 YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
4434
4435 for ( i = 0; i < _yybytes_len; ++i )
4436 buf[i] = yybytes[i];
4437
4438 buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
4439
4440 b = yy_scan_buffer( buf, n , yyscanner);
4441 if ( ! b )
4442 YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
4443
4444 /* It's okay to grow etc. this buffer, and we should throw it
4445 * away when we're done.
4446 */
4447 b->yy_is_our_buffer = 1;
4448
4449 return b;
4450 }
4451
4452 #ifndef YY_EXIT_FAILURE
4453 #define YY_EXIT_FAILURE 2
4454 #endif
4455
yy_fatal_error(const char * msg,yyscan_t yyscanner)4456 static void yynoreturn yy_fatal_error (const char* msg , yyscan_t yyscanner)
4457 {
4458 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4459 (void)yyg;
4460 fprintf( stderr, "%s\n", msg );
4461 exit( YY_EXIT_FAILURE );
4462 }
4463
4464 /* Redefine yyless() so it works in section 3 code. */
4465
4466 #undef yyless
4467 #define yyless(n) \
4468 do \
4469 { \
4470 /* Undo effects of setting up yytext. */ \
4471 int yyless_macro_arg = (n); \
4472 YY_LESS_LINENO(yyless_macro_arg);\
4473 yytext[yyleng] = yyg->yy_hold_char; \
4474 yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
4475 yyg->yy_hold_char = *yyg->yy_c_buf_p; \
4476 *yyg->yy_c_buf_p = '\0'; \
4477 yyleng = yyless_macro_arg; \
4478 } \
4479 while ( 0 )
4480
4481 /* Accessor methods (get/set functions) to struct members. */
4482
4483 /** Get the user-defined data for this scanner.
4484 * @param yyscanner The scanner object.
4485 */
yyget_extra(yyscan_t yyscanner)4486 YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
4487 {
4488 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4489 return yyextra;
4490 }
4491
4492 /** Get the current line number.
4493 * @param yyscanner The scanner object.
4494 */
yyget_lineno(yyscan_t yyscanner)4495 int yyget_lineno (yyscan_t yyscanner)
4496 {
4497 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4498
4499 if (! YY_CURRENT_BUFFER)
4500 return 0;
4501
4502 return yylineno;
4503 }
4504
4505 /** Get the current column number.
4506 * @param yyscanner The scanner object.
4507 */
yyget_column(yyscan_t yyscanner)4508 int yyget_column (yyscan_t yyscanner)
4509 {
4510 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4511
4512 if (! YY_CURRENT_BUFFER)
4513 return 0;
4514
4515 return yycolumn;
4516 }
4517
4518 /** Get the input stream.
4519 * @param yyscanner The scanner object.
4520 */
yyget_in(yyscan_t yyscanner)4521 FILE *yyget_in (yyscan_t yyscanner)
4522 {
4523 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4524 return yyin;
4525 }
4526
4527 /** Get the output stream.
4528 * @param yyscanner The scanner object.
4529 */
yyget_out(yyscan_t yyscanner)4530 FILE *yyget_out (yyscan_t yyscanner)
4531 {
4532 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4533 return yyout;
4534 }
4535
4536 /** Get the length of the current token.
4537 * @param yyscanner The scanner object.
4538 */
yyget_leng(yyscan_t yyscanner)4539 int yyget_leng (yyscan_t yyscanner)
4540 {
4541 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4542 return yyleng;
4543 }
4544
4545 /** Get the current token.
4546 * @param yyscanner The scanner object.
4547 */
4548
yyget_text(yyscan_t yyscanner)4549 char *yyget_text (yyscan_t yyscanner)
4550 {
4551 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4552 return yytext;
4553 }
4554
4555 /** Set the user-defined data. This data is never touched by the scanner.
4556 * @param user_defined The data to be associated with this scanner.
4557 * @param yyscanner The scanner object.
4558 */
yyset_extra(YY_EXTRA_TYPE user_defined,yyscan_t yyscanner)4559 void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
4560 {
4561 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4562 yyextra = user_defined ;
4563 }
4564
4565 /** Set the current line number.
4566 * @param _line_number line number
4567 * @param yyscanner The scanner object.
4568 */
yyset_lineno(int _line_number,yyscan_t yyscanner)4569 void yyset_lineno (int _line_number , yyscan_t yyscanner)
4570 {
4571 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4572
4573 /* lineno is only valid if an input buffer exists. */
4574 if (! YY_CURRENT_BUFFER )
4575 YY_FATAL_ERROR( "yyset_lineno called with no buffer" );
4576
4577 yylineno = _line_number;
4578 }
4579
4580 /** Set the current column.
4581 * @param _column_no column number
4582 * @param yyscanner The scanner object.
4583 */
yyset_column(int _column_no,yyscan_t yyscanner)4584 void yyset_column (int _column_no , yyscan_t yyscanner)
4585 {
4586 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4587
4588 /* column is only valid if an input buffer exists. */
4589 if (! YY_CURRENT_BUFFER )
4590 YY_FATAL_ERROR( "yyset_column called with no buffer" );
4591
4592 yycolumn = _column_no;
4593 }
4594
4595 /** Set the input stream. This does not discard the current
4596 * input buffer.
4597 * @param _in_str A readable stream.
4598 * @param yyscanner The scanner object.
4599 * @see yy_switch_to_buffer
4600 */
yyset_in(FILE * _in_str,yyscan_t yyscanner)4601 void yyset_in (FILE * _in_str , yyscan_t yyscanner)
4602 {
4603 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4604 yyin = _in_str ;
4605 }
4606
yyset_out(FILE * _out_str,yyscan_t yyscanner)4607 void yyset_out (FILE * _out_str , yyscan_t yyscanner)
4608 {
4609 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4610 yyout = _out_str ;
4611 }
4612
yyget_debug(yyscan_t yyscanner)4613 int yyget_debug (yyscan_t yyscanner)
4614 {
4615 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4616 return yy_flex_debug;
4617 }
4618
yyset_debug(int _bdebug,yyscan_t yyscanner)4619 void yyset_debug (int _bdebug , yyscan_t yyscanner)
4620 {
4621 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4622 yy_flex_debug = _bdebug ;
4623 }
4624
4625 /* Accessor methods for yylval and yylloc */
4626
yyget_lval(yyscan_t yyscanner)4627 YYSTYPE * yyget_lval (yyscan_t yyscanner)
4628 {
4629 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4630 return yylval;
4631 }
4632
yyset_lval(YYSTYPE * yylval_param,yyscan_t yyscanner)4633 void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
4634 {
4635 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4636 yylval = yylval_param;
4637 }
4638
4639 /* User-visible API */
4640
4641 /* yylex_init is special because it creates the scanner itself, so it is
4642 * the ONLY reentrant function that doesn't take the scanner as the last argument.
4643 * That's why we explicitly handle the declaration, instead of using our macros.
4644 */
yylex_init(yyscan_t * ptr_yy_globals)4645 int yylex_init(yyscan_t* ptr_yy_globals)
4646 {
4647 if (ptr_yy_globals == NULL){
4648 errno = EINVAL;
4649 return 1;
4650 }
4651
4652 *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
4653
4654 if (*ptr_yy_globals == NULL){
4655 errno = ENOMEM;
4656 return 1;
4657 }
4658
4659 /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
4660 memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
4661
4662 return yy_init_globals ( *ptr_yy_globals );
4663 }
4664
4665 /* yylex_init_extra has the same functionality as yylex_init, but follows the
4666 * convention of taking the scanner as the last argument. Note however, that
4667 * this is a *pointer* to a scanner, as it will be allocated by this call (and
4668 * is the reason, too, why this function also must handle its own declaration).
4669 * The user defined value in the first argument will be available to yyalloc in
4670 * the yyextra field.
4671 */
yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t * ptr_yy_globals)4672 int yylex_init_extra( YY_EXTRA_TYPE yy_user_defined, yyscan_t* ptr_yy_globals )
4673 {
4674 struct yyguts_t dummy_yyguts;
4675
4676 yyset_extra (yy_user_defined, &dummy_yyguts);
4677
4678 if (ptr_yy_globals == NULL){
4679 errno = EINVAL;
4680 return 1;
4681 }
4682
4683 *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
4684
4685 if (*ptr_yy_globals == NULL){
4686 errno = ENOMEM;
4687 return 1;
4688 }
4689
4690 /* By setting to 0xAA, we expose bugs in
4691 yy_init_globals. Leave at 0x00 for releases. */
4692 memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
4693
4694 yyset_extra (yy_user_defined, *ptr_yy_globals);
4695
4696 return yy_init_globals ( *ptr_yy_globals );
4697 }
4698
yy_init_globals(yyscan_t yyscanner)4699 static int yy_init_globals (yyscan_t yyscanner)
4700 {
4701 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4702 /* Initialization is the same as for the non-reentrant scanner.
4703 * This function is called from yylex_destroy(), so don't allocate here.
4704 */
4705
4706 yyg->yy_buffer_stack = NULL;
4707 yyg->yy_buffer_stack_top = 0;
4708 yyg->yy_buffer_stack_max = 0;
4709 yyg->yy_c_buf_p = NULL;
4710 yyg->yy_init = 0;
4711 yyg->yy_start = 0;
4712
4713 yyg->yy_start_stack_ptr = 0;
4714 yyg->yy_start_stack_depth = 0;
4715 yyg->yy_start_stack = NULL;
4716
4717 /* Defined in main.c */
4718 #ifdef YY_STDINIT
4719 yyin = stdin;
4720 yyout = stdout;
4721 #else
4722 yyin = NULL;
4723 yyout = NULL;
4724 #endif
4725
4726 /* For future reference: Set errno on error, since we are called by
4727 * yylex_init()
4728 */
4729 return 0;
4730 }
4731
4732 /* yylex_destroy is for both reentrant and non-reentrant scanners. */
yylex_destroy(yyscan_t yyscanner)4733 int yylex_destroy (yyscan_t yyscanner)
4734 {
4735 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4736
4737 /* Pop the buffer stack, destroying each element. */
4738 while(YY_CURRENT_BUFFER){
4739 yy_delete_buffer( YY_CURRENT_BUFFER , yyscanner );
4740 YY_CURRENT_BUFFER_LVALUE = NULL;
4741 yypop_buffer_state(yyscanner);
4742 }
4743
4744 /* Destroy the stack itself. */
4745 yyfree(yyg->yy_buffer_stack , yyscanner);
4746 yyg->yy_buffer_stack = NULL;
4747
4748 /* Destroy the start condition stack. */
4749 yyfree( yyg->yy_start_stack , yyscanner );
4750 yyg->yy_start_stack = NULL;
4751
4752 /* Reset the globals. This is important in a non-reentrant scanner so the next time
4753 * yylex() is called, initialization will occur. */
4754 yy_init_globals( yyscanner);
4755
4756 /* Destroy the main struct (reentrant only). */
4757 yyfree ( yyscanner , yyscanner );
4758 yyscanner = NULL;
4759 return 0;
4760 }
4761
4762 /*
4763 * Internal utility routines.
4764 */
4765
4766 #ifndef yytext_ptr
yy_flex_strncpy(char * s1,const char * s2,int n,yyscan_t yyscanner)4767 static void yy_flex_strncpy (char* s1, const char * s2, int n , yyscan_t yyscanner)
4768 {
4769 struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
4770 (void)yyg;
4771
4772 int i;
4773 for ( i = 0; i < n; ++i )
4774 s1[i] = s2[i];
4775 }
4776 #endif
4777
4778 #ifdef YY_NEED_STRLEN
yy_flex_strlen(const char * s,yyscan_t yyscanner)4779 static int yy_flex_strlen (const char * s , yyscan_t yyscanner)
4780 {
4781 int n;
4782 for ( n = 0; s[n]; ++n )
4783 ;
4784
4785 return n;
4786 }
4787 #endif
4788
4789 #define YYTABLES_NAME "yytables"
4790
4791 #line 1933 "../libinterp/parse-tree/lex.ll"
4792
4793
4794 #if defined (HAVE_PRAGMA_GCC_DIAGNOSTIC)
4795 // Restore prevailing warning state for remainder of the file.
4796 # pragma GCC diagnostic pop
4797 #endif
4798
4799 void *
octave_alloc(yy_size_t size,yyscan_t)4800 octave_alloc (yy_size_t size, yyscan_t)
4801 {
4802 return std::malloc (size);
4803 }
4804
4805 void *
octave_realloc(void * ptr,yy_size_t size,yyscan_t)4806 octave_realloc (void *ptr, yy_size_t size, yyscan_t)
4807 {
4808 return std::realloc (ptr, size);
4809 }
4810
4811 void
octave_free(void * ptr,yyscan_t)4812 octave_free (void *ptr, yyscan_t)
4813 {
4814 std::free (ptr);
4815 }
4816
4817 static void
display_character(char c)4818 display_character (char c)
4819 {
4820 if (isgraph (c))
4821 std::cerr << c;
4822 else
4823 switch (c)
4824 {
4825 case 0:
4826 std::cerr << "NUL";
4827 break;
4828
4829 case 1:
4830 std::cerr << "SOH";
4831 break;
4832
4833 case 2:
4834 std::cerr << "STX";
4835 break;
4836
4837 case 3:
4838 std::cerr << "ETX";
4839 break;
4840
4841 case 4:
4842 std::cerr << "EOT";
4843 break;
4844
4845 case 5:
4846 std::cerr << "ENQ";
4847 break;
4848
4849 case 6:
4850 std::cerr << "ACK";
4851 break;
4852
4853 case 7:
4854 std::cerr << "\\a";
4855 break;
4856
4857 case 8:
4858 std::cerr << "\\b";
4859 break;
4860
4861 case 9:
4862 std::cerr << "\\t";
4863 break;
4864
4865 case 10:
4866 std::cerr << "\\n";
4867 break;
4868
4869 case 11:
4870 std::cerr << "\\v";
4871 break;
4872
4873 case 12:
4874 std::cerr << "\\f";
4875 break;
4876
4877 case 13:
4878 std::cerr << "\\r";
4879 break;
4880
4881 case 14:
4882 std::cerr << "SO";
4883 break;
4884
4885 case 15:
4886 std::cerr << "SI";
4887 break;
4888
4889 case 16:
4890 std::cerr << "DLE";
4891 break;
4892
4893 case 17:
4894 std::cerr << "DC1";
4895 break;
4896
4897 case 18:
4898 std::cerr << "DC2";
4899 break;
4900
4901 case 19:
4902 std::cerr << "DC3";
4903 break;
4904
4905 case 20:
4906 std::cerr << "DC4";
4907 break;
4908
4909 case 21:
4910 std::cerr << "NAK";
4911 break;
4912
4913 case 22:
4914 std::cerr << "SYN";
4915 break;
4916
4917 case 23:
4918 std::cerr << "ETB";
4919 break;
4920
4921 case 24:
4922 std::cerr << "CAN";
4923 break;
4924
4925 case 25:
4926 std::cerr << "EM";
4927 break;
4928
4929 case 26:
4930 std::cerr << "SUB";
4931 break;
4932
4933 case 27:
4934 std::cerr << "ESC";
4935 break;
4936
4937 case 28:
4938 std::cerr << "FS";
4939 break;
4940
4941 case 29:
4942 std::cerr << "GS";
4943 break;
4944
4945 case 30:
4946 std::cerr << "RS";
4947 break;
4948
4949 case 31:
4950 std::cerr << "US";
4951 break;
4952
4953 case 32:
4954 std::cerr << "SPACE";
4955 break;
4956
4957 case 127:
4958 std::cerr << "DEL";
4959 break;
4960 }
4961 }
4962
4963 DEFUN (iskeyword, args, ,
4964 doc: /* -*- texinfo -*-
4965 @deftypefn {} {} iskeyword ()
4966 @deftypefnx {} {} iskeyword (@var{name})
4967 Return true if @var{name} is an Octave keyword.
4968
4969 If @var{name} is omitted, return a list of keywords.
4970 @seealso{isvarname, exist}
4971 @end deftypefn */)
4972 {
4973 octave_value retval;
4974
4975 int nargin = args.length ();
4976
4977 if (nargin > 1)
4978 print_usage ();
4979
4980 if (nargin == 0)
4981 {
4982 // Neither set nor get are keywords. See the note in the
4983 // iskeyword function for additional details.
4984
4985 string_vector lst (TOTAL_KEYWORDS);
4986
4987 int j = 0;
4988
4989 for (int i = 0; i < TOTAL_KEYWORDS; i++)
4990 {
4991 std::string kword = wordlist[i].name;
4992
4993 if (! (kword == "set" || kword == "get"
4994 || kword == "enumeration" || kword == "events"
4995 || kword == "methods" || kword == "properties"))
4996 lst[j++] = kword;
4997 }
4998
4999 lst.resize (j);
5000
5001 retval = Cell (lst.sort ());
5002 }
5003 else
5004 {
5005 std::string name = args(0).xstring_value ("iskeyword: NAME must be a string");
5006 retval = octave::iskeyword (name);
5007 }
5008
5009 return retval;
5010 }
5011
5012 /*
5013
5014 %!assert (iskeyword ("for"))
5015 %!assert (iskeyword ("fort"), false)
5016 %!assert (iskeyword ("fft"), false)
5017 %!assert (iskeyword ("get"), false)
5018 %!assert (iskeyword ("set"), false)
5019
5020 %!error iskeyword ("A", "B")
5021 %!error <NAME must be a string> iskeyword (1)
5022
5023 */
5024
5025 namespace octave
5026 {
5027 void
clear(void)5028 lexical_feedback::symbol_table_context::clear (void)
5029 {
5030 while (! m_frame_stack.empty ())
5031 m_frame_stack.pop_front ();
5032 }
5033
5034 void
pop(void)5035 lexical_feedback::symbol_table_context::pop (void)
5036 {
5037 if (empty ())
5038 panic_impossible ();
5039
5040 m_frame_stack.pop_front ();
5041 }
5042
5043 symbol_scope
curr_scope(void) const5044 lexical_feedback::symbol_table_context::curr_scope (void) const
5045 {
5046 if (empty ())
5047 return m_interpreter.get_current_scope ();
5048 else
5049 return m_frame_stack.front ();
5050 }
5051
5052 symbol_scope
parent_scope(void) const5053 lexical_feedback::symbol_table_context::parent_scope (void) const
5054 {
5055 std::size_t sz = size ();
5056
5057 return (sz > 1
5058 ? m_frame_stack[1]
5059 : (sz == 1 ? m_frame_stack[0] : symbol_scope ()));
5060 }
5061
~lexical_feedback(void)5062 lexical_feedback::~lexical_feedback (void)
5063 {
5064 m_tokens.clear ();
5065 }
5066
5067 void
init(void)5068 lexical_feedback::init (void)
5069 {
5070 // The closest paren, brace, or bracket nesting is not an object
5071 // index.
5072 m_looking_at_object_index.push_front (false);
5073 }
5074
5075 void
reset(void)5076 lexical_feedback::reset (void)
5077 {
5078 m_end_of_input = false;
5079 m_allow_command_syntax = true;
5080 m_at_beginning_of_statement = true;
5081 m_looking_at_anon_fcn_args = false;
5082 m_looking_at_return_list = false;
5083 m_looking_at_parameter_list = false;
5084 m_looking_at_decl_list = false;
5085 m_looking_at_initializer_expression = false;
5086 m_looking_at_matrix_or_assign_lhs = false;
5087 m_looking_for_object_index = false;
5088 m_looking_at_indirect_ref = false;
5089 m_parsing_anon_fcn_body = false;
5090 m_parsing_class_method = false;
5091 m_parsing_classdef = false;
5092 m_parsing_classdef_decl = false;
5093 m_parsing_classdef_superclass = false;
5094 m_maybe_classdef_get_set_method = false;
5095 m_parsing_classdef_get_method = false;
5096 m_parsing_classdef_set_method = false;
5097 m_quote_is_transpose = false;
5098 m_force_script = false;
5099 m_reading_fcn_file = false;
5100 m_reading_script_file = false;
5101 m_reading_classdef_file = false;
5102 m_buffer_function_text = false;
5103 m_bracketflag = 0;
5104 m_braceflag = 0;
5105 m_looping = 0;
5106 m_defining_func = 0;
5107 m_looking_at_function_handle = 0;
5108 m_block_comment_nesting_level = 0;
5109 m_command_arg_paren_count = 0;
5110 m_token_count = 0;
5111 m_filepos = filepos ();
5112 m_tok_beg = filepos ();
5113 m_tok_end = filepos ();
5114 m_string_text = "";
5115 m_current_input_line = "";
5116 m_comment_text = "";
5117 m_help_text = "";
5118 m_function_text = "";
5119 m_fcn_file_name = "";
5120 m_fcn_file_full_name = "";
5121 m_dir_name = "";
5122 m_package_name = "";
5123 m_looking_at_object_index.clear ();
5124 m_looking_at_object_index.push_front (false);
5125
5126 while (! m_parsed_function_name.empty ())
5127 m_parsed_function_name.pop ();
5128
5129 m_pending_local_variables.clear ();
5130 m_symtab_context.clear ();
5131 m_nesting_level.reset ();
5132 m_tokens.clear ();
5133 }
5134
5135 int
previous_token_value(void) const5136 lexical_feedback::previous_token_value (void) const
5137 {
5138 const token *tok = m_tokens.front ();
5139 return tok ? tok->token_value () : 0;
5140 }
5141
5142 bool
previous_token_value_is(int tok_val) const5143 lexical_feedback::previous_token_value_is (int tok_val) const
5144 {
5145 const token *tok = m_tokens.front ();
5146 return tok ? tok->token_value_is (tok_val) : false;
5147 }
5148
5149 void
mark_previous_token_trailing_space(void)5150 lexical_feedback::mark_previous_token_trailing_space (void)
5151 {
5152 token *tok = m_tokens.front ();
5153 if (tok && ! previous_token_value_is ('\n'))
5154 tok->mark_trailing_space ();
5155 }
5156
5157 bool
space_follows_previous_token(void) const5158 lexical_feedback::space_follows_previous_token (void) const
5159 {
5160 const token *tok = m_tokens.front ();
5161 return tok ? tok->space_follows_token () : false;
5162 }
5163
5164 bool
previous_token_is_binop(void) const5165 lexical_feedback::previous_token_is_binop (void) const
5166 {
5167 int tok = previous_token_value ();
5168
5169 return (tok == '+' || tok == '-' || tok == '@'
5170 || tok == ',' || tok == ';' || tok == '*' || tok == '/'
5171 || tok == ':' || tok == '=' || tok == ADD_EQ
5172 || tok == AND_EQ || tok == DIV_EQ || tok == EDIV
5173 || tok == EDIV_EQ || tok == ELEFTDIV || tok == ELEFTDIV_EQ
5174 || tok == EMINUS || tok == EMUL || tok == EMUL_EQ
5175 || tok == EPOW || tok == EPOW_EQ || tok == EXPR_AND
5176 || tok == EXPR_AND_AND || tok == EXPR_EQ || tok == EXPR_GE
5177 || tok == EXPR_GT || tok == EXPR_LE || tok == EXPR_LT
5178 || tok == EXPR_NE || tok == EXPR_NOT || tok == EXPR_OR
5179 || tok == EXPR_OR_OR || tok == LEFTDIV || tok == LEFTDIV_EQ
5180 || tok == MUL_EQ || tok == OR_EQ || tok == POW
5181 || tok == POW_EQ || tok == SUB_EQ);
5182 }
5183
5184 bool
previous_token_is_keyword(void) const5185 lexical_feedback::previous_token_is_keyword (void) const
5186 {
5187 const token *tok = m_tokens.front ();
5188 return tok ? tok->iskeyword () : false;
5189 }
5190
5191 bool
previous_token_may_be_command(void) const5192 lexical_feedback::previous_token_may_be_command (void) const
5193 {
5194 if (! m_allow_command_syntax)
5195 return false;
5196
5197 const token *tok = m_tokens.front ();
5198 return tok ? tok->may_be_command () : false;
5199 }
5200
5201 void
maybe_mark_previous_token_as_variable(void)5202 lexical_feedback::maybe_mark_previous_token_as_variable (void)
5203 {
5204 token *tok = m_tokens.front ();
5205
5206 if (tok && tok->is_symbol ())
5207 m_pending_local_variables.insert (tok->symbol_name ());
5208 }
5209
5210 void
mark_as_variables(const std::list<std::string> & lst)5211 lexical_feedback::mark_as_variables (const std::list<std::string>& lst)
5212 {
5213 for (const auto& var : lst)
5214 m_pending_local_variables.insert (var);
5215 }
5216 }
5217
5218 static bool
looks_like_copyright(const std::string & s)5219 looks_like_copyright (const std::string& s)
5220 {
5221 if (s.empty ())
5222 return false;
5223
5224 // Comment characters have been stripped but whitespace
5225 // (including newlines) remains.
5226
5227 std::size_t offset = s.find_first_not_of (" \t\n\r");
5228
5229 return (offset != std::string::npos
5230 && (s.substr (offset, 9) == "Copyright"
5231 || s.substr (offset, 6) == "Author"
5232 || s.substr (offset, 23) == "SPDX-License-Identifier"));
5233 }
5234
5235 static bool
looks_like_shebang(const std::string & s)5236 looks_like_shebang (const std::string& s)
5237 {
5238 return ((! s.empty ()) && (s[0] == '!'));
5239 }
5240
5241 namespace octave
5242 {
5243 void
fill(const std::string & input,bool eof_arg)5244 base_lexer::input_buffer::fill (const std::string& input, bool eof_arg)
5245 {
5246 m_buffer = input;
5247 m_chars_left = m_buffer.length ();
5248 m_offset = 0;
5249 m_eof = eof_arg;
5250 }
5251
5252 // If BY_LINES is true, return chunks to the lexer line by line.
5253 int
copy_chunk(char * buf,std::size_t max_size,bool by_lines)5254 base_lexer::input_buffer::copy_chunk (char *buf, std::size_t max_size,
5255 bool by_lines)
5256 {
5257 static const char * const eol = "\n";
5258
5259 std::size_t len = 0;
5260 if (by_lines)
5261 {
5262 std::size_t newline_pos = m_buffer.find ('\n', m_offset);
5263 len = (newline_pos != std::string::npos
5264 ? newline_pos - m_offset + 1
5265 : (max_size > m_chars_left ? m_chars_left : max_size));
5266 }
5267 else
5268 len = max_size > m_chars_left ? m_chars_left : max_size;
5269
5270 assert (len > 0);
5271 memcpy (buf, m_buffer.c_str () + m_offset, len);
5272
5273 m_chars_left -= len;
5274 m_offset += len;
5275
5276 // Make sure the final input returned to the lexer ends with a new
5277 // line character.
5278
5279 if (m_chars_left == 0 && buf[len-1] != '\n')
5280 {
5281 if (len < max_size)
5282 {
5283 // There is enough room to plug the newline character in
5284 // the buffer.
5285 buf[len++] = '\n';
5286 }
5287 else
5288 {
5289 // There isn't enough room to plug the newline character
5290 // in BUF so arrange to have it returned on the next call
5291 // to base_lexer::read.
5292
5293 // At this point we've exhausted the original input
5294 // (m_chars_left is zero) so we can overwrite the initial
5295 // buffer with a single newline character to be returned on
5296 // the next call.
5297
5298 m_buffer = eol;
5299 m_chars_left = 1;
5300 m_offset = 0;
5301 }
5302 }
5303
5304 return len;
5305 }
5306
~base_lexer(void)5307 base_lexer::~base_lexer (void)
5308 {
5309 yylex_destroy (m_scanner);
5310 }
5311
5312 void
init(void)5313 base_lexer::init (void)
5314 {
5315 yylex_init (&m_scanner);
5316
5317 // Make base_lexer object available through yyextra in
5318 // flex-generated lexer.
5319 yyset_extra (this, m_scanner);
5320
5321 clear_start_state ();
5322 }
5323
5324 // Inside Flex-generated functions, yyg is the scanner cast to its real
5325 // type. Some flex macros that we use in base_lexer member functions
5326 // (for example, BEGIN) use yyg. If we could perform the actions of
5327 // these macros with functions instead, we could eliminate the
5328 // OCTAVE_YYG macro.
5329
5330 #define OCTAVE_YYG \
5331 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (m_scanner)
5332
5333 void
reset(void)5334 base_lexer::reset (void)
5335 {
5336 // Start off on the right foot.
5337 clear_start_state ();
5338
5339 m_symtab_context.clear ();
5340
5341 // Only ask for input from stdin if we are expecting interactive
5342 // input.
5343
5344 if (m_interpreter.interactive ()
5345 && ! (m_reading_fcn_file
5346 || m_reading_classdef_file
5347 || m_reading_script_file
5348 || input_from_eval_string ()))
5349 yyrestart (stdin, m_scanner);
5350
5351 lexical_feedback::reset ();
5352
5353 m_comment_buf.reset ();
5354 }
5355
5356 void
prep_for_file(void)5357 base_lexer::prep_for_file (void)
5358 {
5359 m_reading_script_file = true;
5360
5361 push_start_state (INPUT_FILE_START);
5362 }
5363
5364 void
begin_string(int state)5365 base_lexer::begin_string (int state)
5366 {
5367 m_tok_beg = m_filepos;
5368
5369 push_start_state (state);
5370 }
5371
5372 int
handle_end_of_input(void)5373 base_lexer::handle_end_of_input (void)
5374 {
5375 lexer_debug ("<<EOF>>");
5376
5377 m_tok_beg = m_filepos;
5378 m_tok_end = m_filepos;
5379
5380 if (m_block_comment_nesting_level != 0)
5381 {
5382 warning ("block comment open at end of input");
5383
5384 if ((m_reading_fcn_file || m_reading_script_file || m_reading_classdef_file)
5385 && ! m_fcn_file_name.empty ())
5386 warning ("near line %d of file '%s.m'",
5387 m_filepos.line (), m_fcn_file_name.c_str ());
5388 }
5389
5390 token *tok_val = new token (END_OF_INPUT, m_tok_beg, m_tok_end);
5391
5392 push_token (tok_val);
5393
5394 return count_token_internal (END_OF_INPUT);
5395 }
5396
5397 char *
flex_yytext(void)5398 base_lexer::flex_yytext (void)
5399 {
5400 return yyget_text (m_scanner);
5401 }
5402
5403 int
flex_yyleng(void)5404 base_lexer::flex_yyleng (void)
5405 {
5406 return yyget_leng (m_scanner);
5407 }
5408
5409 int
text_yyinput(void)5410 base_lexer::text_yyinput (void)
5411 {
5412 int c = yyinput (m_scanner);
5413
5414 if (debug_flag ())
5415 {
5416 std::cerr << "I: ";
5417 display_character (c);
5418 std::cerr << std::endl;
5419 }
5420
5421 // Convert CRLF into just LF and single CR into LF.
5422
5423 if (c == '\r')
5424 {
5425 c = yyinput (m_scanner);
5426
5427 if (debug_flag ())
5428 {
5429 std::cerr << "I: ";
5430 display_character (c);
5431 std::cerr << std::endl;
5432 }
5433
5434 if (c != '\n')
5435 {
5436 xunput (c);
5437 c = '\n';
5438 }
5439 }
5440
5441 return c;
5442 }
5443
5444 void
xunput(char c,char * buf)5445 base_lexer::xunput (char c, char *buf)
5446 {
5447 if (c != EOF)
5448 {
5449 if (debug_flag ())
5450 {
5451 std::cerr << "U: ";
5452 display_character (c);
5453 std::cerr << std::endl;
5454 }
5455
5456 yyunput (c, buf, m_scanner);
5457 }
5458 }
5459
5460 void
xunput(char c)5461 base_lexer::xunput (char c)
5462 {
5463 char *yytxt = flex_yytext ();
5464
5465 xunput (c, yytxt);
5466 }
5467
5468 void
update_token_positions(int tok_len)5469 base_lexer::update_token_positions (int tok_len)
5470 {
5471 m_tok_beg = m_filepos;
5472 m_tok_end = m_filepos;
5473
5474 if (tok_len > 1)
5475 m_tok_end.increment_column (tok_len - 1);
5476
5477 m_filepos.increment_column (tok_len);
5478 }
5479
5480 bool
looking_at_space(void)5481 base_lexer::looking_at_space (void)
5482 {
5483 int c = text_yyinput ();
5484 xunput (c);
5485 return is_space_or_tab (c);
5486 }
5487
5488 bool
inside_any_object_index(void)5489 base_lexer::inside_any_object_index (void)
5490 {
5491 bool retval = false;
5492
5493 for (const bool is_obj_idx : m_looking_at_object_index)
5494 {
5495 if (is_obj_idx)
5496 {
5497 retval = true;
5498 break;
5499 }
5500 }
5501
5502 return retval;
5503 }
5504
5505 bool
is_variable(const std::string & name,const symbol_scope &)5506 base_lexer::is_variable (const std::string& name,
5507 const symbol_scope& /*scope*/)
5508 {
5509 return ((m_interpreter.at_top_level ()
5510 && m_interpreter.is_variable (name))
5511 || (m_pending_local_variables.find (name)
5512 != m_pending_local_variables.end ()));
5513 }
5514
5515 int
make_keyword_token(const std::string & s)5516 base_lexer::make_keyword_token (const std::string& s)
5517 {
5518 // Token positions should have already been updated before this
5519 // function is called.
5520
5521 int slen = s.length ();
5522
5523 const octave_kw *kw = octave_kw_hash::in_word_set (s.c_str (), slen);
5524
5525 if (! kw)
5526 return 0;
5527
5528 bool previous_at_bos = m_at_beginning_of_statement;
5529
5530 // May be reset to true for some token types.
5531 m_at_beginning_of_statement = false;
5532
5533 token *tok_val = nullptr;
5534
5535 switch (kw->kw_id)
5536 {
5537 case break_kw:
5538 case catch_kw:
5539 case continue_kw:
5540 case else_kw:
5541 case otherwise_kw:
5542 case return_kw:
5543 case unwind_protect_cleanup_kw:
5544 m_at_beginning_of_statement = true;
5545 break;
5546
5547 case persistent_kw:
5548 case global_kw:
5549 m_looking_at_decl_list = true;
5550 break;
5551
5552 case case_kw:
5553 case elseif_kw:
5554 case until_kw:
5555 break;
5556
5557 case end_kw:
5558 if (inside_any_object_index ()
5559 || (m_defining_func
5560 && ! (m_looking_at_return_list
5561 || m_parsed_function_name.top ())))
5562 {
5563 m_at_beginning_of_statement = previous_at_bos;
5564 return 0;
5565 }
5566
5567 tok_val = new token (end_kw, token::simple_end, m_tok_beg, m_tok_end);
5568 m_at_beginning_of_statement = true;
5569 break;
5570
5571 case end_try_catch_kw:
5572 tok_val = new token (end_try_catch_kw, token::try_catch_end, m_tok_beg,
5573 m_tok_end);
5574 m_at_beginning_of_statement = true;
5575 break;
5576
5577 case end_unwind_protect_kw:
5578 tok_val = new token (end_unwind_protect_kw,
5579 token::unwind_protect_end, m_tok_beg, m_tok_end);
5580 m_at_beginning_of_statement = true;
5581 break;
5582
5583 case endfor_kw:
5584 tok_val = new token (endfor_kw, token::for_end, m_tok_beg, m_tok_end);
5585 m_at_beginning_of_statement = true;
5586 break;
5587
5588 case endfunction_kw:
5589 tok_val = new token (endfunction_kw, token::function_end, m_tok_beg,
5590 m_tok_end);
5591 m_at_beginning_of_statement = true;
5592 break;
5593
5594 case endif_kw:
5595 tok_val = new token (endif_kw, token::if_end, m_tok_beg, m_tok_end);
5596 m_at_beginning_of_statement = true;
5597 break;
5598
5599 case endparfor_kw:
5600 tok_val = new token (endparfor_kw, token::parfor_end, m_tok_beg,
5601 m_tok_end);
5602 m_at_beginning_of_statement = true;
5603 break;
5604
5605 case endswitch_kw:
5606 tok_val = new token (endswitch_kw, token::switch_end, m_tok_beg,
5607 m_tok_end);
5608 m_at_beginning_of_statement = true;
5609 break;
5610
5611 case endwhile_kw:
5612 tok_val = new token (endwhile_kw, token::while_end, m_tok_beg,
5613 m_tok_end);
5614 m_at_beginning_of_statement = true;
5615 break;
5616
5617 case endclassdef_kw:
5618 tok_val = new token (endclassdef_kw, token::classdef_end, m_tok_beg,
5619 m_tok_end);
5620 m_at_beginning_of_statement = true;
5621 break;
5622
5623 case endenumeration_kw:
5624 tok_val = new token (endenumeration_kw, token::enumeration_end,
5625 m_tok_beg, m_tok_end);
5626 m_at_beginning_of_statement = true;
5627 break;
5628
5629 case endevents_kw:
5630 tok_val = new token (endevents_kw, token::events_end, m_tok_beg,
5631 m_tok_end);
5632 m_at_beginning_of_statement = true;
5633 break;
5634
5635 case endmethods_kw:
5636 tok_val = new token (endmethods_kw, token::methods_end, m_tok_beg,
5637 m_tok_end);
5638 m_at_beginning_of_statement = true;
5639 break;
5640
5641 case endproperties_kw:
5642 tok_val = new token (endproperties_kw, token::properties_end, m_tok_beg,
5643 m_tok_end);
5644 m_at_beginning_of_statement = true;
5645 break;
5646
5647
5648 case for_kw:
5649 case parfor_kw:
5650 case while_kw:
5651 m_looping++;
5652 break;
5653
5654 case do_kw:
5655 m_at_beginning_of_statement = true;
5656 m_looping++;
5657 break;
5658
5659 case try_kw:
5660 case unwind_protect_kw:
5661 m_at_beginning_of_statement = true;
5662 break;
5663
5664 case if_kw:
5665 case switch_kw:
5666 break;
5667
5668 case get_kw:
5669 case set_kw:
5670 // 'get' and 'set' are keywords in classdef method
5671 // declarations.
5672 if (! m_maybe_classdef_get_set_method)
5673 {
5674 m_at_beginning_of_statement = previous_at_bos;
5675 return 0;
5676 }
5677 break;
5678
5679 case enumeration_kw:
5680 case events_kw:
5681 case methods_kw:
5682 case properties_kw:
5683 // 'properties', 'methods' and 'events' are keywords for
5684 // classdef blocks.
5685 if (! m_parsing_classdef)
5686 {
5687 m_at_beginning_of_statement = previous_at_bos;
5688 return 0;
5689 }
5690 // fall through ...
5691
5692 case classdef_kw:
5693 // 'classdef' is always a keyword.
5694 if (! m_force_script && m_token_count == 0 && input_from_file ())
5695 {
5696 m_reading_classdef_file = true;
5697 m_reading_script_file = false;
5698 }
5699 break;
5700
5701 case function_kw:
5702 m_defining_func++;
5703 m_parsed_function_name.push (false);
5704
5705 if (! m_force_script && m_token_count == 0 && input_from_file ())
5706 {
5707 m_reading_fcn_file = true;
5708 m_reading_script_file = false;
5709 }
5710
5711 if (! (m_reading_fcn_file || m_reading_script_file
5712 || m_reading_classdef_file))
5713 {
5714 // Input must be coming from the terminal or stdin?
5715 m_buffer_function_text = true;
5716 m_function_text += (m_current_input_line + "\n");
5717
5718 // FIXME: do we need to save and restore the file position
5719 // or just reset the line number here? The goal is to
5720 // track line info for command-line functions relative
5721 // to the function keyword.
5722
5723 m_filepos = filepos ();
5724 update_token_positions (slen);
5725 }
5726 break;
5727
5728 case magic_file_kw:
5729 {
5730 if ((m_reading_fcn_file || m_reading_script_file
5731 || m_reading_classdef_file)
5732 && ! m_fcn_file_full_name.empty ())
5733 tok_val = new token (magic_file_kw, m_fcn_file_full_name,
5734 m_tok_beg, m_tok_end);
5735 else
5736 tok_val = new token (magic_file_kw, "stdin", m_tok_beg, m_tok_end);
5737 }
5738 break;
5739
5740 case magic_line_kw:
5741 {
5742 int l = m_tok_beg.line ();
5743 tok_val = new token (magic_line_kw, static_cast<double> (l),
5744 "", m_tok_beg, m_tok_end);
5745 }
5746 break;
5747
5748 default:
5749 panic_impossible ();
5750 }
5751
5752 if (! tok_val)
5753 tok_val = new token (kw->tok, true, m_tok_beg, m_tok_end);
5754
5755 push_token (tok_val);
5756
5757 return kw->tok;
5758 }
5759
5760 bool
fq_identifier_contains_keyword(const std::string & s)5761 base_lexer::fq_identifier_contains_keyword (const std::string& s)
5762 {
5763 std::size_t p1 = 0;
5764 std::size_t p2;
5765
5766 std::string s_part;
5767
5768 do
5769 {
5770 p2 = s.find ('.', p1);
5771
5772 if (p2 != std::string::npos)
5773 {
5774 s_part = s.substr (p1, p2 - p1);
5775 p1 = p2 + 1;
5776 }
5777 else
5778 s_part = s.substr (p1);
5779
5780 if (iskeyword (s_part))
5781 return true;
5782 }
5783 while (p2 != std::string::npos);
5784
5785 return false;
5786 }
5787
5788 bool
whitespace_is_significant(void)5789 base_lexer::whitespace_is_significant (void)
5790 {
5791 return (m_nesting_level.is_bracket ()
5792 || (m_nesting_level.is_brace ()
5793 && ! m_looking_at_object_index.front ()));
5794 }
5795 }
5796
5797 static inline bool
looks_like_bin(const char * s,int len)5798 looks_like_bin (const char *s, int len)
5799 {
5800 return (len > 2 && s[0] == '0' && (s[1] == 'b' || s[1] == 'B'));
5801 }
5802
5803 static inline bool
looks_like_hex(const char * s,int len)5804 looks_like_hex (const char *s, int len)
5805 {
5806 return (len > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X'));
5807 }
5808
5809 namespace octave
5810 {
5811 void
handle_number(void)5812 base_lexer::handle_number (void)
5813 {
5814 double value = 0.0;
5815 int nread = 0;
5816
5817 char *yytxt = flex_yytext ();
5818
5819 // Strip any underscores
5820 char *tmptxt = strsave (yytxt);
5821 char *rptr = tmptxt;
5822 char *wptr = tmptxt;
5823 while (*rptr)
5824 {
5825 *wptr = *rptr++;
5826 wptr += (*wptr != '_');
5827 }
5828 *wptr = '\0';
5829
5830 if (looks_like_hex (tmptxt, strlen (tmptxt)))
5831 {
5832 uintmax_t long_int_value;
5833
5834 nread = sscanf (tmptxt, "%jx", &long_int_value);
5835
5836 value = static_cast<double> (long_int_value);
5837 }
5838 else if (looks_like_bin (tmptxt, strlen (tmptxt)))
5839 {
5840 uintmax_t long_int_value = 0;
5841
5842 for (std::size_t i = 0; i < strlen (tmptxt); i++)
5843 {
5844 if (tmptxt[i] == '0')
5845 long_int_value <<= 1;
5846 else if (tmptxt[i] == '1')
5847 {
5848 long_int_value <<= 1;
5849 long_int_value += 1;
5850 }
5851 }
5852
5853 value = static_cast<double> (long_int_value);
5854
5855 nread = 1; // Just to pass the assert stmt below
5856 }
5857 else
5858 {
5859 char *idx = strpbrk (tmptxt, "Dd");
5860
5861 if (idx)
5862 *idx = 'e';
5863
5864 nread = sscanf (tmptxt, "%lf", &value);
5865 }
5866
5867 delete [] tmptxt;
5868
5869 // If yytext doesn't contain a valid number, we are in deep doo doo.
5870
5871 assert (nread == 1);
5872
5873 m_looking_for_object_index = false;
5874 m_at_beginning_of_statement = false;
5875
5876 update_token_positions (flex_yyleng ());
5877
5878 push_token (new token (NUM, value, yytxt, m_tok_beg, m_tok_end));
5879 }
5880
5881 void
handle_continuation(void)5882 base_lexer::handle_continuation (void)
5883 {
5884 char *yytxt = flex_yytext ();
5885 int yylng = flex_yyleng ();
5886
5887 int offset = 1;
5888 if (yytxt[0] == '\\')
5889 warn_language_extension_continuation ();
5890 else
5891 offset = 3;
5892
5893 bool have_space = false;
5894 while (offset < yylng)
5895 {
5896 char c = yytxt[offset];
5897 if (is_space_or_tab (c))
5898 {
5899 have_space = true;
5900 offset++;
5901 }
5902 else
5903 break;
5904 }
5905
5906 if (have_space)
5907 mark_previous_token_trailing_space ();
5908
5909 bool have_comment = false;
5910 while (offset < yylng)
5911 {
5912 char c = yytxt[offset];
5913 if (c == '#' || c == '%')
5914 {
5915 have_comment = true;
5916 offset++;
5917 }
5918 else
5919 break;
5920 }
5921
5922 if (have_comment)
5923 {
5924 m_comment_text = &yytxt[offset];
5925
5926 // finish_comment sets m_at_beginning_of_statement to true but
5927 // that's not be correct if we are handling a continued
5928 // statement. Preserve the current state.
5929
5930 bool saved_bos = m_at_beginning_of_statement;
5931
5932 finish_comment (comment_elt::end_of_line);
5933
5934 m_at_beginning_of_statement = saved_bos;
5935 }
5936
5937 m_filepos.next_line ();
5938 }
5939
5940 void
finish_comment(comment_elt::comment_type typ)5941 base_lexer::finish_comment (comment_elt::comment_type typ)
5942 {
5943 bool copyright = looks_like_copyright (m_comment_text);
5944
5945 if (m_nesting_level.none () && m_help_text.empty () && ! m_comment_text.empty ()
5946 && ! copyright && ! looks_like_shebang (m_comment_text))
5947 m_help_text = m_comment_text;
5948
5949 if (copyright)
5950 typ = comment_elt::copyright;
5951
5952 m_comment_buf.append (m_comment_text, typ);
5953
5954 m_comment_text = "";
5955
5956 m_at_beginning_of_statement = true;
5957 }
5958
5959 int
handle_close_bracket(int bracket_type)5960 base_lexer::handle_close_bracket (int bracket_type)
5961 {
5962 m_looking_at_object_index.pop_front ();
5963
5964 m_looking_for_object_index = true;
5965 m_at_beginning_of_statement = false;
5966
5967 if (! m_nesting_level.none ())
5968 {
5969 m_nesting_level.remove ();
5970
5971 if (bracket_type == ']')
5972 m_bracketflag--;
5973 else if (bracket_type == '}')
5974 m_braceflag--;
5975 else
5976 panic_impossible ();
5977 }
5978
5979 pop_start_state ();
5980
5981 return count_token (bracket_type);
5982 }
5983
5984 bool
looks_like_command_arg(void)5985 base_lexer::looks_like_command_arg (void)
5986 {
5987 if (! m_allow_command_syntax)
5988 return false;
5989
5990 bool space_before = space_follows_previous_token ();
5991 bool space_after = looking_at_space ();
5992
5993 return (space_before && ! space_after
5994 && previous_token_may_be_command ());
5995 }
5996
5997 int
handle_superclass_identifier(void)5998 base_lexer::handle_superclass_identifier (void)
5999 {
6000 update_token_positions (flex_yyleng ());
6001
6002 std::string txt = flex_yytext ();
6003
6004 txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab),
6005 txt.end ());
6006
6007 std::size_t pos = txt.find ("@");
6008
6009 std::string meth = txt.substr (0, pos);
6010 std::string cls = txt.substr (pos + 1);
6011
6012 if (iskeyword (meth) || fq_identifier_contains_keyword (cls))
6013 {
6014 token *tok
6015 = new token (LEXICAL_ERROR,
6016 "method, class, and package names may not be keywords",
6017 m_tok_beg, m_tok_end);
6018
6019 push_token (tok);
6020
6021 return count_token_internal (LEXICAL_ERROR);
6022 }
6023
6024 push_token (new token (SUPERCLASSREF, meth, cls, m_tok_beg, m_tok_end));
6025
6026 m_filepos.increment_column (flex_yyleng ());
6027
6028 return count_token_internal (SUPERCLASSREF);
6029 }
6030
6031 int
handle_meta_identifier(void)6032 base_lexer::handle_meta_identifier (void)
6033 {
6034 std::string txt = flex_yytext ();
6035
6036 txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab),
6037 txt.end ());
6038
6039 // Eliminate leading '?'
6040 std::string cls = txt.substr (1);
6041
6042 // Token positions should have already been updated before this
6043 // function is called.
6044
6045 if (fq_identifier_contains_keyword (cls))
6046 {
6047 token *tok = new token (LEXICAL_ERROR,
6048 "class and package names may not be keywords",
6049 m_tok_beg, m_tok_end);
6050 push_token (tok);
6051
6052 return count_token_internal (LEXICAL_ERROR);
6053 }
6054
6055 push_token (new token (METAQUERY, cls, m_tok_beg, m_tok_end));
6056
6057 m_filepos.increment_column (flex_yyleng ());
6058
6059 return METAQUERY;
6060 }
6061
6062 int
handle_fq_identifier(void)6063 base_lexer::handle_fq_identifier (void)
6064 {
6065 std::string txt = flex_yytext ();
6066
6067 txt.erase (std::remove_if (txt.begin (), txt.end (), is_space_or_tab),
6068 txt.end ());
6069
6070 // Token positions should have already been updated before this
6071 // function is called.
6072
6073 if (fq_identifier_contains_keyword (txt))
6074 {
6075 token *tok
6076 = new token (LEXICAL_ERROR,
6077 "function, method, class, and package names may not be keywords",
6078 m_tok_beg, m_tok_end);
6079
6080 push_token (tok);
6081
6082 return count_token_internal (LEXICAL_ERROR);
6083 }
6084
6085 push_token (new token (FQ_IDENT, txt, m_tok_beg, m_tok_end));
6086
6087 m_filepos.increment_column (flex_yyleng ());
6088
6089 return FQ_IDENT;
6090 }
6091
6092 // Figure out exactly what kind of token to return when we have seen
6093 // an identifier. Handles keywords. Return -1 if the identifier
6094 // should be ignored.
6095
6096 int
handle_identifier(void)6097 base_lexer::handle_identifier (void)
6098 {
6099 update_token_positions (flex_yyleng ());
6100
6101 std::string ident = flex_yytext ();
6102
6103 // If we are expecting a structure element, avoid recognizing
6104 // keywords and other special names and return STRUCT_ELT, which is
6105 // a string that is also a valid identifier.
6106
6107 if (m_looking_at_indirect_ref)
6108 {
6109 push_token (new token (STRUCT_ELT, ident, m_tok_beg, m_tok_end));
6110
6111 m_looking_for_object_index = true;
6112
6113 return STRUCT_ELT;
6114 }
6115
6116 // If ident is a keyword token, then make_keyword_token will set
6117 // m_at_beginning_of_statement. For example, if tok is an IF
6118 // token, then m_at_beginning_of_statement will be false.
6119
6120 int kw_token = make_keyword_token (ident);
6121
6122 // If we have a regular keyword, return it.
6123 // Keywords can be followed by identifiers.
6124
6125 if (kw_token)
6126 {
6127 m_looking_for_object_index = false;
6128
6129 // The call to make_keyword_token set m_at_beginning_of_statement.
6130
6131 return count_token_internal (kw_token);
6132 }
6133
6134 // Find the token in the symbol table.
6135
6136 symbol_scope scope = m_symtab_context.curr_scope ();
6137
6138 symbol_record sr = (scope ? scope.insert (ident) : symbol_record (ident));
6139
6140 token *tok = new token (NAME, sr, m_tok_beg, m_tok_end);
6141
6142 // The following symbols are handled specially so that things like
6143 //
6144 // pi +1
6145 //
6146 // are parsed as an addition expression instead of as a command-style
6147 // function call with the argument "+1".
6148
6149 if (m_at_beginning_of_statement
6150 && ! (m_parsing_anon_fcn_body
6151 || is_variable (ident, scope)
6152 || ident == "e" || ident == "pi"
6153 || ident == "I" || ident == "i"
6154 || ident == "J" || ident == "j"
6155 || ident == "Inf" || ident == "inf"
6156 || ident == "NaN" || ident == "nan"))
6157 tok->mark_may_be_command ();
6158
6159 push_token (tok);
6160
6161 // The magic end index can't be indexed.
6162
6163 if (ident != "end")
6164 m_looking_for_object_index = true;
6165
6166 m_at_beginning_of_statement = false;
6167
6168 return count_token_internal (NAME);
6169 }
6170
6171 void
maybe_warn_separator_insert(char sep)6172 base_lexer::maybe_warn_separator_insert (char sep)
6173 {
6174 std::string nm = m_fcn_file_full_name;
6175
6176 if (nm.empty ())
6177 warning_with_id ("Octave:separator-insert",
6178 "potential auto-insertion of '%c' near line %d",
6179 sep, m_filepos.line ());
6180 else
6181 warning_with_id ("Octave:separator-insert",
6182 "potential auto-insertion of '%c' near line %d of file %s",
6183 sep, m_filepos.line (), nm.c_str ());
6184 }
6185
6186 void
warn_single_quote_string(void)6187 base_lexer::warn_single_quote_string (void)
6188 {
6189 std::string nm = m_fcn_file_full_name;
6190
6191 if (nm.empty ())
6192 warning_with_id ("Octave:single-quote-string",
6193 "single quote delimited string near line %d",
6194 m_filepos.line ());
6195 else
6196 warning_with_id ("Octave:single-quote-string",
6197 "single quote delimited string near line %d of file %s",
6198 m_filepos.line (), nm.c_str ());
6199 }
6200
6201 void
warn_language_extension(const std::string & msg)6202 base_lexer::warn_language_extension (const std::string& msg)
6203 {
6204 std::string nm = m_fcn_file_full_name;
6205
6206 if (nm.empty ())
6207 warning_with_id ("Octave:language-extension",
6208 "Octave language extension used: %s",
6209 msg.c_str ());
6210 else
6211 warning_with_id ("Octave:language-extension",
6212 "Octave language extension used: %s near line %d offile %s",
6213 msg.c_str (), m_filepos.line (), nm.c_str ());
6214 }
6215
6216 void
maybe_warn_language_extension_comment(char c)6217 base_lexer::maybe_warn_language_extension_comment (char c)
6218 {
6219 if (c == '#')
6220 warn_language_extension ("# used as comment character");
6221 }
6222
6223 void
warn_language_extension_continuation(void)6224 base_lexer::warn_language_extension_continuation (void)
6225 {
6226 warn_language_extension ("\\ used as line continuation marker");
6227 }
6228
6229 void
warn_language_extension_operator(const std::string & op)6230 base_lexer::warn_language_extension_operator (const std::string& op)
6231 {
6232 std::string t = op;
6233 int n = t.length ();
6234 if (t[n-1] == '\n')
6235 t.resize (n-1);
6236 warn_language_extension (t + " used as operator");
6237 }
6238
6239 void
push_token(token * tok)6240 base_lexer::push_token (token *tok)
6241 {
6242 YYSTYPE *lval = yyget_lval (m_scanner);
6243 lval->tok_val = tok;
6244 m_tokens.push (tok);
6245 }
6246
6247 token *
current_token(void)6248 base_lexer::current_token (void)
6249 {
6250 YYSTYPE *lval = yyget_lval (m_scanner);
6251 return lval->tok_val;
6252 }
6253
6254 std::size_t
pending_token_count(void) const6255 base_lexer::pending_token_count (void) const
6256 {
6257 return m_tokens.size ();
6258 }
6259
6260 void
display_token(int tok)6261 base_lexer::display_token (int tok)
6262 {
6263 switch (tok)
6264 {
6265 case '=': std::cerr << "'='\n"; break;
6266 case ':': std::cerr << "':'\n"; break;
6267 case '-': std::cerr << "'-'\n"; break;
6268 case '+': std::cerr << "'+'\n"; break;
6269 case '*': std::cerr << "'*'\n"; break;
6270 case '/': std::cerr << "'/'\n"; break;
6271 case ADD_EQ: std::cerr << "ADD_EQ\n"; break;
6272 case SUB_EQ: std::cerr << "SUB_EQ\n"; break;
6273 case MUL_EQ: std::cerr << "MUL_EQ\n"; break;
6274 case DIV_EQ: std::cerr << "DIV_EQ\n"; break;
6275 case LEFTDIV_EQ: std::cerr << "LEFTDIV_EQ\n"; break;
6276 case POW_EQ: std::cerr << "POW_EQ\n"; break;
6277 case EMUL_EQ: std::cerr << "EMUL_EQ\n"; break;
6278 case EDIV_EQ: std::cerr << "EDIV_EQ\n"; break;
6279 case ELEFTDIV_EQ: std::cerr << "ELEFTDIV_EQ\n"; break;
6280 case EPOW_EQ: std::cerr << "EPOW_EQ\n"; break;
6281 case AND_EQ: std::cerr << "AND_EQ\n"; break;
6282 case OR_EQ: std::cerr << "OR_EQ\n"; break;
6283 case EXPR_AND_AND: std::cerr << "EXPR_AND_AND\n"; break;
6284 case EXPR_OR_OR: std::cerr << "EXPR_OR_OR\n"; break;
6285 case EXPR_AND: std::cerr << "EXPR_AND\n"; break;
6286 case EXPR_OR: std::cerr << "EXPR_OR\n"; break;
6287 case EXPR_NOT: std::cerr << "EXPR_NOT\n"; break;
6288 case EXPR_LT: std::cerr << "EXPR_LT\n"; break;
6289 case EXPR_LE: std::cerr << "EXPR_LE\n"; break;
6290 case EXPR_EQ: std::cerr << "EXPR_EQ\n"; break;
6291 case EXPR_NE: std::cerr << "EXPR_NE\n"; break;
6292 case EXPR_GE: std::cerr << "EXPR_GE\n"; break;
6293 case EXPR_GT: std::cerr << "EXPR_GT\n"; break;
6294 case LEFTDIV: std::cerr << "LEFTDIV\n"; break;
6295 case EMUL: std::cerr << "EMUL\n"; break;
6296 case EDIV: std::cerr << "EDIV\n"; break;
6297 case ELEFTDIV: std::cerr << "ELEFTDIV\n"; break;
6298 case EPLUS: std::cerr << "EPLUS\n"; break;
6299 case EMINUS: std::cerr << "EMINUS\n"; break;
6300 case HERMITIAN: std::cerr << "HERMITIAN\n"; break;
6301 case TRANSPOSE: std::cerr << "TRANSPOSE\n"; break;
6302 case PLUS_PLUS: std::cerr << "PLUS_PLUS\n"; break;
6303 case MINUS_MINUS: std::cerr << "MINUS_MINUS\n"; break;
6304 case POW: std::cerr << "POW\n"; break;
6305 case EPOW: std::cerr << "EPOW\n"; break;
6306
6307 case NUM:
6308 case IMAG_NUM:
6309 {
6310 token *tok_val = current_token ();
6311 std::cerr << (tok == NUM ? "NUM" : "IMAG_NUM")
6312 << " [" << tok_val->number () << "]\n";
6313 }
6314 break;
6315
6316 case STRUCT_ELT:
6317 {
6318 token *tok_val = current_token ();
6319 std::cerr << "STRUCT_ELT [" << tok_val->text () << "]\n";
6320 }
6321 break;
6322
6323 case NAME:
6324 {
6325 token *tok_val = current_token ();
6326 symbol_record sr = tok_val->sym_rec ();
6327 std::cerr << "NAME [" << sr.name () << "]\n";
6328 }
6329 break;
6330
6331 case END: std::cerr << "END\n"; break;
6332
6333 case DQ_STRING:
6334 case SQ_STRING:
6335 {
6336 token *tok_val = current_token ();
6337
6338 std::cerr << (tok == DQ_STRING ? "DQ_STRING" : "SQ_STRING")
6339 << " [" << tok_val->text () << "]\n";
6340 }
6341 break;
6342
6343 case FOR: std::cerr << "FOR\n"; break;
6344 case WHILE: std::cerr << "WHILE\n"; break;
6345 case DO: std::cerr << "DO\n"; break;
6346 case UNTIL: std::cerr << "UNTIL\n"; break;
6347 case IF: std::cerr << "IF\n"; break;
6348 case ELSEIF: std::cerr << "ELSEIF\n"; break;
6349 case ELSE: std::cerr << "ELSE\n"; break;
6350 case SWITCH: std::cerr << "SWITCH\n"; break;
6351 case CASE: std::cerr << "CASE\n"; break;
6352 case OTHERWISE: std::cerr << "OTHERWISE\n"; break;
6353 case BREAK: std::cerr << "BREAK\n"; break;
6354 case CONTINUE: std::cerr << "CONTINUE\n"; break;
6355 case FUNC_RET: std::cerr << "FUNC_RET\n"; break;
6356 case UNWIND: std::cerr << "UNWIND\n"; break;
6357 case CLEANUP: std::cerr << "CLEANUP\n"; break;
6358 case TRY: std::cerr << "TRY\n"; break;
6359 case CATCH: std::cerr << "CATCH\n"; break;
6360 case GLOBAL: std::cerr << "GLOBAL\n"; break;
6361 case PERSISTENT: std::cerr << "PERSISTENT\n"; break;
6362 case FCN_HANDLE: std::cerr << "FCN_HANDLE\n"; break;
6363 case END_OF_INPUT: std::cerr << "END_OF_INPUT\n\n"; break;
6364 case LEXICAL_ERROR: std::cerr << "LEXICAL_ERROR\n\n"; break;
6365 case FCN: std::cerr << "FCN\n"; break;
6366 case INPUT_FILE: std::cerr << "INPUT_FILE\n"; break;
6367 case SUPERCLASSREF: std::cerr << "SUPERCLASSREF\n"; break;
6368 case METAQUERY: std::cerr << "METAQUERY\n"; break;
6369 case GET: std::cerr << "GET\n"; break;
6370 case SET: std::cerr << "SET\n"; break;
6371 case PROPERTIES: std::cerr << "PROPERTIES\n"; break;
6372 case METHODS: std::cerr << "METHODS\n"; break;
6373 case EVENTS: std::cerr << "EVENTS\n"; break;
6374 case CLASSDEF: std::cerr << "CLASSDEF\n"; break;
6375 case '\n': std::cerr << "\\n\n"; break;
6376 case '\r': std::cerr << "\\r\n"; break;
6377 case '\t': std::cerr << "TAB\n"; break;
6378 default:
6379 {
6380 if (tok < 256 && tok > 31)
6381 std::cerr << static_cast<char> (tok) << "\n";
6382 else
6383 std::cerr << "UNKNOWN(" << tok << ")\n";
6384 }
6385 break;
6386 }
6387 }
6388
6389 void
fatal_error(const char * msg)6390 base_lexer::fatal_error (const char *msg)
6391 {
6392 error ("fatal lexer error: %s", msg);
6393 }
6394
6395 bool
debug_flag(void) const6396 base_lexer::debug_flag (void) const
6397 {
6398 settings& stgs = m_interpreter.get_settings ();
6399 return stgs.lexer_debug_flag ();
6400 }
6401
6402 bool
display_tokens(void) const6403 base_lexer::display_tokens (void) const
6404 {
6405 settings& stgs = m_interpreter.get_settings ();
6406 return stgs.display_tokens ();
6407 }
6408
6409 void
increment_token_count(void)6410 base_lexer::increment_token_count (void)
6411 {
6412 settings& stgs = m_interpreter.get_settings ();
6413 stgs.increment_token_count ();
6414
6415 m_token_count++;
6416 }
6417
6418 void
lexer_debug(const char * pattern)6419 base_lexer::lexer_debug (const char *pattern)
6420 {
6421 if (debug_flag ())
6422 {
6423 std::cerr << std::endl;
6424
6425 display_start_state ();
6426
6427 std::cerr << "P: " << pattern << std::endl;
6428 std::cerr << "T: " << flex_yytext () << std::endl;
6429 }
6430 }
6431
6432 bool
input_from_tmp_history_file(void)6433 base_lexer::input_from_tmp_history_file (void)
6434 {
6435 history_system& history_sys = m_interpreter.get_history_system ();
6436
6437 return history_sys.input_from_tmp_file ();
6438 }
6439
6440 void
push_start_state(int state)6441 base_lexer::push_start_state (int state)
6442 {
6443 OCTAVE_YYG;
6444
6445 start_state_stack.push (state);
6446
6447 BEGIN (start_state ());
6448 }
6449
6450 void
pop_start_state(void)6451 base_lexer::pop_start_state (void)
6452 {
6453 OCTAVE_YYG;
6454
6455 start_state_stack.pop ();
6456
6457 BEGIN (start_state ());
6458 }
6459
6460 void
clear_start_state(void)6461 base_lexer::clear_start_state (void)
6462 {
6463 while (! start_state_stack.empty ())
6464 start_state_stack.pop ();
6465
6466 push_start_state (INITIAL);
6467 }
6468
6469 void
display_start_state(void) const6470 base_lexer::display_start_state (void) const
6471 {
6472 std::cerr << "S: ";
6473
6474 switch (start_state ())
6475 {
6476 case INITIAL:
6477 std::cerr << "INITIAL" << std::endl;
6478 break;
6479
6480 case COMMAND_START:
6481 std::cerr << "COMMAND_START" << std::endl;
6482 break;
6483
6484 case MATRIX_START:
6485 std::cerr << "MATRIX_START" << std::endl;
6486 break;
6487
6488 case INPUT_FILE_START:
6489 std::cerr << "INPUT_FILE_START" << std::endl;
6490 break;
6491
6492 case BLOCK_COMMENT_START:
6493 std::cerr << "BLOCK_COMMENT_START" << std::endl;
6494 break;
6495
6496 case LINE_COMMENT_START:
6497 std::cerr << "LINE_COMMENT_START" << std::endl;
6498 break;
6499
6500 case DQ_STRING_START:
6501 std::cerr << "DQ_STRING_START" << std::endl;
6502 break;
6503
6504 case SQ_STRING_START:
6505 std::cerr << "SQ_STRING_START" << std::endl;
6506 break;
6507
6508 case FQ_IDENT_START:
6509 std::cerr << "FQ_IDENT_START" << std::endl;
6510 break;
6511
6512 default:
6513 std::cerr << "UNKNOWN START STATE!" << std::endl;
6514 break;
6515 }
6516 }
6517
6518 bool
maybe_unput_comma_before_unary_op(int tok)6519 base_lexer::maybe_unput_comma_before_unary_op (int tok)
6520 {
6521 int prev_tok = previous_token_value ();
6522
6523 bool unput_comma = false;
6524
6525 if (whitespace_is_significant () && space_follows_previous_token ())
6526 {
6527 int c = text_yyinput ();
6528 xunput (c);
6529
6530 bool space_after = is_space_or_tab (c);
6531
6532 if (! (prev_tok == '[' || prev_tok == '{'
6533 || previous_token_is_binop ()
6534 || ((tok == '+' || tok == '-') && space_after)))
6535 unput_comma = true;
6536 }
6537
6538 return unput_comma;
6539 }
6540
6541 int
handle_op(int tok,bool bos,bool compat)6542 base_lexer::handle_op (int tok, bool bos, bool compat)
6543 {
6544 if (! compat)
6545 warn_language_extension_operator (flex_yytext ());
6546
6547 update_token_positions (flex_yyleng ());
6548
6549 push_token (new token (tok, m_tok_beg, m_tok_end));
6550
6551 m_looking_for_object_index = false;
6552 m_at_beginning_of_statement = bos;
6553
6554 switch (tok)
6555 {
6556 case EXPR_LT:
6557 if (m_parsing_classdef_decl)
6558 {
6559 m_parsing_classdef_superclass = true;
6560 push_start_state (FQ_IDENT_START);
6561 }
6562 break;
6563
6564 case EXPR_AND:
6565 if (m_parsing_classdef_superclass)
6566 push_start_state (FQ_IDENT_START);
6567 break;
6568
6569 default:
6570 break;
6571 }
6572
6573 return count_token_internal (tok);
6574 }
6575
6576 // When a command argument boundary is detected, push out the current
6577 // argument being built. This one seems like a good candidate for a
6578 // function call.
6579
6580 int
finish_command_arg(void)6581 base_lexer::finish_command_arg (void)
6582 {
6583 int tok = SQ_STRING;
6584
6585 token *tok_val = new token (tok, m_string_text, m_tok_beg, m_tok_end);
6586
6587 m_string_text = "";
6588 m_command_arg_paren_count = 0;
6589
6590 return handle_token (tok, tok_val);
6591 }
6592
6593 int
handle_token(int tok,token * tok_val)6594 base_lexer::handle_token (int tok, token *tok_val)
6595 {
6596 if (! tok_val)
6597 tok_val = new token (tok, m_tok_beg, m_tok_end);
6598
6599 push_token (tok_val);
6600
6601 return count_token_internal (tok);
6602 }
6603
6604 int
count_token(int tok)6605 base_lexer::count_token (int tok)
6606 {
6607 token *tok_val = new token (tok, m_tok_beg, m_tok_end);
6608
6609 push_token (tok_val);
6610
6611 return count_token_internal (tok);
6612 }
6613
6614 int
count_token_internal(int tok)6615 base_lexer::count_token_internal (int tok)
6616 {
6617 if (tok != '\n')
6618 increment_token_count ();
6619
6620 return show_token (tok);
6621 }
6622
6623 int
show_token(int tok)6624 base_lexer::show_token (int tok)
6625 {
6626
6627 if (display_tokens ())
6628 display_token (tok);
6629
6630 if (debug_flag ())
6631 {
6632 std::cerr << "R: ";
6633 display_token (tok);
6634 std::cerr << std::endl;
6635 }
6636
6637 return tok;
6638 }
6639
6640 int
fill_flex_buffer(char * buf,unsigned max_size)6641 lexer::fill_flex_buffer (char *buf, unsigned max_size)
6642 {
6643 int status = 0;
6644
6645 if (m_input_buf.empty ())
6646 {
6647 input_system& input_sys = m_interpreter.get_input_system ();
6648
6649 std::string ps
6650 = m_initial_input ? input_sys.PS1 () : input_sys.PS2 ();
6651
6652 std::string prompt = command_editor::decode_prompt_string (ps);
6653
6654 bool eof = false;
6655 m_current_input_line = m_reader.get_input (prompt, eof);
6656
6657 m_input_buf.fill (m_current_input_line, eof);
6658
6659 // Attempt to capture text for functions defined on the
6660 // command line.
6661 //
6662 // FIXME: the handling of newline here seems a bit clumsy.
6663 //
6664 // See also comments in push_lexer::append_input.
6665
6666 if (m_buffer_function_text)
6667 {
6668 if (! m_current_input_line.empty ())
6669 {
6670 m_function_text += m_current_input_line;
6671 if (m_current_input_line.back () != '\n')
6672 m_function_text += '\n';
6673 }
6674 }
6675 }
6676
6677 if (! m_input_buf.empty ())
6678 status = m_input_buf.copy_chunk (buf, max_size);
6679 else
6680 status = YY_NULL;
6681
6682 m_initial_input = false;
6683
6684 return status;
6685 }
6686
6687 void
append_input(const std::string & input,bool eof)6688 push_lexer::append_input (const std::string& input, bool eof)
6689 {
6690 // FIXME: input may contain more than one line, so how can we
6691 // properly start buffering input for command-line functions?
6692 //
6693 // Currently, base_lexer::make_keyword_token starts buffering text
6694 // for command-line functions by setting the initial value of
6695 // m_function_text to m_current_input_line when function_kw is
6696 // recognized. To make that work, we need to do something like
6697 // maintain a queue of input strings and pass them to the flex
6698 // buffer one line at a time, while also setting
6699 // m_current_input_line. Some care will be needed if a single line
6700 // of input arrives in multiple calls to append_input.
6701 //
6702 // OR, should we require that the input string to append_input
6703 // IS a single line of input? That seems to be what we are doing
6704 // here by setting m_current_input_line to input.
6705
6706 m_input_buf.fill (input, eof);
6707 m_current_input_line = input;
6708 }
6709
6710 int
fill_flex_buffer(char * buf,unsigned max_size)6711 push_lexer::fill_flex_buffer (char *buf, unsigned max_size)
6712 {
6713 int status = 0;
6714
6715 if (m_input_buf.empty () && ! m_input_buf.at_eof ())
6716 {
6717 // If the input buffer is empty or we are at the end of the
6718 // buffer, insert ASCII 1 as a marker for subsequent rules.
6719 // Don't insert a newline character in this case. Instead of
6720 // calling input_buffer::fill followed immediately by
6721 // input_buffer::copy_chunk, simply insert the marker directly
6722 // in BUF.
6723
6724 assert (max_size > 0);
6725
6726 buf[0] = static_cast<char> (1);
6727 status = 1;
6728 }
6729 else
6730 {
6731 // Note that the copy_chunk function may append a newline
6732 // character to the input.
6733
6734 if (! m_input_buf.empty ())
6735 status = m_input_buf.copy_chunk (buf, max_size, true);
6736 else
6737 status = YY_NULL;
6738 }
6739
6740 return status;
6741 }
6742 }
6743
6744