comparison libinterp/parse-tree/lex.ll @ 16224:4a848eb52de2

use stack for tracking lexer start states * lex.h (octave_lexer::start_state_stack): New member variable. (octave_lexer::push_start_state, octave_lexer::pop_start_state, octave_lexer::clear_start_state, octave_lexer::start_state, octave_lexer::display_start_state): New functions. * lex.ll (INPUT_FILE_START): Rename from INPUT_FILE_BEGIN. Use push_start_state and pop_start_state instead of switching flex start states directly with the flex BEGIN macro. (octave_lexer::init, octave_lexer::reset): Clear start state stack. (octave_lexer::prep_for_file, octave_lexer::process_comment, octave_lexer::handle_close_bracket): Don't use OCTAVE_YYG macro. (octave_lexer::display_start_state): Rename from display_state. Eliminate argument. Display current start state.
author John W. Eaton <jwe@octave.org>
date Fri, 08 Mar 2013 10:46:13 -0500
parents e7ff32e7cf82
children e19b1632d7c1
comparison
equal deleted inserted replaced
16223:caf4f386aaab 16224:4a848eb52de2
44 } 44 }
45 45
46 %s COMMAND_START 46 %s COMMAND_START
47 %s MATRIX_START 47 %s MATRIX_START
48 48
49 %x INPUT_FILE_BEGIN 49 %x INPUT_FILE_START
50 50
51 %{ 51 %{
52 52
53 #include <cctype> 53 #include <cctype>
54 #include <cstring> 54 #include <cstring>
257 %{ 257 %{
258 // Make script and function files start with a bogus token. This makes 258 // Make script and function files start with a bogus token. This makes
259 // the parser go down a special path. 259 // the parser go down a special path.
260 %} 260 %}
261 261
262 <INPUT_FILE_BEGIN>. { 262 <INPUT_FILE_START>. {
263 LEXER_DEBUG ("<INPUT_FILE_BEGIN>."); 263 LEXER_DEBUG ("<INPUT_FILE_START>.");
264 264
265 BEGIN (INITIAL);
266 curr_lexer->xunput (yytext[0]); 265 curr_lexer->xunput (yytext[0]);
267 266
268 // May be reset later if we see "function" or "classdef" appears 267 // May be reset later if we see "function" or "classdef" appears
269 // as the first token. 268 // as the first token.
270 curr_lexer->reading_script_file = true; 269 curr_lexer->reading_script_file = true;
271 270
271 curr_lexer->pop_start_state ();
272
272 DISPLAY_TOK_AND_RETURN (INPUT_FILE); 273 DISPLAY_TOK_AND_RETURN (INPUT_FILE);
273 } 274 }
274 275
275 %{ 276 %{
276 // Help and other command-style functions. 277 // Help and other command-style functions.
277 %} 278 %}
278 279
279 <COMMAND_START>{NL} { 280 <COMMAND_START>{NL} {
280 LEXER_DEBUG ("<COMMAND_START>{NL}"); 281 LEXER_DEBUG ("<COMMAND_START>{NL}");
281 282
282 BEGIN (INITIAL);
283 curr_lexer->input_line_number++; 283 curr_lexer->input_line_number++;
284 curr_lexer->current_input_column = 1; 284 curr_lexer->current_input_column = 1;
285 285
286 curr_lexer->quote_is_transpose = false; 286 curr_lexer->quote_is_transpose = false;
287 curr_lexer->convert_spaces_to_comma = true; 287 curr_lexer->convert_spaces_to_comma = true;
288 curr_lexer->looking_for_object_index = false; 288 curr_lexer->looking_for_object_index = false;
289 curr_lexer->at_beginning_of_statement = true; 289 curr_lexer->at_beginning_of_statement = true;
290 290
291 curr_lexer->pop_start_state ();
292
291 COUNT_TOK_AND_RETURN ('\n'); 293 COUNT_TOK_AND_RETURN ('\n');
292 } 294 }
293 295
294 <COMMAND_START>[\;\,] { 296 <COMMAND_START>[\;\,] {
295 LEXER_DEBUG ("<COMMAND_START>[\\;\\,]"); 297 LEXER_DEBUG ("<COMMAND_START>[\\;\\,]");
296 298
297 curr_lexer->looking_for_object_index = false; 299 curr_lexer->looking_for_object_index = false;
298 curr_lexer->at_beginning_of_statement = true; 300 curr_lexer->at_beginning_of_statement = true;
299 301
300 BEGIN (INITIAL); 302 curr_lexer->pop_start_state ();
301 303
302 if (strcmp (yytext, ",") == 0) 304 if (strcmp (yytext, ",") == 0)
303 TOK_RETURN (','); 305 TOK_RETURN (',');
304 else 306 else
305 TOK_RETURN (';'); 307 TOK_RETURN (';');
540 542
541 curr_lexer->decrement_promptflag (); 543 curr_lexer->decrement_promptflag ();
542 curr_lexer->eat_whitespace (); 544 curr_lexer->eat_whitespace ();
543 545
544 curr_lexer->bracketflag++; 546 curr_lexer->bracketflag++;
545 BEGIN (MATRIX_START); 547
548 curr_lexer->push_start_state (MATRIX_START);
549
546 COUNT_TOK_AND_RETURN ('['); 550 COUNT_TOK_AND_RETURN ('[');
547 } 551 }
548 552
549 \] { 553 \] {
550 LEXER_DEBUG ("\\]"); 554 LEXER_DEBUG ("\\]");
922 926
923 curr_lexer->decrement_promptflag (); 927 curr_lexer->decrement_promptflag ();
924 curr_lexer->eat_whitespace (); 928 curr_lexer->eat_whitespace ();
925 929
926 curr_lexer->braceflag++; 930 curr_lexer->braceflag++;
927 BEGIN (MATRIX_START); 931
932 curr_lexer->push_start_state (MATRIX_START);
933
928 COUNT_TOK_AND_RETURN ('{'); 934 COUNT_TOK_AND_RETURN ('{');
929 } 935 }
930 936
931 "}" { 937 "}" {
932 LEXER_DEBUG ("}"); 938 LEXER_DEBUG ("}");
1422 yylex_init (&scanner); 1428 yylex_init (&scanner);
1423 1429
1424 // Make octave_lexer object available through yyextra in 1430 // Make octave_lexer object available through yyextra in
1425 // flex-generated lexer. 1431 // flex-generated lexer.
1426 yyset_extra (this, scanner); 1432 yyset_extra (this, scanner);
1433
1434 clear_start_state ();
1427 } 1435 }
1428 1436
1429 // Inside Flex-generated functions, yyg is the scanner cast to its real 1437 // Inside Flex-generated functions, yyg is the scanner cast to its real
1430 // type. The BEGIN macro uses yyg and we want to use that in 1438 // type. Some flex macros that we use in octave_lexer member functions
1431 // octave_lexer member functions. If we could set the start state 1439 // (for example, BEGIN) use yyg. If we could perform the actions of
1432 // by calling a function instead of using the BEGIN macro, we could 1440 // these macros with functions instead, we could eliminate the
1433 // eliminate the OCTAVE_YYG macro. 1441 // OCTAVE_YYG macro.
1434 1442
1435 #define OCTAVE_YYG \ 1443 #define OCTAVE_YYG \
1436 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner) 1444 struct yyguts_t *yyg = static_cast<struct yyguts_t*> (scanner)
1437 1445
1438 void 1446 void
1439 octave_lexer::reset (void) 1447 octave_lexer::reset (void)
1440 { 1448 {
1441 OCTAVE_YYG;
1442
1443 // Start off on the right foot. 1449 // Start off on the right foot.
1444 BEGIN (INITIAL); 1450 clear_start_state ();
1445 1451
1446 parser_symtab_context.clear (); 1452 parser_symtab_context.clear ();
1447 1453
1448 // We do want a prompt by default. 1454 // We do want a prompt by default.
1449 promptflag (1); 1455 promptflag (1);
1465 } 1471 }
1466 1472
1467 void 1473 void
1468 octave_lexer::prep_for_file (void) 1474 octave_lexer::prep_for_file (void)
1469 { 1475 {
1470 OCTAVE_YYG;
1471
1472 reading_script_file = true; 1476 reading_script_file = true;
1473 1477
1474 BEGIN (INPUT_FILE_BEGIN); 1478 push_start_state (INPUT_FILE_START);
1475 } 1479 }
1476 1480
1477 int 1481 int
1478 octave_lexer::read (char *buf, unsigned max_size) 1482 octave_lexer::read (char *buf, unsigned max_size)
1479 { 1483 {
2155 } 2159 }
2156 2160
2157 int 2161 int
2158 octave_lexer::process_comment (bool start_in_block, bool& eof) 2162 octave_lexer::process_comment (bool start_in_block, bool& eof)
2159 { 2163 {
2160 OCTAVE_YYG;
2161
2162 eof = false; 2164 eof = false;
2163 2165
2164 char *yytxt = flex_yytext (); 2166 char *yytxt = flex_yytext ();
2165 flex_stream_reader flex_reader (this, yytxt); 2167 flex_stream_reader flex_reader (this, yytxt);
2166 2168
2183 current_input_column = 1; 2185 current_input_column = 1;
2184 quote_is_transpose = false; 2186 quote_is_transpose = false;
2185 convert_spaces_to_comma = true; 2187 convert_spaces_to_comma = true;
2186 at_beginning_of_statement = true; 2188 at_beginning_of_statement = true;
2187 2189
2188 if (YY_START == COMMAND_START) 2190 if (start_state () == COMMAND_START)
2189 BEGIN (INITIAL); 2191 pop_start_state ();
2190 2192
2191 if (nesting_level.none ()) 2193 if (nesting_level.none ())
2192 return '\n'; 2194 return '\n';
2193 else if (nesting_level.is_bracket_or_brace ()) 2195 else if (nesting_level.is_bracket_or_brace ())
2194 return ';'; 2196 return ';';
2910 } 2912 }
2911 2913
2912 int 2914 int
2913 octave_lexer::handle_close_bracket (bool spc_gobbled, int bracket_type) 2915 octave_lexer::handle_close_bracket (bool spc_gobbled, int bracket_type)
2914 { 2916 {
2915 OCTAVE_YYG;
2916
2917 int retval = bracket_type; 2917 int retval = bracket_type;
2918 2918
2919 if (! nesting_level.none ()) 2919 if (! nesting_level.none ())
2920 { 2920 {
2921 nesting_level.remove (); 2921 nesting_level.remove ();
2926 braceflag--; 2926 braceflag--;
2927 else 2927 else
2928 panic_impossible (); 2928 panic_impossible ();
2929 } 2929 }
2930 2930
2931 if (bracketflag == 0 && braceflag == 0) 2931 pop_start_state ();
2932 BEGIN (INITIAL);
2933 2932
2934 if (bracket_type == ']' 2933 if (bracket_type == ']'
2935 && next_token_is_assign_op () 2934 && next_token_is_assign_op ()
2936 && ! looking_at_return_list) 2935 && ! looking_at_return_list)
2937 { 2936 {
3475 if (! is_variable (tok)) 3474 if (! is_variable (tok))
3476 { 3475 {
3477 if (at_bos && spc_gobbled && can_be_command (tok) 3476 if (at_bos && spc_gobbled && can_be_command (tok)
3478 && looks_like_command_arg ()) 3477 && looks_like_command_arg ())
3479 { 3478 {
3480 BEGIN (COMMAND_START); 3479 push_start_state (COMMAND_START);
3481 } 3480 }
3482 else if (next_tok_is_eq 3481 else if (next_tok_is_eq
3483 || looking_at_decl_list 3482 || looking_at_decl_list
3484 || looking_at_return_list 3483 || looking_at_return_list
3485 || (looking_at_parameter_list 3484 || (looking_at_parameter_list
3742 } 3741 }
3743 break; 3742 break;
3744 } 3743 }
3745 } 3744 }
3746 3745
3747 static void 3746 void
3748 display_state (int state) 3747 octave_lexer::fatal_error (const char *msg)
3748 {
3749 error (msg);
3750
3751 OCTAVE_QUIT;
3752
3753 yy_fatal_error (msg, scanner);
3754 }
3755
3756 void
3757 octave_lexer::lexer_debug (const char *pattern, const char *text)
3758 {
3759 std::cerr << std::endl;
3760
3761 display_start_state ();
3762
3763 std::cerr << "P: " << pattern << std::endl;
3764 std::cerr << "T: " << text << std::endl;
3765 }
3766
3767 void
3768 octave_lexer::push_start_state (int state)
3769 {
3770 OCTAVE_YYG;
3771
3772 start_state_stack.push (state);
3773
3774 BEGIN (start_state ());
3775 }
3776
3777 void
3778 octave_lexer::pop_start_state (void)
3779 {
3780 OCTAVE_YYG;
3781
3782 start_state_stack.pop ();
3783
3784 BEGIN (start_state ());
3785 }
3786
3787 void
3788 octave_lexer::clear_start_state (void)
3789 {
3790 while (! start_state_stack.empty ())
3791 start_state_stack.pop ();
3792
3793 push_start_state (INITIAL);
3794 }
3795
3796 void
3797 octave_lexer::display_start_state (void) const
3749 { 3798 {
3750 std::cerr << "S: "; 3799 std::cerr << "S: ";
3751 3800
3752 switch (state) 3801 switch (start_state ())
3753 { 3802 {
3754 case INITIAL: 3803 case INITIAL:
3755 std::cerr << "INITIAL" << std::endl; 3804 std::cerr << "INITIAL" << std::endl;
3756 break; 3805 break;
3757 3806
3761 3810
3762 case MATRIX_START: 3811 case MATRIX_START:
3763 std::cerr << "MATRIX_START" << std::endl; 3812 std::cerr << "MATRIX_START" << std::endl;
3764 break; 3813 break;
3765 3814
3766 case INPUT_FILE_BEGIN: 3815 case INPUT_FILE_START:
3767 std::cerr << "INPUT_FILE_BEGIN" << std::endl; 3816 std::cerr << "INPUT_FILE_BEGIN" << std::endl;
3768 break; 3817 break;
3769 3818
3770 default: 3819 default:
3771 std::cerr << "UNKNOWN START STATE!" << std::endl; 3820 std::cerr << "UNKNOWN START STATE!" << std::endl;
3772 break; 3821 break;
3773 } 3822 }
3774 } 3823 }
3775
3776 void
3777 octave_lexer::fatal_error (const char *msg)
3778 {
3779 error (msg);
3780
3781 OCTAVE_QUIT;
3782
3783 yy_fatal_error (msg, scanner);
3784 }
3785
3786 void
3787 octave_lexer::lexer_debug (const char *pattern, const char *text)
3788 {
3789 OCTAVE_YYG;
3790
3791 std::cerr << std::endl;
3792
3793 display_state (YY_START);
3794
3795 std::cerr << "P: " << pattern << std::endl;
3796 std::cerr << "T: " << text << std::endl;
3797 }