diff --git a/DynareFlex.ll b/DynareFlex.ll
index 546ca19002309a108388803ef79c114bd172f2d3..9281f22aaf096723b0ed1ca3bdd758d285655d63 100644
--- a/DynareFlex.ll
+++ b/DynareFlex.ll
@@ -70,8 +70,8 @@ int sigma_e = 0;
   yylloc->step();
 %}
 
- /* Rules for matching @line directives */
-<*>^@line\ \"   { line_caller = YYSTATE; BEGIN(LINE1); }
+ /* Rules for matching $line directives */
+<*>^\$line\ \"  { line_caller = YYSTATE; BEGIN(LINE1); }
 <LINE1>[^\"]*   {
                   if (yylloc->begin.filename)
                     delete yylloc->begin.filename;
diff --git a/macro/MacroBison.yy b/macro/MacroBison.yy
index 7e23011e258f5660e163e4dc3890756a81f9379a..be9c41d47ff7cc912688e97fbb76cfbcec1f424b 100644
--- a/macro/MacroBison.yy
+++ b/macro/MacroBison.yy
@@ -40,8 +40,8 @@ class MacroDriver;
 {
   // Initialize the location filenames
   @$.begin.filename = @$.end.filename = &driver.file;
-  // Output first @line statement
-  out << "@line \"" << driver.file << "\" 1" << endl;
+  // Output first $line statement
+  out << "$line \"" << driver.file << "\" 1" << endl;
 };
 
 %debug
@@ -118,7 +118,7 @@ statement : expr
           | ERROR expr
             { TYPERR_CATCH(driver.error(@$, $2), @$); }
           | LINE STRING INTEGER
-            /* Ignore @line declarations */
+            /* Ignore $line declarations */
           ;
 
 expr : INTEGER
diff --git a/macro/MacroDriver.cc b/macro/MacroDriver.cc
index a18c38f2daaeddef7d1479c3f0b27955b4bdcbd7..98875a00191f18da0c43e6ae0760535ac9ec6d48 100644
--- a/macro/MacroDriver.cc
+++ b/macro/MacroDriver.cc
@@ -83,7 +83,7 @@ MacroDriver::init_loop(const string &name, const MacroValue *value) throw (Macro
   const ArrayMV<int> *mv1 = dynamic_cast<const ArrayMV<int> *>(value);
   const ArrayMV<string> *mv2 = dynamic_cast<const ArrayMV<string> *>(value);
   if (!mv1 && !mv2)
-    throw MacroValue::TypeError("Argument of @for loop must be an array expression");
+    throw MacroValue::TypeError("Argument of $for loop must be an array expression");
   loop_stack.push(make_pair(name, make_pair(value, 0)));
 }
 
@@ -132,7 +132,7 @@ MacroDriver::begin_if(const MacroValue *value) throw (MacroValue::TypeError)
 {
   const IntMV *ival = dynamic_cast<const IntMV *>(value);
   if (!ival)
-    throw MacroValue::TypeError("Argument of @if must be an integer");
+    throw MacroValue::TypeError("Argument of $if must be an integer");
   last_if = (bool) ival->value;
 }
 
@@ -141,7 +141,7 @@ MacroDriver::echo(const Macro::parser::location_type &l, const MacroValue *value
 {
   const StringMV *sval = dynamic_cast<const StringMV *>(value);
   if (!sval)
-    throw MacroValue::TypeError("Argument of @echo must be a string");
+    throw MacroValue::TypeError("Argument of $echo must be a string");
 
   cerr << "ECHO in macro-processor: " << l << ": " << sval->value << endl;
 }
@@ -151,7 +151,7 @@ MacroDriver::error(const Macro::parser::location_type &l, const MacroValue *valu
 {
   const StringMV *sval = dynamic_cast<const StringMV *>(value);
   if (!sval)
-    throw MacroValue::TypeError("Argument of @error must be a string");
+    throw MacroValue::TypeError("Argument of $error must be a string");
 
   error(l, sval->value);
 }
diff --git a/macro/MacroDriver.hh b/macro/MacroDriver.hh
index 7f4c0b85e42ee78ceb90d760fd2e69a946a896e3..37985d3277f4fc22c81a85968b5220d2a79aa938 100644
--- a/macro/MacroDriver.hh
+++ b/macro/MacroDriver.hh
@@ -81,12 +81,12 @@ private:
   string for_body_tmp;
   //! Temporary variable used in FOR_BODY mode
   Macro::parser::location_type for_body_loc_tmp;
-  //! Temporary variable used in FOR_BODY mode. Keeps track of number of nested @for/@endfor
+  //! Temporary variable used in FOR_BODY mode. Keeps track of number of nested $for/$endfor
   int nested_for_nb;
   //! Set to true while parsing a FOR statement (only the statement, not the loop body)
   bool reading_for_statement;
 
-  //! Temporary variable used in THEN_BODY and ELSE_BODY modes. Keeps track of number of nested @if
+  //! Temporary variable used in THEN_BODY and ELSE_BODY modes. Keeps track of number of nested $if
   int nested_if_nb;
   //! Temporary variable used in THEN_BODY mode
   string then_body_tmp;
@@ -99,7 +99,7 @@ private:
   //! Set to true while parsing an IF statement (only the statement, not the body)
   bool reading_if_statement;
 
-  //! Output the @line declaration
+  //! Output the $line declaration
   void output_line(Macro::parser::location_type *yylloc) const;
 
   //! Save current scanning context
@@ -170,7 +170,7 @@ public:
   //! Reference to the lexer
   class MacroFlex *lexer;
 
-  //! Used to store the value of the last @if condition
+  //! Used to store the value of the last $if condition
   bool last_if;
 
   //! Error handler
@@ -191,13 +191,13 @@ public:
   /*! Returns false if iteration is no more possible (end of loop); in that case it destroys the pointer given to init_loop() */
   bool iter_loop();
 
-  //! Begins an @if statement
+  //! Begins an $if statement
   void begin_if(const MacroValue *value) throw (MacroValue::TypeError);
 
-  //! Executes @echo directive
+  //! Executes $echo directive
   void echo(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError);
 
-  //! Executes @error directive
+  //! Executes $error directive
   void error(const Macro::parser::location_type &l, const MacroValue *value) const throw (MacroValue::TypeError);
 };
 
diff --git a/macro/MacroFlex.ll b/macro/MacroFlex.ll
index d1d2fc9ece56b2e4b85b8493fa62d90005770800..84ffc3b3e738da38d66e63b3c125061e48fa217b 100644
--- a/macro/MacroFlex.ll
+++ b/macro/MacroFlex.ll
@@ -47,7 +47,8 @@ typedef Macro::parser::token token;
 
 %option case-insensitive noyywrap nounput batch debug never-interactive
 
-%x MACRO
+%x STMT
+%x EXPR
 %x FOR_BODY
 %x THEN_BODY
 %x ELSE_BODY
@@ -68,7 +69,7 @@ CONT \\\\
   yylloc->step();
 %}
 
-<INITIAL>@{SPC}*include{SPC}+\"[^\"\r\n]*\"{SPC}*{EOL} {
+<INITIAL>^{SPC}*\${SPC}*include{SPC}+\"[^\"\r\n]*\"{SPC}*{EOL} {
                               yylloc->lines(1);
                               yylloc->step();
 
@@ -84,15 +85,13 @@ CONT \\\\
                               BEGIN(INITIAL);
                             }
 
