Mercurial > octave-nkf
diff src/lex.l @ 4238:a5a68c0afe56
[project @ 2002-12-25 21:04:33 by jwe]
author | jwe |
---|---|
date | Wed, 25 Dec 2002 21:04:34 +0000 |
parents | 9c8034434982 |
children | 8627d992beb8 |
line wrap: on
line diff
--- a/src/lex.l Wed Dec 25 03:14:38 2002 +0000 +++ b/src/lex.l Wed Dec 25 21:04:34 2002 +0000 @@ -22,6 +22,7 @@ %s COMMAND_START %s MATRIX_START +%s NESTED_FUNCTION_START %{ #ifdef HAVE_CONFIG_H @@ -193,6 +194,8 @@ static void do_comma_insert_check (void); static int is_plot_keyword (const std::string& s); static int is_keyword (const std::string& s); +static void prep_for_function (void); +static void prep_for_nested_function (void); static std::string plot_style_token (const std::string& s); static symbol_record *lookup_identifier (const std::string& s); static void grab_help_text (void); @@ -238,6 +241,12 @@ NUMBER (({D}+\.?{D}*{EXPON}?)|(\.{D}+{EXPON}?)|(0[xX][0-9a-fA-F]+)) %% +<NESTED_FUNCTION_START>{} { + BEGIN 0; + prep_for_nested_function (); + return FCN; + } + %{ // Help and other command-style functions are a pain in the ass. This // stuff needs to be simplified. May require some changes in the @@ -529,7 +538,10 @@ %} {IDENT}{S}* { - return handle_identifier (); + int id_tok = handle_identifier (); + + if (id_tok >= 0) + return id_tok; } %{ @@ -814,7 +826,10 @@ error_state = 0; warning_state = 0; parser_end_of_input = false; - symtab_context = 0; + end_tokens_expected = 0; + + while (! symtab_context.empty ()) + symtab_context.pop (); // We do want a prompt by default. promptflag = 1; @@ -1046,7 +1061,35 @@ } } -// Handle keywords. +static void +prep_for_function (void) +{ + end_tokens_expected++; + + // Prepare for local symbols. + + tmp_local_sym_tab = new symbol_table (); + + promptflag--; + + lexer_flags.defining_func = true; + lexer_flags.parsed_function_name = false; + lexer_flags.beginning_of_function = true; + + if (! (reading_fcn_file || reading_script_file)) + input_line_number = 1; +} + +static void +prep_for_nested_function (void) +{ + lexer_flags.parsing_nested_function = true; + prep_for_function (); + yylval.tok_val = new token (input_line_number, current_input_column); + token_stack.push (yylval.tok_val); +} + +// Handle keywords. Return -1 if the keyword should be ignored. static int is_keyword (const std::string& s) @@ -1111,40 +1154,65 @@ if (lexer_flags.looking_at_object_index) return 0; else - yylval.tok_val = new token (token::simple_end, l, c); + { + if (reading_fcn_file && end_tokens_expected == 1) + return -1; + else + { + yylval.tok_val = new token (token::simple_end, l, c); + end_tokens_expected--; + } + } break; case end_try_catch_kw: + end_tokens_expected--; yylval.tok_val = new token (token::try_catch_end, l, c); break; case end_unwind_protect_kw: + end_tokens_expected--; yylval.tok_val = new token (token::unwind_protect_end, l, c); break; case endfor_kw: + end_tokens_expected--; yylval.tok_val = new token (token::for_end, l, c); break; case endfunction_kw: - yylval.tok_val = new token (token::function_end, l, c); + { + if (reading_fcn_file && end_tokens_expected == 1) + return -1; + else + { + yylval.tok_val = new token (token::function_end, l, c); + end_tokens_expected--; + } + } break; case endif_kw: + end_tokens_expected--; yylval.tok_val = new token (token::if_end, l, c); break; case endswitch_kw: + end_tokens_expected--; yylval.tok_val = new token (token::switch_end, l, c); break; case endwhile_kw: + end_tokens_expected--; yylval.tok_val = new token (token::while_end, l, c); break; - case do_kw: case for_kw: case while_kw: + end_tokens_expected++; + // Fall through... + + case do_kw: promptflag--; lexer_flags.looping++; break; @@ -1153,6 +1221,7 @@ case try_kw: case switch_kw: case unwind_protect_kw: + end_tokens_expected++; promptflag--; break; @@ -1172,35 +1241,40 @@ break; case function_kw: - if (lexer_flags.defining_func) - { - error ("function keyword invalid within a function body"); - - if ((reading_fcn_file || reading_script_file) - && ! curr_fcn_file_name.empty ()) - error ("defining new function near line %d of file `%s.m'", - input_line_number, curr_fcn_file_name.c_str ()); - else - error ("defining new function near line %d", - input_line_number); - - return LEXICAL_ERROR; - } - else - { - // Prepare for local symbols. - - tmp_local_sym_tab = new symbol_table (); - - promptflag--; - - lexer_flags.defining_func = true; - lexer_flags.parsed_function_name = false; - lexer_flags.beginning_of_function = true; - - if (! (reading_fcn_file || reading_script_file)) - input_line_number = 1; - } + { + if (lexer_flags.defining_func) + { + if (reading_fcn_file) + { + + if (lexer_flags.parsing_nested_function) + { + BEGIN NESTED_FUNCTION_START; + yylval.tok_val = new token (token::function_end, l, c); + } + else + { + prep_for_nested_function (); + return FCN; + } + } + else + { + error ("nested functions not implemented in this context"); + + if ((reading_fcn_file || reading_script_file) + && ! curr_fcn_file_name.empty ()) + error ("near line %d of file `%s.m'", + input_line_number, curr_fcn_file_name.c_str ()); + else + error ("near line %d", input_line_number); + + return LEXICAL_ERROR; + } + } + else + prep_for_function (); + } break; case magic_file_kw: @@ -1248,7 +1322,13 @@ static symbol_record * lookup_identifier (const std::string& name) { - return curr_sym_tab->lookup (name, true); + std::string sym_name = name; + + if (curr_sym_tab == fbi_sym_tab + && lexer_flags.parsing_nested_function) + sym_name = parent_function_name + ":" + sym_name; + + return curr_sym_tab->lookup (sym_name, true); } static bool @@ -2243,7 +2323,8 @@ } // Figure out exactly what kind of token to return when we have seen -// an identifier. Handles keywords. +// an identifier. Handles keywords. Return -1 if the identifier +// should be ignored. static int handle_identifier (void) @@ -2295,7 +2376,9 @@ if (kw_token) { - if (kw_token == STYLE) + if (kw_token < 0) + return kw_token; + else if (kw_token == STYLE) { current_input_column += yyleng; lexer_flags.quote_is_transpose = false; @@ -2536,6 +2619,7 @@ beginning_of_function = false; defining_func = false; parsed_function_name = false; + parsing_nested_function = false; // Not parsing a function return or parameter list. looking_at_return_list = false;