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));