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