preprocessor: support echomacrovars(save). closes #1564

issue#70
Houtan Bastani 2017-12-04 14:16:42 +01:00
parent f836aa92c5
commit f57fb54a45
7 changed files with 67 additions and 18 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2015 Dynare Team * Copyright (C) 2015-2017 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -29,7 +29,7 @@ main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool sa
// Do macro processing // Do macro processing
MacroDriver m; MacroDriver m;
m.parse(modfile, modfiletxt, macro_output, debug, no_line_macro, defines, path); m.parse(modfile, basename, modfiletxt, macro_output, debug, no_line_macro, defines, path);
if (save_macro) if (save_macro)
{ {
if (save_macro_file.empty()) if (save_macro_file.empty())

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2008-2016 Dynare Team * Copyright (C) 2008-2017 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -74,7 +74,7 @@ class MacroDriver;
} }
%token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF %token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF
%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH %token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH ECHOMACROVARS SAVE
%token <int_val> INTEGER %token <int_val> INTEGER
%token <string_val> NAME STRING %token <string_val> NAME STRING
@ -121,6 +121,10 @@ statement : expr
{ TYPERR_CATCH(driver.error(@$, $2), @$); } { TYPERR_CATCH(driver.error(@$, $2), @$); }
| LINE STRING INTEGER | LINE STRING INTEGER
/* Ignore @#line declarations */ /* Ignore @#line declarations */
| ECHOMACROVARS
{ driver.printvars(@$, true); }
| ECHOMACROVARS LPAREN SAVE RPAREN
{ out << driver.printvars(@$, false); }
; ;
expr : INTEGER expr : INTEGER

View File

@ -37,10 +37,13 @@ MacroDriver::~MacroDriver()
} }
void void
MacroDriver::parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, MacroDriver::parse(const string &f, const string &fb, const string &modfiletxt,
map<string, string> defines, vector<string> path) ostream &out, bool debug, bool no_line_macro_arg, map<string, string> defines,
vector<string> path)
{ {
file = f; file = f;
basename = fb;
no_line_macro = no_line_macro_arg;
/* /*
Copy the file into a stringstream, and add an extra end-of-line. This is a Copy the file into a stringstream, and add an extra end-of-line. This is a
@ -206,12 +209,26 @@ MacroDriver::error(const Macro::parser::location_type &l, const MacroValue *valu
error(l, sval->value); error(l, sval->value);
} }
void string
MacroDriver::printvars(const Macro::parser::location_type &l) const MacroDriver::printvars(const Macro::parser::location_type &l, const bool tostdout) const
{ {
cout << "Macroprocessor: Printing macro variable values at line " << l << endl; if (tostdout)
{
cout << "Macroprocessor: Printing macro variable values from " << file
<< " at line " << l.begin.line << endl;
for (map<string, const MacroValue *>::const_iterator it = env.begin();
it != env.end(); it++)
cout << " " << it->first << " = " << it->second->print() << endl;
cout << endl;
return "";
}
stringstream intomfile;
if (!no_line_macro)
intomfile << "@#line \"" << file << "\" " << l.begin.line << endl;
for (map<string, const MacroValue *>::const_iterator it = env.begin(); for (map<string, const MacroValue *>::const_iterator it = env.begin();
it != env.end(); it++) it != env.end(); it++)
cout << "|- " << it->first << " = " << it->second->print() << endl; intomfile<< "options_.macrovars." << it->first << " = " << it->second->print() << ";" << endl;
cout << endl; return intomfile.str();
} }

View File

@ -182,12 +182,18 @@ public:
//! Starts parsing a file, returns output in out //! Starts parsing a file, returns output in out
/*! \param no_line_macro should we omit the @#line statements ? */ /*! \param no_line_macro should we omit the @#line statements ? */
void parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, void parse(const string &f, const string &fb, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro_arg,
map<string, string> defines, vector<string> path); map<string, string> defines, vector<string> path);
//! Name of main file being parsed //! Name of main file being parsed
string file; string file;
//! Basename of main file being parsed
string basename;
//! Whether or not to print @#line
bool no_line_macro;
//! Reference to the lexer //! Reference to the lexer
class MacroFlex *lexer; class MacroFlex *lexer;
@ -198,7 +204,7 @@ public:
void error(const Macro::parser::location_type &l, const string &m) const; void error(const Macro::parser::location_type &l, const string &m) const;
//! Print variables //! Print variables
void printvars(const Macro::parser::location_type &l) const; string printvars(const Macro::parser::location_type &l, const bool save) const;
//! Set a variable //! Set a variable
void set_variable(const string &name, const MacroValue *value); void set_variable(const string &name, const MacroValue *value);

View File

@ -236,7 +236,8 @@ CONT \\\\
<STMT>line { return token::LINE; } <STMT>line { return token::LINE; }
<STMT>define { return token::DEFINE; } <STMT>define { return token::DEFINE; }
<STMT>echomacrovars{SPC}*{EOL} { driver.printvars(*yylloc); BEGIN(INITIAL); } <STMT>echomacrovars { return token::ECHOMACROVARS; }
<STMT>save { return token::SAVE; }
<STMT>for { reading_for_statement = true; return token::FOR; } <STMT>for { reading_for_statement = true; return token::FOR; }
<STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); } <STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); }

View File

@ -407,7 +407,7 @@ StringMV::toString() const
string string
StringMV::print() const StringMV::print() const
{ {
return toString(); return "'" + value + "'";
} }
const MacroValue * const MacroValue *

View File

@ -23,6 +23,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <boost/lexical_cast.hpp>
using namespace std; using namespace std;
@ -344,16 +345,36 @@ template<typename T>
string string
ArrayMV<T>::print() const ArrayMV<T>::print() const
{ {
bool printStrArr = false;
try
{
typename vector<T>::const_iterator it = values.begin();
boost::lexical_cast<int>(*it);
}
catch (boost::bad_lexical_cast &)
{
printStrArr= true;
}
ostringstream ss; ostringstream ss;
ss << "["; if (printStrArr)
ss << "{";
else
ss << "[";
for (typename vector<T>::const_iterator it = values.begin(); for (typename vector<T>::const_iterator it = values.begin();
it != values.end(); it++) it != values.end(); it++)
{ {
if (it != values.begin()) if (it != values.begin())
ss << ", "; ss << ", ";
ss << *it;
if (printStrArr)
ss << "'" << *it << "'";
else
ss << *it;
} }
ss << "]"; if (printStrArr)
ss << "}";
else
ss << "]";
return ss.str(); return ss.str();
} }