Mercurial > octave-nkf
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 } |