# HG changeset patch # User John W. Eaton # Date 1363061908 14400 # Node ID 04a7953496a7ae1584a7add975c5b296c4dc4a40 # Parent 3389152014cade1b88f8ac8cec5e2660d2477b26 create base class for parser; use reference for curr_lexer * lex.h, lex.ll (octave_base_parser): New base class for parser class. Move most of previous octave_parser class here. Use reference for curr_lexer object instead of pointer. Change all uses. (octave_parser): Derive from octave_base_parser. diff -r 3389152014ca -r 04a7953496a7 libinterp/interpfcn/toplev.cc --- a/libinterp/interpfcn/toplev.cc Mon Mar 11 18:19:10 2013 -0400 +++ b/libinterp/interpfcn/toplev.cc Tue Mar 12 00:18:28 2013 -0400 @@ -620,7 +620,7 @@ command_editor::increment_current_command_number (); } } - else if (curr_parser.curr_lexer->end_of_input) + else if (curr_parser.curr_lexer.end_of_input) break; } } diff -r 3389152014ca -r 04a7953496a7 libinterp/parse-tree/oct-parse.in.yy --- a/libinterp/parse-tree/oct-parse.in.yy Mon Mar 11 18:19:10 2013 -0400 +++ b/libinterp/parse-tree/oct-parse.in.yy Tue Mar 12 00:18:28 2013 -0400 @@ -107,7 +107,7 @@ // Forward declarations for some functions defined at the bottom of // the file. -static void yyerror (octave_parser& curr_parser, const char *s); +static void yyerror (octave_base_parser& curr_parser, const char *s); // Finish building a statement. template @@ -126,7 +126,7 @@ if (! parser_symtab_context.empty ()) \ parser_symtab_context.pop (); \ if ((interactive || forced_interactive) \ - && ! (curr_lexer)->input_from_eval_string ()) \ + && ! curr_lexer.input_from_eval_string ()) \ YYACCEPT; \ else \ YYABORT; \ @@ -134,7 +134,7 @@ while (0) #define curr_lexer curr_parser.curr_lexer -#define scanner curr_lexer->scanner +#define scanner curr_lexer.scanner %} @@ -156,7 +156,7 @@ %define api.pure %PUSH_PULL_DECL% -%parse-param { octave_parser& curr_parser } +%parse-param { octave_base_parser& curr_parser } %lex-param { void *scanner } %union @@ -326,7 +326,7 @@ { $$ = 0; } | END_OF_INPUT { - curr_lexer->end_of_input = true; + curr_lexer.end_of_input = true; $$ = 0; } | simple_list @@ -484,14 +484,14 @@ fcn_handle : '@' FCN_HANDLE { $$ = curr_parser.make_fcn_handle ($2); - curr_lexer->looking_at_function_handle--; + curr_lexer.looking_at_function_handle--; } ; anon_fcn_handle : '@' param_list statement { $$ = curr_parser.make_anon_fcn_handle ($2, $3); - curr_lexer->nesting_level.remove (); + curr_lexer.nesting_level.remove (); } ; @@ -503,7 +503,7 @@ { $$ = $1; } | matrix { - curr_lexer->looking_at_matrix_or_assign_lhs = false; + curr_lexer.looking_at_matrix_or_assign_lhs = false; $$ = $1; } | cell @@ -553,7 +553,7 @@ ; indirect_ref_op : '.' - { curr_lexer->looking_at_indirect_ref = true; } + { curr_lexer.looking_at_indirect_ref = true; } ; oper_expr : primary_expr @@ -660,7 +660,7 @@ $$ = curr_parser.validate_matrix_for_assignment ($1); if ($$) - { curr_lexer->looking_at_matrix_or_assign_lhs = false; } + { curr_lexer.looking_at_matrix_or_assign_lhs = false; } else { // validate_matrix_for_assignment deleted $1. @@ -751,12 +751,12 @@ declaration : GLOBAL decl1 { $$ = curr_parser.make_decl_command (GLOBAL, $1, $2); - curr_lexer->looking_at_decl_list = false; + curr_lexer.looking_at_decl_list = false; } | PERSISTENT decl1 { $$ = curr_parser.make_decl_command (PERSISTENT, $1, $2); - curr_lexer->looking_at_decl_list = false; + curr_lexer.looking_at_decl_list = false; } ; @@ -770,13 +770,13 @@ ; decl_param_init : // empty - { curr_lexer->looking_at_initializer_expression = true; } + { curr_lexer.looking_at_initializer_expression = true; } decl2 : identifier { $$ = new tree_decl_elt ($1); } | identifier '=' decl_param_init expression { - curr_lexer->looking_at_initializer_expression = false; + curr_lexer.looking_at_initializer_expression = false; $$ = new tree_decl_elt ($1, $4); } | magic_tilde @@ -817,7 +817,7 @@ if_cmd_list1 : expression opt_sep opt_list { - $1->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); + $1->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name); $$ = curr_parser.start_if_command ($1, $3); } @@ -830,7 +830,7 @@ elseif_clause : ELSEIF stash_comment opt_sep expression opt_sep opt_list { - $4->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); + $4->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name); $$ = curr_parser.make_elseif_clause ($1, $4, $6, $2); } @@ -889,7 +889,7 @@ loop_command : WHILE stash_comment expression opt_sep opt_list END { - $3->mark_braindead_shortcircuit (curr_lexer->fcn_file_full_name); + $3->mark_braindead_shortcircuit (curr_lexer.fcn_file_full_name); if (! ($$ = curr_parser.make_while_command ($1, $3, $5, $6, $2))) ABORT_PARSE; @@ -986,12 +986,12 @@ curr_parser.function_scopes.push_back (symbol_table::current_scope ()); - if (! curr_lexer->reading_script_file + if (! curr_lexer.reading_script_file && curr_parser.curr_fcn_depth == 1 && ! curr_parser.parsing_subfunctions) curr_parser.primary_fcn_scope = symbol_table::current_scope (); - if (curr_lexer->reading_script_file + if (curr_lexer.reading_script_file && curr_parser.curr_fcn_depth > 1) curr_parser.bison_error ("nested functions not implemented in this context"); } @@ -1003,22 +1003,22 @@ param_list_beg : '(' { - curr_lexer->looking_at_parameter_list = true; - - if (curr_lexer->looking_at_function_handle) + curr_lexer.looking_at_parameter_list = true; + + if (curr_lexer.looking_at_function_handle) { parser_symtab_context.push (); symbol_table::set_scope (symbol_table::alloc_scope ()); - curr_lexer->looking_at_function_handle--; - curr_lexer->looking_at_anon_fcn_args = true; + curr_lexer.looking_at_function_handle--; + curr_lexer.looking_at_anon_fcn_args = true; } } ; param_list_end : ')' { - curr_lexer->looking_at_parameter_list = false; - curr_lexer->looking_for_object_index = false; + curr_lexer.looking_at_parameter_list = false; + curr_lexer.looking_for_object_index = false; } ; @@ -1059,12 +1059,12 @@ return_list : '[' ']' { - curr_lexer->looking_at_return_list = false; + curr_lexer.looking_at_return_list = false; $$ = new tree_parameter_list (); } | return_list1 { - curr_lexer->looking_at_return_list = false; + curr_lexer.looking_at_return_list = false; if ($1->validate (tree_parameter_list::out)) $$ = $1; else @@ -1072,7 +1072,7 @@ } | '[' return_list1 ']' { - curr_lexer->looking_at_return_list = false; + curr_lexer.looking_at_return_list = false; if ($2->validate (tree_parameter_list::out)) $$ = $2; else @@ -1095,12 +1095,12 @@ file : INPUT_FILE opt_nl opt_list END_OF_INPUT { - if (! curr_lexer->reading_fcn_file) + if (! curr_lexer.reading_fcn_file) { tree_statement *end_of_script = curr_parser.make_end ("endscript", - curr_lexer->input_line_number, - curr_lexer->current_input_column); + curr_lexer.input_line_number, + curr_lexer.current_input_column); curr_parser.make_script ($3, end_of_script); } @@ -1116,9 +1116,9 @@ function_beg : push_fcn_symtab FCN stash_comment { $$ = $3; - if (curr_lexer->reading_classdef_file - || curr_lexer->parsing_classdef) - curr_lexer->maybe_classdef_get_set_method = true; + if (curr_lexer.reading_classdef_file + || curr_lexer.parsing_classdef) + curr_lexer.maybe_classdef_get_set_method = true; } ; @@ -1138,21 +1138,21 @@ { std::string id_name = $1->name (); - curr_lexer->parsed_function_name.top () = true; - curr_lexer->maybe_classdef_get_set_method = false; + curr_lexer.parsed_function_name.top () = true; + curr_lexer.maybe_classdef_get_set_method = false; $$ = $1; } | GET '.' identifier { - curr_lexer->parsed_function_name.top () = true; - curr_lexer->maybe_classdef_get_set_method = false; + curr_lexer.parsed_function_name.top () = true; + curr_lexer.maybe_classdef_get_set_method = false; $$ = $3; } | SET '.' identifier { - curr_lexer->parsed_function_name.top () = true; - curr_lexer->maybe_classdef_get_set_method = false; + curr_lexer.parsed_function_name.top () = true; + curr_lexer.maybe_classdef_get_set_method = false; $$ = $3; } ; @@ -1185,7 +1185,7 @@ | END_OF_INPUT { // A lot of tests are based on the assumption that this is OK -// if (curr_lexer->reading_script_file) +// if (curr_lexer.reading_script_file) // { // curr_parser.bison_error ("function body open at end of script"); // YYABORT; @@ -1199,22 +1199,22 @@ YYABORT; } - if (! (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file - || (curr_lexer)->input_from_eval_string ())) + if (! (curr_lexer.reading_fcn_file || curr_lexer.reading_script_file + || curr_lexer.input_from_eval_string ())) { curr_parser.bison_error ("function body open at end of input"); YYABORT; } - if (curr_lexer->reading_classdef_file) + if (curr_lexer.reading_classdef_file) { curr_parser.bison_error ("classdef body open at end of input"); YYABORT; } $$ = curr_parser.make_end ("endfunction", - curr_lexer->input_line_number, - curr_lexer->current_input_column); + curr_lexer.input_line_number, + curr_lexer.current_input_column); } ; @@ -1225,13 +1225,13 @@ classdef_beg : CLASSDEF stash_comment { $$ = 0; - curr_lexer->parsing_classdef = true; + curr_lexer.parsing_classdef = true; } ; classdef_end : END { - curr_lexer->parsing_classdef = false; + curr_lexer.parsing_classdef = false; if (curr_parser.end_token_ok ($1, token::classdef_end)) $$ = curr_parser.make_end ("endclassdef", $1->line (), $1->column ()); @@ -1443,12 +1443,12 @@ #undef curr_lexer static void -yyerror (octave_parser& curr_parser, const char *s) +yyerror (octave_base_parser& curr_parser, const char *s) { curr_parser.bison_error (s); } -octave_parser::~octave_parser (void) +octave_base_parser::~octave_base_parser (void) { #if defined (OCTAVE_USE_PUSH_PARSER) yypstate_delete (static_cast (parser_state)); @@ -1456,60 +1456,33 @@ delete stmt_list; - delete curr_lexer; + delete &curr_lexer; } -void octave_parser::init (void) + +void octave_base_parser::init (void) { #if defined (OCTAVE_USE_PUSH_PARSER) parser_state = yypstate_new (); #endif - CURR_LEXER = curr_lexer; + CURR_LEXER = &curr_lexer; } void -octave_parser::reset (void) +octave_base_parser::reset (void) { delete stmt_list; stmt_list = 0; - curr_lexer->reset (); -} - -int -octave_parser::run (void) -{ - int status = 0; - -#if defined (OCTAVE_USE_PUSH_PARSER) - - do - { - YYSTYPE lval; - - int token = octave_lex (&lval, scanner); - - yypstate *pstate = static_cast (parser_state); - - status = octave_push_parse (pstate, token, &lval, *this); - } - while (status == YYPUSH_MORE); - -#else - - status = octave_parse (*this); - -#endif - - return status; + curr_lexer.reset (); } // Error mesages for mismatched end tokens. void -octave_parser::end_error (const char *type, token::end_tok_type ettype, - int l, int c) +octave_base_parser::end_error (const char *type, token::end_tok_type ettype, + int l, int c) { static const char *fmt = "'%s' command matched by '%s' near line %d column %d"; @@ -1561,7 +1534,7 @@ // Check to see that end tokens are properly matched. bool -octave_parser::end_token_ok (token *tok, token::end_tok_type expected) +octave_base_parser::end_token_ok (token *tok, token::end_tok_type expected) { bool retval = true; @@ -1631,12 +1604,12 @@ // test in a logical expression. void -octave_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) +octave_base_parser::maybe_warn_assign_as_truth_value (tree_expression *expr) { if (expr->is_assignment_expression () && expr->paren_count () < 2) { - if (curr_lexer->fcn_file_full_name.empty ()) + if (curr_lexer.fcn_file_full_name.empty ()) warning_with_id ("Octave:assign-as-truth-value", "suggest parenthesis around assignment used as truth value"); @@ -1644,25 +1617,25 @@ warning_with_id ("Octave:assign-as-truth-value", "suggest parenthesis around assignment used as truth value near line %d, column %d in file '%s'", - expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); + expr->line (), expr->column (), curr_lexer.fcn_file_full_name.c_str ()); } } // Maybe print a warning about switch labels that aren't constants. void -octave_parser::maybe_warn_variable_switch_label (tree_expression *expr) +octave_base_parser::maybe_warn_variable_switch_label (tree_expression *expr) { if (! expr->is_constant ()) { - if (curr_lexer->fcn_file_full_name.empty ()) + if (curr_lexer.fcn_file_full_name.empty ()) warning_with_id ("Octave:variable-switch-label", "variable switch label"); else warning_with_id ("Octave:variable-switch-label", "variable switch label near line %d, column %d in file '%s'", - expr->line (), expr->column (), curr_lexer->fcn_file_full_name.c_str ()); + expr->line (), expr->column (), curr_lexer.fcn_file_full_name.c_str ()); } } @@ -1758,7 +1731,7 @@ // Finish building a range. tree_expression * -octave_parser::finish_colon_expression (tree_colon_expression *e) +octave_base_parser::finish_colon_expression (tree_colon_expression *e) { tree_expression *retval = e; @@ -1822,7 +1795,7 @@ // Make a constant. tree_constant * -octave_parser::make_constant (int op, token *tok_val) +octave_base_parser::make_constant (int op, token *tok_val) { int l = tok_val->line (); int c = tok_val->column (); @@ -1885,7 +1858,7 @@ // Make a function handle. tree_fcn_handle * -octave_parser::make_fcn_handle (token *tok_val) +octave_base_parser::make_fcn_handle (token *tok_val) { int l = tok_val->line (); int c = tok_val->column (); @@ -1898,12 +1871,12 @@ // Make an anonymous function handle. tree_anon_fcn_handle * -octave_parser::make_anon_fcn_handle (tree_parameter_list *param_list, - tree_statement *stmt) +octave_base_parser::make_anon_fcn_handle (tree_parameter_list *param_list, + tree_statement *stmt) { // FIXME -- need to get these from the location of the @ symbol. - int l = curr_lexer->input_line_number; - int c = curr_lexer->current_input_column; + int l = curr_lexer.input_line_number; + int c = curr_lexer.current_input_column; tree_parameter_list *ret_list = 0; @@ -1924,7 +1897,7 @@ = new tree_anon_fcn_handle (param_list, ret_list, body, fcn_scope, l, c); // FIXME: Stash the filename. This does not work and produces // errors when executed. - //retval->stash_file_name (curr_lexer->fcn_file_name); + //retval->stash_file_name (curr_lexer.fcn_file_name); return retval; } @@ -1932,8 +1905,8 @@ // Build a binary expression. tree_expression * -octave_parser::make_binary_op (int op, tree_expression *op1, token *tok_val, - tree_expression *op2) +octave_base_parser::make_binary_op (int op, tree_expression *op1, + token *tok_val, tree_expression *op2) { octave_value::binary_op t = octave_value::unknown_binary_op; @@ -2036,8 +2009,8 @@ // Build a boolean expression. tree_expression * -octave_parser::make_boolean_op (int op, tree_expression *op1, token *tok_val, - tree_expression *op2) +octave_base_parser::make_boolean_op (int op, tree_expression *op1, + token *tok_val, tree_expression *op2) { tree_boolean_expression::type t; @@ -2068,7 +2041,8 @@ // Build a prefix expression. tree_expression * -octave_parser::make_prefix_op (int op, tree_expression *op1, token *tok_val) +octave_base_parser::make_prefix_op (int op, tree_expression *op1, + token *tok_val) { octave_value::unary_op t = octave_value::unknown_unary_op; @@ -2111,7 +2085,8 @@ // Build a postfix expression. tree_expression * -octave_parser::make_postfix_op (int op, tree_expression *op1, token *tok_val) +octave_base_parser::make_postfix_op (int op, tree_expression *op1, + token *tok_val) { octave_value::unary_op t = octave_value::unknown_unary_op; @@ -2150,12 +2125,12 @@ // Build an unwind-protect command. tree_command * -octave_parser::make_unwind_command (token *unwind_tok, - tree_statement_list *body, - tree_statement_list *cleanup_stmts, - token *end_tok, - octave_comment_list *lc, - octave_comment_list *mc) +octave_base_parser::make_unwind_command (token *unwind_tok, + tree_statement_list *body, + tree_statement_list *cleanup_stmts, + token *end_tok, + octave_comment_list *lc, + octave_comment_list *mc) { tree_command *retval = 0; @@ -2176,11 +2151,12 @@ // Build a try-catch command. tree_command * -octave_parser::make_try_command (token *try_tok, tree_statement_list *body, - tree_statement_list *cleanup_stmts, - token *end_tok, - octave_comment_list *lc, - octave_comment_list *mc) +octave_base_parser::make_try_command (token *try_tok, + tree_statement_list *body, + tree_statement_list *cleanup_stmts, + token *end_tok, + octave_comment_list *lc, + octave_comment_list *mc) { tree_command *retval = 0; @@ -2201,9 +2177,11 @@ // Build a while command. tree_command * -octave_parser::make_while_command (token *while_tok, tree_expression *expr, - tree_statement_list *body, token *end_tok, - octave_comment_list *lc) +octave_base_parser::make_while_command (token *while_tok, + tree_expression *expr, + tree_statement_list *body, + token *end_tok, + octave_comment_list *lc) { tree_command *retval = 0; @@ -2213,7 +2191,7 @@ { octave_comment_list *tc = octave_comment_buffer::get_comment (); - curr_lexer->looping--; + curr_lexer.looping--; int l = while_tok->line (); int c = while_tok->column (); @@ -2227,10 +2205,10 @@ // Build a do-until command. tree_command * -octave_parser::make_do_until_command (token *until_tok, - tree_statement_list *body, - tree_expression *expr, - octave_comment_list *lc) +octave_base_parser::make_do_until_command (token *until_tok, + tree_statement_list *body, + tree_expression *expr, + octave_comment_list *lc) { tree_command *retval = 0; @@ -2238,7 +2216,7 @@ octave_comment_list *tc = octave_comment_buffer::get_comment (); - curr_lexer->looping--; + curr_lexer.looping--; int l = until_tok->line (); int c = until_tok->column (); @@ -2251,12 +2229,13 @@ // Build a for command. tree_command * -octave_parser::make_for_command (int tok_id, token *for_tok, - tree_argument_list *lhs, - tree_expression *expr, - tree_expression *maxproc, - tree_statement_list *body, token *end_tok, - octave_comment_list *lc) +octave_base_parser::make_for_command (int tok_id, token *for_tok, + tree_argument_list *lhs, + tree_expression *expr, + tree_expression *maxproc, + tree_statement_list *body, + token *end_tok, + octave_comment_list *lc) { tree_command *retval = 0; @@ -2266,7 +2245,7 @@ { octave_comment_list *tc = octave_comment_buffer::get_comment (); - curr_lexer->looping--; + curr_lexer.looping--; int l = for_tok->line (); int c = for_tok->column (); @@ -2296,7 +2275,7 @@ // Build a break command. tree_command * -octave_parser::make_break_command (token *break_tok) +octave_base_parser::make_break_command (token *break_tok) { tree_command *retval = 0; @@ -2311,7 +2290,7 @@ // Build a continue command. tree_command * -octave_parser::make_continue_command (token *continue_tok) +octave_base_parser::make_continue_command (token *continue_tok) { tree_command *retval = 0; @@ -2326,7 +2305,7 @@ // Build a return command. tree_command * -octave_parser::make_return_command (token *return_tok) +octave_base_parser::make_return_command (token *return_tok) { tree_command *retval = 0; @@ -2341,8 +2320,8 @@ // Start an if command. tree_if_command_list * -octave_parser::start_if_command (tree_expression *expr, - tree_statement_list *list) +octave_base_parser::start_if_command (tree_expression *expr, + tree_statement_list *list) { maybe_warn_assign_as_truth_value (expr); @@ -2354,8 +2333,10 @@ // Finish an if command. tree_if_command * -octave_parser::finish_if_command (token *if_tok, tree_if_command_list *list, - token *end_tok, octave_comment_list *lc) +octave_base_parser::finish_if_command (token *if_tok, + tree_if_command_list *list, + token *end_tok, + octave_comment_list *lc) { tree_if_command *retval = 0; @@ -2386,9 +2367,10 @@ // Build an elseif clause. tree_if_clause * -octave_parser::make_elseif_clause (token *elseif_tok, tree_expression *expr, - tree_statement_list *list, - octave_comment_list *lc) +octave_base_parser::make_elseif_clause (token *elseif_tok, + tree_expression *expr, + tree_statement_list *list, + octave_comment_list *lc) { maybe_warn_assign_as_truth_value (expr); @@ -2401,9 +2383,11 @@ // Finish a switch command. tree_switch_command * -octave_parser::finish_switch_command (token *switch_tok, tree_expression *expr, - tree_switch_case_list *list, - token *end_tok, octave_comment_list *lc) +octave_base_parser::finish_switch_command (token *switch_tok, + tree_expression *expr, + tree_switch_case_list *list, + token *end_tok, + octave_comment_list *lc) { tree_switch_command *retval = 0; @@ -2434,9 +2418,10 @@ // Build a switch case. tree_switch_case * -octave_parser::make_switch_case (token *case_tok, tree_expression *expr, - tree_statement_list *list, - octave_comment_list *lc) +octave_base_parser::make_switch_case (token *case_tok, + tree_expression *expr, + tree_statement_list *list, + octave_comment_list *lc) { maybe_warn_variable_switch_label (expr); @@ -2449,8 +2434,8 @@ // Build an assignment to a variable. tree_expression * -octave_parser::make_assign_op (int op, tree_argument_list *lhs, token *eq_tok, - tree_expression *rhs) +octave_base_parser::make_assign_op (int op, tree_argument_list *lhs, + token *eq_tok, tree_expression *rhs) { tree_expression *retval = 0; @@ -2545,8 +2530,8 @@ // Define a script. void -octave_parser::make_script (tree_statement_list *cmds, - tree_statement *end_script) +octave_base_parser::make_script (tree_statement_list *cmds, + tree_statement *end_script) { if (! cmds) cmds = new tree_statement_list (); @@ -2554,11 +2539,11 @@ cmds->append (end_script); octave_user_script *script - = new octave_user_script (curr_lexer->fcn_file_full_name, - curr_lexer->fcn_file_name, - cmds, curr_lexer->help_text); - - curr_lexer->help_text = ""; + = new octave_user_script (curr_lexer.fcn_file_full_name, + curr_lexer.fcn_file_name, + cmds, curr_lexer.help_text); + + curr_lexer.help_text = ""; octave_time now; @@ -2570,9 +2555,9 @@ // Begin defining a function. octave_user_function * -octave_parser::start_function (tree_parameter_list *param_list, - tree_statement_list *body, - tree_statement *end_fcn_stmt) +octave_base_parser::start_function (tree_parameter_list *param_list, + tree_statement_list *body, + tree_statement *end_fcn_stmt) { // We'll fill in the return list later. @@ -2596,7 +2581,7 @@ } tree_statement * -octave_parser::make_end (const std::string& type, int l, int c) +octave_base_parser::make_end (const std::string& type, int l, int c) { return make_statement (new tree_no_op_command (type, l, c)); } @@ -2604,8 +2589,8 @@ // Do most of the work for defining a function. octave_user_function * -octave_parser::frob_function (const std::string& fname, - octave_user_function *fcn) +octave_base_parser::frob_function (const std::string& fname, + octave_user_function *fcn) { std::string id_name = fname; @@ -2613,36 +2598,36 @@ // the file does not match the name of the function stated in the // file. Matlab doesn't provide a diagnostic (it ignores the stated // name). - if (! autoloading && curr_lexer->reading_fcn_file + if (! autoloading && curr_lexer.reading_fcn_file && curr_fcn_depth == 1 && ! parsing_subfunctions) { - // FIXME -- should curr_lexer->fcn_file_name already be + // FIXME -- should curr_lexer.fcn_file_name already be // preprocessed when we get here? It seems to only be a // problem with relative file names. - std::string nm = curr_lexer->fcn_file_name; + std::string nm = curr_lexer.fcn_file_name; size_t pos = nm.find_last_of (file_ops::dir_sep_chars ()); if (pos != std::string::npos) - nm = curr_lexer->fcn_file_name.substr (pos+1); + nm = curr_lexer.fcn_file_name.substr (pos+1); if (nm != id_name) { warning_with_id ("Octave:function-name-clash", "function name '%s' does not agree with function file name '%s'", - id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); + id_name.c_str (), curr_lexer.fcn_file_full_name.c_str ()); id_name = nm; } } - if (curr_lexer->reading_fcn_file || curr_lexer->reading_classdef_file || autoloading) + if (curr_lexer.reading_fcn_file || curr_lexer.reading_classdef_file || autoloading) { octave_time now; - fcn->stash_fcn_file_name (curr_lexer->fcn_file_full_name); + fcn->stash_fcn_file_name (curr_lexer.fcn_file_full_name); fcn->stash_fcn_file_time (now); fcn->mark_as_system_fcn_file (); @@ -2651,7 +2636,7 @@ if (curr_fcn_depth > 1 || parsing_subfunctions) { - fcn->stash_parent_fcn_name (curr_lexer->fcn_file_name); + fcn->stash_parent_fcn_name (curr_lexer.fcn_file_name); if (curr_fcn_depth > 1) fcn->stash_parent_fcn_scope (function_scopes[function_scopes.size ()-2]); @@ -2659,7 +2644,7 @@ fcn->stash_parent_fcn_scope (primary_fcn_scope); } - if (curr_lexer->parsing_class_method) + if (curr_lexer.parsing_class_method) { if (curr_class_name == id_name) fcn->mark_as_class_constructor (); @@ -2678,27 +2663,27 @@ "time stamp for '%s' is in the future", nm.c_str ()); } else if (! input_from_tmp_history_file - && ! curr_lexer->force_script - && curr_lexer->reading_script_file - && curr_lexer->fcn_file_name == id_name) + && ! curr_lexer.force_script + && curr_lexer.reading_script_file + && curr_lexer.fcn_file_name == id_name) { warning ("function '%s' defined within script file '%s'", - id_name.c_str (), curr_lexer->fcn_file_full_name.c_str ()); + id_name.c_str (), curr_lexer.fcn_file_full_name.c_str ()); } fcn->stash_function_name (id_name); - fcn->stash_fcn_location (curr_lexer->input_line_number, - curr_lexer->current_input_column); - - if (! curr_lexer->help_text.empty () && curr_fcn_depth == 1 + fcn->stash_fcn_location (curr_lexer.input_line_number, + curr_lexer.current_input_column); + + if (! curr_lexer.help_text.empty () && curr_fcn_depth == 1 && ! parsing_subfunctions) { - fcn->document (curr_lexer->help_text); - - curr_lexer->help_text = ""; + fcn->document (curr_lexer.help_text); + + curr_lexer.help_text = ""; } - if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 + if (curr_lexer.reading_fcn_file && curr_fcn_depth == 1 && ! parsing_subfunctions) primary_fcn_ptr = fcn; @@ -2706,9 +2691,9 @@ } tree_function_def * -octave_parser::finish_function (tree_parameter_list *ret_list, - octave_user_function *fcn, - octave_comment_list *lc) +octave_base_parser::finish_function (tree_parameter_list *ret_list, + octave_user_function *fcn, + octave_comment_list *lc) { tree_function_def *retval = 0; @@ -2751,7 +2736,7 @@ if (curr_fcn_depth == 1 && fcn) symbol_table::update_nest (fcn->scope ()); - if (! curr_lexer->reading_fcn_file && curr_fcn_depth == 1) + if (! curr_lexer.reading_fcn_file && curr_fcn_depth == 1) { // We are either reading a script file or defining a function // at the command line, so this definition creates a @@ -2771,31 +2756,32 @@ } void -octave_parser::recover_from_parsing_function (void) +octave_base_parser::recover_from_parsing_function (void) { if (parser_symtab_context.empty ()) panic_impossible (); parser_symtab_context.pop (); - if (curr_lexer->reading_fcn_file && curr_fcn_depth == 1 + if (curr_lexer.reading_fcn_file && curr_fcn_depth == 1 && ! parsing_subfunctions) parsing_subfunctions = true; curr_fcn_depth--; function_scopes.pop_back (); - curr_lexer->defining_func--; - curr_lexer->parsed_function_name.pop (); - curr_lexer->looking_at_return_list = false; - curr_lexer->looking_at_parameter_list = false; + curr_lexer.defining_func--; + curr_lexer.parsed_function_name.pop (); + curr_lexer.looking_at_return_list = false; + curr_lexer.looking_at_parameter_list = false; } // Make an index expression. tree_index_expression * -octave_parser::make_index_expression (tree_expression *expr, - tree_argument_list *args, char type) +octave_base_parser::make_index_expression (tree_expression *expr, + tree_argument_list *args, + char type) { tree_index_expression *retval = 0; @@ -2827,8 +2813,8 @@ // Make an indirect reference expression. tree_index_expression * -octave_parser::make_indirect_ref (tree_expression *expr, - const std::string& elt) +octave_base_parser::make_indirect_ref (tree_expression *expr, + const std::string& elt) { tree_index_expression *retval = 0; @@ -2846,7 +2832,7 @@ else retval = new tree_index_expression (expr, elt, l, c); - curr_lexer->looking_at_indirect_ref = false; + curr_lexer.looking_at_indirect_ref = false; return retval; } @@ -2854,7 +2840,7 @@ // Make an indirect reference expression with dynamic field name. tree_index_expression * -octave_parser::make_indirect_ref (tree_expression *expr, tree_expression *elt) +octave_base_parser::make_indirect_ref (tree_expression *expr, tree_expression *elt) { tree_index_expression *retval = 0; @@ -2872,7 +2858,7 @@ else retval = new tree_index_expression (expr, elt, l, c); - curr_lexer->looking_at_indirect_ref = false; + curr_lexer.looking_at_indirect_ref = false; return retval; } @@ -2880,8 +2866,8 @@ // Make a declaration command. tree_decl_command * -octave_parser::make_decl_command (int tok, token *tok_val, - tree_decl_init_list *lst) +octave_base_parser::make_decl_command (int tok, token *tok_val, + tree_decl_init_list *lst) { tree_decl_command *retval = 0; @@ -2899,9 +2885,9 @@ retval = new tree_persistent_command (lst, l, c); else { - if (curr_lexer->reading_script_file) + if (curr_lexer.reading_script_file) warning ("ignoring persistent declaration near line %d of file '%s'", - l, curr_lexer->fcn_file_full_name.c_str ()); + l, curr_lexer.fcn_file_full_name.c_str ()); else warning ("ignoring persistent declaration near line %d", l); } @@ -2916,7 +2902,7 @@ } bool -octave_parser::validate_array_list (tree_expression *e) +octave_base_parser::validate_array_list (tree_expression *e) { bool retval = true; @@ -2941,7 +2927,7 @@ } tree_argument_list * -octave_parser::validate_matrix_for_assignment (tree_expression *e) +octave_base_parser::validate_matrix_for_assignment (tree_expression *e) { tree_argument_list *retval = 0; @@ -2995,7 +2981,7 @@ // Finish building an array_list. tree_expression * -octave_parser::finish_array_list (tree_array_list *array_list) +octave_base_parser::finish_array_list (tree_array_list *array_list) { tree_expression *retval = array_list; @@ -3040,7 +3026,7 @@ // Finish building a matrix list. tree_expression * -octave_parser::finish_matrix (tree_matrix *m) +octave_base_parser::finish_matrix (tree_matrix *m) { return finish_array_list (m); } @@ -3048,13 +3034,13 @@ // Finish building a cell list. tree_expression * -octave_parser::finish_cell (tree_cell *c) +octave_base_parser::finish_cell (tree_cell *c) { return finish_array_list (c); } void -octave_parser::maybe_warn_missing_semi (tree_statement_list *t) +octave_base_parser::maybe_warn_missing_semi (tree_statement_list *t) { if (curr_fcn_depth > 0) { @@ -3064,13 +3050,13 @@ warning_with_id ("Octave:missing-semicolon", "missing semicolon near line %d, column %d in file '%s'", - tmp->line (), tmp->column (), curr_lexer->fcn_file_full_name.c_str ()); + tmp->line (), tmp->column (), curr_lexer.fcn_file_full_name.c_str ()); } } tree_statement_list * -octave_parser::set_stmt_print_flag (tree_statement_list *list, char sep, - bool warn_missing_semi) +octave_base_parser::set_stmt_print_flag (tree_statement_list *list, + char sep, bool warn_missing_semi) { tree_statement *tmp = list->back (); @@ -3106,15 +3092,15 @@ } tree_statement_list * -octave_parser::make_statement_list (tree_statement *stmt) +octave_base_parser::make_statement_list (tree_statement *stmt) { return new tree_statement_list (stmt); } tree_statement_list * -octave_parser::append_statement_list (tree_statement_list *list, char sep, - tree_statement *stmt, - bool warn_missing_semi) +octave_base_parser::append_statement_list (tree_statement_list *list, + char sep, tree_statement *stmt, + bool warn_missing_semi) { set_stmt_print_flag (list, sep, warn_missing_semi); @@ -3124,15 +3110,15 @@ } void -octave_parser::bison_error (const char *s) +octave_base_parser::bison_error (const char *s) { - int err_col = curr_lexer->current_input_column - 1; + int err_col = curr_lexer.current_input_column - 1; std::ostringstream output_buf; - if (curr_lexer->reading_fcn_file || curr_lexer->reading_script_file || curr_lexer->reading_classdef_file) - output_buf << "parse error near line " << curr_lexer->input_line_number - << " of file " << curr_lexer->fcn_file_full_name; + if (curr_lexer.reading_fcn_file || curr_lexer.reading_script_file || curr_lexer.reading_classdef_file) + output_buf << "parse error near line " << curr_lexer.input_line_number + << " of file " << curr_lexer.fcn_file_full_name; else output_buf << "parse error:"; @@ -3141,7 +3127,7 @@ output_buf << "\n\n"; - std::string curr_line = curr_lexer->current_input_line; + std::string curr_line = curr_lexer.current_input_line; if (! curr_line.empty ()) { @@ -3170,6 +3156,12 @@ parse_error ("%s", msg.c_str ()); } +int +octave_parser::run (void) +{ + return octave_parse (*this); +} + static void safe_fclose (FILE *f) { @@ -3216,7 +3208,7 @@ if (ffile) { - // octave_parser constructor sets this for us. + // octave_base_parser constructor sets this for us. frame.protect_var (CURR_LEXER); octave_parser curr_parser (ffile); @@ -3225,12 +3217,12 @@ curr_parser.autoloading = autoload; curr_parser.fcn_file_from_relative_lookup = relative_lookup; - curr_parser.curr_lexer->force_script = force_script; - curr_parser.curr_lexer->prep_for_file (); - curr_parser.curr_lexer->parsing_class_method = ! dispatch_type.empty (); - - curr_parser.curr_lexer->fcn_file_name = file; - curr_parser.curr_lexer->fcn_file_full_name = full_file; + curr_parser.curr_lexer.force_script = force_script; + curr_parser.curr_lexer.prep_for_file (); + curr_parser.curr_lexer.parsing_class_method = ! dispatch_type.empty (); + + curr_parser.curr_lexer.fcn_file_name = file; + curr_parser.curr_lexer.fcn_file_full_name = full_file; int status = curr_parser.run (); @@ -3912,7 +3904,7 @@ unwind_protect frame; - // octave_parser constructor sets this for us. + // octave_base_parser constructor sets this for us. frame.protect_var (CURR_LEXER); octave_parser curr_parser (eval_str); @@ -3972,7 +3964,7 @@ || tree_continue_command::continuing) break; } - else if (curr_parser.curr_lexer->end_of_input) + else if (curr_parser.curr_lexer.end_of_input) break; } } diff -r 3389152014ca -r 04a7953496a7 libinterp/parse-tree/parse.h --- a/libinterp/parse-tree/parse.h Mon Mar 11 18:19:10 2013 -0400 +++ b/libinterp/parse-tree/parse.h Tue Mar 12 00:18:28 2013 -0400 @@ -126,54 +126,28 @@ extern octave_lexer *CURR_LEXER; class -octave_parser +octave_base_parser { public: - octave_parser (void) - : endfunction_found (false), - autoloading (false), fcn_file_from_relative_lookup (false), - parsing_subfunctions (false), max_fcn_depth (0), - curr_fcn_depth (0), primary_fcn_scope (-1), - curr_class_name (), function_scopes (), primary_fcn_ptr (0), - stmt_list (0), - curr_lexer (new octave_lexer ()), parser_state (0) - { - init (); - } - - octave_parser (FILE *file) + octave_base_parser (octave_lexer& lxr) : endfunction_found (false), autoloading (false), fcn_file_from_relative_lookup (false), parsing_subfunctions (false), max_fcn_depth (0), curr_fcn_depth (0), primary_fcn_scope (-1), curr_class_name (), function_scopes (), primary_fcn_ptr (0), stmt_list (0), - curr_lexer (new octave_lexer (file)), parser_state (0) + curr_lexer (lxr), parser_state (0) { init (); } - octave_parser (const std::string& eval_string) - : endfunction_found (false), - autoloading (false), fcn_file_from_relative_lookup (false), - parsing_subfunctions (false), max_fcn_depth (0), - curr_fcn_depth (0), primary_fcn_scope (-1), - curr_class_name (), function_scopes (), primary_fcn_ptr (0), - stmt_list (0), - curr_lexer (new octave_lexer (eval_string)), parser_state (0) - { - init (); - } - - ~octave_parser (void); + virtual ~octave_base_parser (void); void init (void); void reset (void); - int run (void); - // Error mesages for mismatched end tokens. void end_error (const char *type, token::end_tok_type ettype, int l, int c); @@ -407,14 +381,41 @@ tree_statement_list *stmt_list; // State of the lexer. - octave_lexer *curr_lexer; + octave_lexer& curr_lexer; // Internal state of the parser. Only used if USE_PUSH_PARSER is // defined. void *parser_state; - // For unwind protect. - static void cleanup (octave_parser *parser) { delete parser; } +private: + + // No copying! + + octave_base_parser (const octave_base_parser&); + + octave_base_parser& operator = (const octave_base_parser&); +}; + +class +octave_parser : public octave_base_parser +{ +public: + + octave_parser (void) + : octave_base_parser (*(new octave_lexer ())) + { } + + octave_parser (FILE *file) + : octave_base_parser (*(new octave_lexer (file))) + { } + + octave_parser (const std::string& eval_string) + : octave_base_parser (*(new octave_lexer (eval_string))) + { } + + ~octave_parser (void) { } + + int run (void); private: