From 9e454debb5eb7cbabcf29e844e16f2463d8d7eb6 Mon Sep 17 00:00:00 2001 From: Houtan Bastani <houtan@dynare.org> Date: Tue, 8 Oct 2019 16:06:01 +0200 Subject: [PATCH] support external functions in MATLAB namespace. closes dynare#1639 --- src/DynareBison.yy | 26 ++++++++++++++++++-------- src/DynareFlex.ll | 2 +- src/ParsingDriver.cc | 6 ++++++ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/DynareBison.yy b/src/DynareBison.yy index 5453d10a..8839deeb 100644 --- a/src/DynareBison.yy +++ b/src/DynareBison.yy @@ -174,7 +174,8 @@ class ParsingDriver; %type <expr_t> expression expression_or_empty %type <expr_t> equation hand_side %type <string> non_negative_number signed_number signed_integer date_str -%type <string> filename symbol vec_of_vec_value vec_value_list date_expr number +%type <string> filename symbol namespace_qualified_filename namespace_qualified_symbol +%type <string> vec_of_vec_value vec_value_list date_expr number %type <string> vec_value_1 vec_value signed_inf signed_number_w_inf %type <string> range vec_value_w_inf vec_value_1_w_inf %type <string> integer_range signed_integer_range @@ -747,7 +748,7 @@ init_param : symbol EQUAL expression ';' { driver.init_param($1, $3); }; expression : '(' expression ')' { $$ = $2;} - | symbol + | namespace_qualified_symbol { $$ = driver.add_expression_variable($1); } | non_negative_number { $$ = driver.add_non_negative_constant($1); } @@ -809,7 +810,7 @@ expression : '(' expression ')' { $$ = driver.add_max($3, $5); } | MIN '(' expression COMMA expression ')' { $$ = driver.add_min($3, $5); } - | symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_expression ')' + | namespace_qualified_symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_expression ')' { $$ = driver.add_model_var_or_external_function($1, false); } | NORMCDF '(' expression COMMA expression COMMA expression ')' { $$ = driver.add_normcdf($3, $5, $7); } @@ -939,7 +940,7 @@ tag_pair : NAME EQUAL QUOTED_STRING hand_side : '(' hand_side ')' { $$ = $2;} - | symbol + | namespace_qualified_symbol { $$ = driver.add_model_variable($1); } | symbol PIPE_E { $$ = driver.declare_or_change_type(SymbolType::endogenous, $1); } @@ -1019,7 +1020,7 @@ hand_side : '(' hand_side ')' { $$ = driver.add_max($3, $5); } | MIN '(' hand_side COMMA hand_side ')' { $$ = driver.add_min($3, $5); } - | symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_hand_side ')' + | namespace_qualified_symbol { driver.push_external_function_arg_vector_onto_stack(); } '(' comma_hand_side ')' { $$ = driver.add_model_var_or_external_function($1, true); } | NORMCDF '(' hand_side COMMA hand_side COMMA hand_side ')' { $$ = driver.add_normcdf($3, $5, $7); } @@ -2253,6 +2254,15 @@ filename : symbol | QUOTED_STRING ; +namespace_qualified_symbol : symbol + | namespace_qualified_symbol '.' symbol + { $$ = $1 + "." + $3; } + ; + +namespace_qualified_filename : namespace_qualified_symbol + | QUOTED_STRING + ; + parallel_local_filename_list : filename { driver.add_parallel_local_file($1); } | parallel_local_filename_list COMMA filename @@ -3559,14 +3569,14 @@ o_equations : EQUATIONS EQUAL vec_int o_silent_optimizer : SILENT_OPTIMIZER { driver.option_num("silent_optimizer", "true"); }; o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; -o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; +o_ext_func_name : EXT_FUNC_NAME EQUAL namespace_qualified_filename { driver.external_function_option("name", $3); }; o_ext_func_nargs : EXT_FUNC_NARGS EQUAL INT_NUMBER { driver.external_function_option("nargs",$3); }; -o_first_deriv_provided : FIRST_DERIV_PROVIDED EQUAL filename +o_first_deriv_provided : FIRST_DERIV_PROVIDED EQUAL namespace_qualified_filename { driver.external_function_option("first_deriv_provided", $3); } | FIRST_DERIV_PROVIDED { driver.external_function_option("first_deriv_provided", ""); } ; -o_second_deriv_provided : SECOND_DERIV_PROVIDED EQUAL filename +o_second_deriv_provided : SECOND_DERIV_PROVIDED EQUAL namespace_qualified_filename { driver.external_function_option("second_deriv_provided", $3); } | SECOND_DERIV_PROVIDED { driver.external_function_option("second_deriv_provided", ""); } diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll index 75307f2d..111d07cb 100644 --- a/src/DynareFlex.ll +++ b/src/DynareFlex.ll @@ -781,7 +781,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4]|w([1-9]{1}|[1-4][0-9]|5[0-2])) <DYNARE_STATEMENT>variances {return token::VARIANCES;} <DYNARE_STATEMENT>equations {return token::EQUATIONS;} -<DYNARE_STATEMENT>\. {return Dynare::parser::token_type (yytext[0]);} +<DYNARE_STATEMENT,DYNARE_BLOCK>\. {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT>\\ {return Dynare::parser::token_type (yytext[0]);} <DYNARE_STATEMENT>\' {return Dynare::parser::token_type (yytext[0]);} diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 4efbe0cf..2ecac4d6 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -319,6 +319,9 @@ ParsingDriver::add_inf_constant() expr_t ParsingDriver::add_model_variable(const string &name) { + if (name.find(".") != string::npos) + error(name + " treated as a variable, but it contains a '.'"); + check_symbol_existence_in_model_block(name); int symb_id; try @@ -406,6 +409,9 @@ ParsingDriver::add_model_variable(int symb_id, int lag) expr_t ParsingDriver::add_expression_variable(const string &name) { + if (name.find(".") != string::npos) + error(name + " treated as a variable, but it contains a '.'"); + if (parsing_epilogue && !mod_file->symbol_table.exists(name)) error("Variable " + name + " used in the epilogue block but was not declared."); -- GitLab