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