- /* Double at-sign gives a single at-sign in output: useful for Matlab function-handles */
-<INITIAL>@@                 { *yyout << '@'; }
+<INITIAL>^{SPC}*\$          { yylloc->step(); BEGIN(STMT); }
+<INITIAL>\$\{               { yylloc->step(); BEGIN(EXPR); }
 
-<INITIAL>@                  { BEGIN(MACRO); }
+<EXPR>\}                    { BEGIN(INITIAL); return token::EOL; }
 
-<MACRO>{SPC}+               { yylloc->step(); }
-<MACRO>@                    { BEGIN(INITIAL); return token::EOL; }
-<MACRO>{CONT}{SPC}*{EOL}    { yylloc->lines(1); yylloc->step(); }
-<MACRO>{EOL}                {
+<STMT>{CONT}{SPC}*{EOL}     { yylloc->lines(1); yylloc->step(); }
+<STMT>{EOL}                 {
                               yylloc->lines(1);
                               yylloc->step();
                               if (reading_for_statement)
@@ -119,74 +118,78 @@ CONT \\\\
                               return token::EOL;
                             }
 
-<MACRO>[0-9]+               {
+<STMT,EXPR>{SPC}+           { yylloc->step(); }
+
+<STMT,EXPR>[0-9]+           {
                               yylval->int_val = atoi(yytext);
                               return token::INTEGER;
                             }
-<MACRO>\(                   { return token::LPAREN; }
-<MACRO>\)                   { return token::RPAREN; }
-<MACRO>\[                   { return token::LBRACKET; }
-<MACRO>\]                   { return token::RBRACKET; }
-<MACRO>:                    { return token::COLON; }
-<MACRO>,                    { return token::COMMA; }
-<MACRO>=                    { return token::EQUAL; }
-<MACRO>[!]                  { return token::EXCLAMATION; }
-<MACRO>"||"                 { return token::LOGICAL_OR; }
-<MACRO>&&                   { return token::LOGICAL_AND; }
-<MACRO>"<="                 { return token::LESS_EQUAL; }
-<MACRO>">="                 { return token::GREATER_EQUAL; }
-<MACRO>"<"                  { return token::LESS; }
-<MACRO>">"                  { return token::GREATER; }
-<MACRO>"=="                 { return token::EQUAL_EQUAL; }
-<MACRO>"!="                 { return token::EXCLAMATION_EQUAL; }
-<MACRO>[+]                  { return token::PLUS; }
-<MACRO>[-]                  { return token::MINUS; }
-<MACRO>[*]                  { return token::TIMES; }
-<MACRO>[/]                  { return token::DIVIDE; }
-
-<MACRO>\"[^\"]*\"           {
+<STMT,EXPR>\(               { return token::LPAREN; }
+<STMT,EXPR>\)               { return token::RPAREN; }
+<STMT,EXPR>\[               { return token::LBRACKET; }
+<STMT,EXPR>\]               { return token::RBRACKET; }
+<STMT,EXPR>:                { return token::COLON; }
+<STMT,EXPR>,                { return token::COMMA; }
+<STMT,EXPR>=                { return token::EQUAL; }
+<STMT,EXPR>[!]              { return token::EXCLAMATION; }
+<STMT,EXPR>"||"             { return token::LOGICAL_OR; }
+<STMT,EXPR>&&               { return token::LOGICAL_AND; }
+<STMT,EXPR>"<="             { return token::LESS_EQUAL; }
+<STMT,EXPR>">="             { return token::GREATER_EQUAL; }
+<STMT,EXPR>"<"              { return token::LESS; }
+<STMT,EXPR>">"              { return token::GREATER; }
+<STMT,EXPR>"=="             { return token::EQUAL_EQUAL; }
+<STMT,EXPR>"!="             { return token::EXCLAMATION_EQUAL; }
+<STMT,EXPR>[+]              { return token::PLUS; }
+<STMT,EXPR>[-]              { return token::MINUS; }
+<STMT,EXPR>[*]              { return token::TIMES; }
+<STMT,EXPR>[/]              { return token::DIVIDE; }
+
+<STMT,EXPR>\"[^\"]*\"       {
                               yylval->string_val = new string(yytext + 1);
                               yylval->string_val->resize(yylval->string_val->length() - 1);
                               return token::STRING;
                             }
 
-<MACRO>line                 { return token::LINE; }
-<MACRO>define               { return token::DEFINE; }
+<STMT>line                  { return token::LINE; }
+<STMT>define                { return token::DEFINE; }
 
-<MACRO>for                  { reading_for_statement = true; return token::FOR; }
-<MACRO>in                   { return token::IN; }
-<MACRO>endfor               { driver.error(*yylloc, "@endfor is not matched by a @for statement"); }
+<STMT>for                   { reading_for_statement = true; return token::FOR; }
+<STMT>in                    { return token::IN; }
+<STMT>endfor                { driver.error(*yylloc, "$endfor is not matched by a $for statement"); }
 
-<MACRO>if                   { reading_if_statement = true; return token::IF; }
-<MACRO>else                 { driver.error(*yylloc, "@else is not matched by an @if statement"); }
-<MACRO>endif                { driver.error(*yylloc, "@endif is not matched by an @if statement"); }
+<STMT>if                    { reading_if_statement = true; return token::IF; }
+<STMT>else                  { driver.error(*yylloc, "$else is not matched by an $if statement"); }
+<STMT>endif                 { driver.error(*yylloc, "$endif is not matched by an $if statement"); }
 
-<MACRO>echo                 { return token::ECHO_DIR; }
-<MACRO>error                { return token::ERROR; }
+<STMT>echo                  { return token::ECHO_DIR; }
+<STMT>error                 { return token::ERROR; }
 
-<MACRO>[A-Za-z_][A-Za-z0-9_]* {
+<STMT,EXPR>[A-Za-z_][A-Za-z0-9_]* {
                               yylval->string_val = new string(yytext);
                               return token::NAME;
                             }
 
-<MACRO><<EOF>>              { driver.error(*yylloc, "Unexpected end of file while parsing a macro expression"); }
+<EXPR><<EOF>>               { driver.error(*yylloc, "Unexpected end of file while parsing a macro expression"); }
+<STMT><<EOF>>               { driver.error(*yylloc, "Unexpected end of file while parsing a macro statement"); }
 
 <FOR_BODY>{EOL}             { yylloc->lines(1); yylloc->step(); for_body_tmp.append(yytext); }
-<FOR_BODY>^{SPC}*@{SPC}*for({SPC}|{CONT}) {
-                              /* In order to catch nested @for, it is necessary to start from the beginning of
-                                 the line (otherwise we could catch something like "@var@ for" */
+<FOR_BODY>^{SPC}*\${SPC}*for({SPC}|{CONT}) {
+                              /* In order to catch nested $for, it is necessary to start from the beginning of
+                                 the line (otherwise we could catch something like "${var} for" */
                               nested_for_nb++;
                               for_body_tmp.append(yytext);
+                              yylloc->step();
                             }
-<FOR_BODY>.                 { for_body_tmp.append(yytext); }
-<FOR_BODY><<EOF>>           { driver.error(*yylloc, "Unexpected end of file: @for loop not matched by an @endfor"); }
-<FOR_BODY>@{SPC}*endfor{SPC}*{EOL} {
+<FOR_BODY>.                 { for_body_tmp.append(yytext); yylloc->step(); }
+<FOR_BODY><<EOF>>           { driver.error(*yylloc, "Unexpected end of file: $for loop not matched by an $endfor"); }
+<FOR_BODY>^{SPC}*\${SPC}*endfor{SPC}*{EOL} {
                               yylloc->lines(1);
                               yylloc->step();
                               if (nested_for_nb)
                                 {
-                                  /* This @endfor is not the end of the loop body,
-                                     but only that of a nested @for loop */
+                                  /* This $endfor is not the end of the loop body,
+                                     but only that of a nested $for loop */
                                   nested_for_nb--;
                                   for_body_tmp.append(yytext);
                                 }
@@ -205,15 +208,16 @@ CONT \\\\
                             }
 
 <THEN_BODY>{EOL}            { yylloc->lines(1); yylloc->step(); then_body_tmp.append(yytext); }
-<THEN_BODY>^{SPC}*@{SPC}*if({SPC}|{CONT}) {
-                              /* In order to catch nested @if, it is necessary to start from the beginning of
-                                 the line (otherwise we could catch something like "@var@ if" */
+<THEN_BODY>^{SPC}*\${SPC}*if({SPC}|{CONT}) {
+                              /* In order to catch nested $if, it is necessary to start from the beginning of
+                                 the line (otherwise we could catch something like "${var} if" */
                               nested_if_nb++;
                               then_body_tmp.append(yytext);
+                              yylloc->step();
                             }
-<THEN_BODY>.                { then_body_tmp.append(yytext); }
-<THEN_BODY><<EOF>>          { driver.error(*yylloc, "Unexpected end of file: @if not matched by an @endif"); }
-<THEN_BODY>@{SPC}*else{SPC}*{EOL} {
+<THEN_BODY>.                { then_body_tmp.append(yytext); yylloc->step(); }
+<THEN_BODY><<EOF>>          { driver.error(*yylloc, "Unexpected end of file: $if not matched by an $endif"); }
+<THEN_BODY>^{SPC}*\${SPC}*else{SPC}*{EOL} {
                               yylloc->lines(1);
                               yylloc->step();
                               if (nested_if_nb)
@@ -226,13 +230,13 @@ CONT \\\\
                                 }
                              }
 
-<THEN_BODY>@{SPC}*endif{SPC}*{EOL} {
+<THEN_BODY>^{SPC}*\${SPC}*endif{SPC}*{EOL} {
                               yylloc->lines(1);
                               yylloc->step();
                               if (nested_if_nb)
                                 {
-                                  /* This @endif is not the end of the @if we're parsing,
-                                     but only that of a nested @if */
+                                  /* This $endif is not the end of the $if we're parsing,
+                                     but only that of a nested $if */
                                   nested_if_nb--;
                                   then_body_tmp.append(yytext);
                                 }
@@ -248,22 +252,23 @@ CONT \\\\
                             }
 
 <ELSE_BODY>{EOL}            { yylloc->lines(1); yylloc->step(); else_body_tmp.append(yytext); }
-<ELSE_BODY>^{SPC}*@{SPC}*if({SPC}|{CONT}) {
-                              /* In order to catch nested @if, it is necessary to start from the beginning of
-                                 the line (otherwise we could catch something like "@var@ if" */
+<ELSE_BODY>^{SPC}*\${SPC}*if({SPC}|{CONT}) {
+                              /* In order to catch nested $if, it is necessary to start from the beginning of
+                                 the line (otherwise we could catch something like "${var} if" */
                               nested_if_nb++;
                               else_body_tmp.append(yytext);
+                              yylloc->step();
                             }
-<ELSE_BODY>.                { else_body_tmp.append(yytext); }
-<ELSE_BODY><<EOF>>          { driver.error(*yylloc, "Unexpected end of file: @if not matched by an @endif"); }
+<ELSE_BODY>.                { else_body_tmp.append(yytext); yylloc->step(); }
+<ELSE_BODY><<EOF>>          { driver.error(*yylloc, "Unexpected end of file: $if not matched by an $endif"); }
 
-<ELSE_BODY>@{SPC}*endif{SPC}*{EOL} {
+<ELSE_BODY>^{SPC}*\${SPC}*endif{SPC}*{EOL} {
                               yylloc->lines(1);
                               yylloc->step();
                               if (nested_if_nb)
                                 {
-                                  /* This @endif is not the end of the @if we're parsing,
-                                     but only that of a nested @if */
+                                  /* This $endif is not the end of the $if we're parsing,
+                                     but only that of a nested $if */
                                   nested_if_nb--;
                                   else_body_tmp.append(yytext);
                                 }
@@ -296,11 +301,10 @@ CONT \\\\
                                 restore_context(yylloc);
                             }
 
- /* Ignore \r, because under Cygwin, outputting \n automatically adds another \r */
-<INITIAL>[\r]+              { yylloc->step(); }
+ /* We don't use echo, because under Cygwin it will add an extra \r */
+<INITIAL>{EOL}              { yylloc->lines(1); yylloc->step(); *yyout << endl; }
 
  /* Copy everything else to output */
-<INITIAL>[\n]+              { yylloc->lines(yyleng); yylloc->step(); ECHO; }
 <INITIAL>.                  { yylloc->step(); ECHO; }
 
 <*>.                        { driver.error(*yylloc, "Macro lexer error: '" + string(yytext) + "'"); }
@@ -314,7 +318,7 @@ MacroFlex::MacroFlex(istream* in, ostream* out)
 void
 MacroFlex::output_line(Macro::parser::location_type *yylloc) const
 {
-  *yyout << endl << "@line \"" << *yylloc->begin.filename << "\" "
+  *yyout << endl << "$line \"" << *yylloc->begin.filename << "\" "
          << yylloc->begin.line << endl;
 }
 
@@ -334,7 +338,7 @@ MacroFlex::restore_context(Macro::parser::location_type *yylloc)
   for_body_loc = context_stack.top().for_body_loc;
   // Remove top of stack
   context_stack.pop();
-  // Dump @line instruction
+  // Dump $line instruction
   output_line(yylloc);
 }
 
@@ -353,7 +357,7 @@ MacroFlex::create_include_context(string *filename, Macro::parser::location_type
   yylloc->begin.column = yylloc->end.column = 0;
   // We are not in a loop body
   for_body.clear();
-  // Output @line information
+  // Output $line information
   output_line(yylloc);
   // Switch to new buffer
   yy_switch_to_buffer(yy_create_buffer(input, YY_BUF_SIZE));