# HG changeset patch # User mjsousa # Date 1336600810 -3600 # Node ID dab341e806643bf0434382f62e9b15607ffa5dca # Parent 8cc4c51c4bfc2447403597b527b2281187c5dc72 Fix parsing os TIME literals & rename the extract_integer() function. diff -r 8cc4c51c4bfc -r dab341e80664 absyntax/absyntax.def --- a/absyntax/absyntax.def Wed May 09 22:59:10 2012 +0100 +++ b/absyntax/absyntax.def Wed May 09 23:00:10 2012 +0100 @@ -210,13 +210,15 @@ /************************/ SYM_REF0(neg_time_c) SYM_REF3(duration_c, type_name, neg, interval) +SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) SYM_TOKEN(fixed_point_c) +/* SYM_REF2(days_c, days, hours) SYM_REF2(hours_c, hours, minutes) SYM_REF2(minutes_c, minutes, seconds) SYM_REF2(seconds_c, seconds, milliseconds) SYM_REF1(milliseconds_c, milliseconds) - +*/ /************************************/ /* B 1.2.3.2 - Time of day and Date */ diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/absyntax_utils.cc --- a/absyntax_utils/absyntax_utils.cc Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/absyntax_utils.cc Wed May 09 23:00:10 2012 +0100 @@ -98,20 +98,21 @@ /* extract the value of an integer from an integer_c object !! */ /* NOTE: it must ignore underscores! */ -int extract_integer(symbol_c *sym) { +long long extract_integer_value(symbol_c *sym) { std::string str = ""; integer_c *integer; neg_integer_c * neg_integer; if ((neg_integer = dynamic_cast(sym)) != NULL) - return - extract_integer((integer_c *)neg_integer->exp); + return - extract_integer_value(neg_integer->exp); if ((integer = dynamic_cast(sym)) == NULL) ERROR; for(unsigned int i = 0; i < strlen(integer->value); i++) if (integer->value[i] != '_') str += integer->value[i]; - return atoi(str.c_str()); + /* return atoi(str.c_str()); */ + return atoll(str.c_str()); } diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/absyntax_utils.hh --- a/absyntax_utils/absyntax_utils.hh Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/absyntax_utils.hh Wed May 09 23:00:10 2012 +0100 @@ -56,7 +56,7 @@ int compare_identifiers(symbol_c *ident1, symbol_c *ident2); /* extract the value of an integer from an integer_c object !! */ -int extract_integer(symbol_c *integer); +long long extract_integer_value(symbol_c *integer); /* A symbol table with all globally declared functions... */ extern function_declaration_c null_symbol1; @@ -119,7 +119,6 @@ #include "search_expression_type.hh" #include "add_en_eno_param_decl.hh" #include "get_sizeof_datatype.hh" -#include "get_function_type.h" #include "search_il_label.hh" #include "get_var_name.hh" diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/function_param_iterator.cc --- a/absyntax_utils/function_param_iterator.cc Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/function_param_iterator.cc Wed May 09 23:00:10 2012 +0100 @@ -130,7 +130,7 @@ if (extensible_parameter != NULL) { sym = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_integer(extensible_parameter->first_index); + _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index); } identifier_c *variable_name = dynamic_cast(sym); if (variable_name == NULL) ERROR; @@ -167,7 +167,7 @@ if (extensible_parameter != NULL) { var_name = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_integer(extensible_parameter->first_index); + _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index); } identifier_c *variable_name = dynamic_cast(var_name); if (variable_name == NULL) ERROR; @@ -265,7 +265,7 @@ if (extensible_parameter != NULL) { sym = extensible_parameter->var_name; current_param_is_extensible = true; - _first_extensible_param_index = extract_integer(extensible_parameter->first_index); + _first_extensible_param_index = extract_integer_value(extensible_parameter->first_index); current_extensible_param_index = _first_extensible_param_index; } identifier = dynamic_cast(sym); diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/search_constant_type.cc --- a/absyntax_utils/search_constant_type.cc Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/search_constant_type.cc Wed May 09 23:00:10 2012 +0100 @@ -105,11 +105,7 @@ void *search_constant_type_c::visit(neg_time_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ void *search_constant_type_c::visit(duration_c *symbol) {return (void *)(symbol->type_name);} void *search_constant_type_c::visit(fixed_point_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(days_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(hours_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(minutes_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(seconds_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ -void *search_constant_type_c::visit(milliseconds_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ +void *search_constant_type_c::visit(interval_c *symbol) {ERROR; return NULL;} /* this member function should never be called. */ /************************************/ /* B 1.2.3.2 - Time of day and Date */ diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/search_constant_type.hh --- a/absyntax_utils/search_constant_type.hh Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/search_constant_type.hh Wed May 09 23:00:10 2012 +0100 @@ -168,12 +168,8 @@ /************************/ void *visit(neg_time_c *symbol); void *visit(duration_c *symbol); + void *visit(interval_c *symbol); void *visit(fixed_point_c *symbol); - void *visit(days_c *symbol); - void *visit(hours_c *symbol); - void *visit(minutes_c *symbol); - void *visit(seconds_c *symbol); - void *visit(milliseconds_c *symbol); /************************************/ /* B 1.2.3.2 - Time of day and Date */ diff -r 8cc4c51c4bfc -r dab341e80664 absyntax_utils/type_initial_value.cc --- a/absyntax_utils/type_initial_value.cc Wed May 09 22:59:10 2012 +0100 +++ b/absyntax_utils/type_initial_value.cc Wed May 09 23:00:10 2012 +0100 @@ -84,7 +84,7 @@ date_literal_0 = new date_literal_c(integer_1, integer_1, integer_1); date_literal_0 = new date_literal_c(new integer_c("1970"), integer_1, integer_1); daytime_literal_0 = new daytime_c(integer_0, integer_0, real_0); - time_0 = new duration_c(new time_type_name_c(), NULL, new seconds_c(integer_0, NULL)); // T#0S + time_0 = new duration_c(new time_type_name_c(), NULL, new interval_c(NULL, NULL, NULL, integer_0, NULL)); // T#0s date_0 = new date_c(new date_type_name_c(), date_literal_0); // D#0001-01-01 tod_0 = new time_of_day_c(new tod_type_name_c(), daytime_literal_0); // TOD#00:00:00 dt_0 = new date_and_time_c(new dt_type_name_c(), date_literal_0, daytime_literal_0); // DT#0001-01-01-00:00:00 diff -r 8cc4c51c4bfc -r dab341e80664 stage1_2/iec_bison.yy --- a/stage1_2/iec_bison.yy Wed May 09 22:59:10 2012 +0100 +++ b/stage1_2/iec_bison.yy Wed May 09 23:00:10 2012 +0100 @@ -58,6 +58,17 @@ /**********************************************************************/ /**********************************************************************/ +/* NOTE: the following file contains many rules used merely for detecting errors in + * the IEC source code being parsed. + * To remove all these rules, simply execute the command (first replace all '%' with '/'): + * $sed '\:%\* ERROR_CHECK_BEGIN \*%:,\:%\* ERROR_CHECK_END \*%: d' iec_bison.yy + * + * The above command had to be edited ('/' replaced by '%') so as not to include the C syntax that closes + * comments inside this comment! + * If you place the command in a shell script, be sure to remove the backslashes '\' before each asterisk '*' !! + */ + + @@ -490,17 +501,6 @@ %type seconds %type milliseconds -%type integer_d -%type integer_h -%type integer_m -%type integer_s -%type integer_ms -%type fixed_point_d -%type fixed_point_h -%type fixed_point_m -%type fixed_point_s -%type fixed_point_ms - %token fixed_point_token %token fixed_point_d_token %token integer_d_token @@ -512,7 +512,8 @@ %token integer_s_token %token fixed_point_ms_token %token integer_ms_token - +%token end_interval_token +%token erroneous_interval_token // %token TIME %token T_SHARP @@ -2138,156 +2139,56 @@ {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;} | TIME '-' interval {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between 'TIME' and interval in duration."); yynerrs++;} -| TIME '#' error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for duration.");} - else {print_err_msg(locf(@3), locl(@3), "invalid value for duration."); yyclearin;} - yyerrok; - } -| T_SHARP error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@1), locf(@2), "no value defined for duration.");} - else {print_err_msg(locf(@2), locl(@2), "invalid value for duration."); yyclearin;} - yyerrok; - } -/* ERROR_CHECK_END */ -; +| TIME '#' erroneous_interval_token + {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value for duration."); yynerrs++;} +| T_SHARP erroneous_interval_token + {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid value for duration."); yynerrs++;} +| TIME '#' '-' erroneous_interval_token + {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid value for duration."); yynerrs++;} +| T_SHARP '-' erroneous_interval_token + {$$ = NULL; print_err_msg(locf(@2), locl(@2), "invalid value for duration."); yynerrs++;} +/* ERROR_CHECK_END */ +; + +fixed_point: + integer +| fixed_point_token {$$ = new fixed_point_c($1, locloc(@$));}; interval: - days -| hours -| minutes -| seconds -| milliseconds -; - -integer_d: integer_d_token {$$ = new integer_c($1, locloc(@$));}; -integer_h: integer_h_token {$$ = new integer_c($1, locloc(@$));}; -integer_m: integer_m_token {$$ = new integer_c($1, locloc(@$));}; -integer_s: integer_s_token {$$ = new integer_c($1, locloc(@$));}; -integer_ms: integer_ms_token {$$ = new integer_c($1, locloc(@$));}; - -fixed_point_d: - fixed_point_d_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer_d -; - -fixed_point_h: - fixed_point_h_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer_h -; - -fixed_point_m: - fixed_point_m_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer_m -; - -fixed_point_s: - fixed_point_s_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer_s -; - -fixed_point_ms: - fixed_point_ms_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer_ms -; - - -fixed_point: - fixed_point_token - {$$ = new fixed_point_c($1, locloc(@$));} -| integer -; - - -days: -/* fixed_point ('d') */ - fixed_point_d - {$$ = new days_c($1, NULL, locloc(@$));} -/*| integer ('d') ['_'] hours */ -| integer_d hours - {$$ = new days_c($1, $2, locloc(@$));} -| integer_d '_' hours - {$$ = new days_c($1, $3, locloc(@$));} -/* ERROR_CHECK_BEGIN */ -| integer_d '_' error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for hours in duration.");} - else {print_err_msg(locf(@3), locl(@3), "invalid value for hours in duration."); yyclearin;} - yyerrok; - } -/* ERROR_CHECK_END */ -; - - -hours: -/* fixed_point ('h') */ - fixed_point_h - {$$ = new hours_c($1, NULL, locloc(@$));} -/*| integer ('h') ['_'] minutes */ -| integer_h minutes - {$$ = new hours_c($1, $2, locloc(@$));} -| integer_h '_' minutes - {$$ = new hours_c($1, $3, locloc(@$));} -/* ERROR_CHECK_BEGIN */ -| integer_h '_' error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for minutes in duration.");} - else {print_err_msg(locf(@3), locl(@3), "invalid value for minutes in duration."); yyclearin;} - yyerrok; - } -/* ERROR_CHECK_END */ - -; - -minutes: -/* fixed_point ('m') */ - fixed_point_m - {$$ = new minutes_c($1, NULL, locloc(@$));} -/*| integer ('m') ['_'] seconds */ -| integer_m seconds - {$$ = new minutes_c($1, $2, locloc(@$));} -| integer_m '_' seconds - {$$ = new minutes_c($1, $3, locloc(@$));} -/* ERROR_CHECK_BEGIN */ -| integer_m '_' error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for seconds in duration.");} - else {print_err_msg(locf(@3), locl(@3), "invalid value for seconds in duration."); yyclearin;} - yyerrok; - } -/* ERROR_CHECK_END */ -; - -seconds: -/* fixed_point ('s') */ - fixed_point_s - {$$ = new seconds_c($1, NULL, locloc(@$));} -/*| integer ('s') ['_'] milliseconds */ -| integer_s milliseconds - {$$ = new seconds_c($1, $2, locloc(@$));} -| integer_s '_' milliseconds - {$$ = new seconds_c($1, $3, locloc(@$));} -/* ERROR_CHECK_BEGIN */ -| integer_s '_' error - {$$ = NULL; - if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no value defined for milliseconds in duration.");} - else {print_err_msg(locf(@3), locl(@3), "invalid value for milliseconds in duration."); yyclearin;} - yyerrok; - } -/* ERROR_CHECK_END */ -; - -milliseconds: -/* fixed_point ('ms') */ - fixed_point_ms - {$$ = new milliseconds_c($1, locloc(@$));} + days hours minutes seconds milliseconds end_interval_token + {$$ = new interval_c($1, $2, $3, $4, $5, locloc(@$));}; +; + + +days: /* fixed_point ('d') */ + /* empty */ {$$ = NULL;} +| fixed_point_d_token {$$ = new fixed_point_c($1, locloc(@$));}; +| integer_d_token {$$ = new integer_c($1, locloc(@$));}; +; + +hours: /* fixed_point ('h') */ + /* empty */ {$$ = NULL;} +| fixed_point_h_token {$$ = new fixed_point_c($1, locloc(@$));}; +| integer_h_token {$$ = new integer_c($1, locloc(@$));}; +; + +minutes: /* fixed_point ('m') */ + /* empty */ {$$ = NULL;} +| fixed_point_m_token {$$ = new fixed_point_c($1, locloc(@$));}; +| integer_m_token {$$ = new integer_c($1, locloc(@$));}; +; + +seconds: /* fixed_point ('s') */ + /* empty */ {$$ = NULL;} +| fixed_point_s_token {$$ = new fixed_point_c($1, locloc(@$));}; +| integer_s_token {$$ = new integer_c($1, locloc(@$));}; +; + +milliseconds: /* fixed_point ('ms') */ + /* empty */ {$$ = NULL;} +| fixed_point_ms_token {$$ = new fixed_point_c($1, locloc(@$));}; +| integer_ms_token {$$ = new integer_c($1, locloc(@$));}; ; @@ -2985,13 +2886,18 @@ {$$ = new array_initial_elements_list_c(locloc(@$)); $$->add_element($1);} | array_initial_elements_list ',' array_initial_elements {$$ = $1; $$->add_element($3);} -/* ERROR_CHECK_BEGIN +/* ERROR_CHECK_BEGIN */ +/* The following error checking rules have been commented out. Why? Was it a typo? + * Lets keep them commented out for now... + */ +/* | array_initial_elements_list ',' error {$$ = $1; if (is_current_syntax_token()) {print_err_msg(locl(@2), locf(@3), "no array initial value in array initial values list.");} else {print_err_msg(locf(@3), locl(@3), "invalid array initial value in array initial values list."); yyclearin;} yyerrok; } +*/ /* ERROR_CHECK_END */ ; @@ -3145,7 +3051,11 @@ {$$ = new structure_element_initialization_list_c(locloc(@$)); $$->add_element($1);} | structure_element_initialization_list ',' structure_element_initialization {$$ = $1; $$->add_element($3);} -/* ERROR_CHECK_BEGIN +/* ERROR_CHECK_BEGIN */ +/* The following error checking rules have been commented out. Why? Was it a typo? + * Lets keep them commented out for now... + */ +/* | structure_element_initialization_list structure_element_initialization {$$ = $1; print_err_msg(locl(@1), locf(@2), "',' missing in structure element initialization list in structure initialization."); yynerrs++;} | structure_element_initialization_list ',' error @@ -3154,6 +3064,7 @@ else {print_err_msg(locf(@3), locl(@3), "invalid structure element initialization in structure initialization."); yyclearin;} yyerrok; } +*/ /* ERROR_CHECK_END */ ; @@ -5454,12 +5365,15 @@ {$$ = NULL;} | '(' {cmd_goto_sfc_priority_state();} PRIORITY {cmd_pop_state();} ASSIGN integer ')' {$$ = $6;} -/* ERROR_CHECK_BEGIN +/* ERROR_CHECK_BEGIN */ +/* The following error checking rules have been intentionally commented out. */ +/* | '(' ASSIGN integer ')' {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'PRIORITY' missing between '(' and ':=' in transition declaration with priority."); yynerrs++;} | '(' error ASSIGN integer ')' {$$ = NULL; print_err_msg(locf(@2), locl(@2), "expecting 'PRIORITY' between '(' and ':=' in transition declaration with priority."); yyerrok;} - ERROR_CHECK_END */ +*/ +/* ERROR_CHECK_END */ ; @@ -8250,6 +8164,7 @@ } /* first parse the standard library file... */ + /* Do not debug the standard library, even if debug flag is set! */ /* #if YYDEBUG yydebug = 1; diff -r 8cc4c51c4bfc -r dab341e80664 stage1_2/iec_flex.ll --- a/stage1_2/iec_flex.ll Wed May 09 22:59:10 2012 +0100 +++ b/stage1_2/iec_flex.ll Wed May 09 23:00:10 2012 +0100 @@ -91,8 +91,10 @@ */ %option noyy_top_state -/* We will not be using unput() in our flex code... */ +/* We will be using unput() in our flex code, so we cannot set the following option!... */ +/* %option nounput +*/ /**************************************************/ /* External Variable and Function declarations... */ @@ -241,6 +243,10 @@ %{ /* return all the text in the current token back to the input stream. */ void unput_text(unsigned int n); +/* return all the text in the current token back to the input stream, + * but first return to the stream an additional character to mark the end of the token. + */ +void unput_and_mark(const char c); %} @@ -340,6 +346,16 @@ * expecting any action qualifiers, flex does not return these tokens, and is free * to interpret them as previously defined variables/functions/... as the case may be. * + * The time_literal_state is required because TIME# literals are decomposed into + * portions, and wewant to send these portions one by one to bison. Each poertion will + * represent the value in days/hours/minutes/seconds/ms. + * Unfortunately, some of these portions may also be lexically analysed as an identifier. So, + * we need to disable lexical identification of identifiers while parsing TIME# literals! + * e.g.: TIME#55d_4h_56m + * We would like to return to bison the tokens 'TIME' '#' '55d' '_' '4h' '_' '56m' + * Unfortunately, flex will join '_' and '4h' to create a legal {identifier} '_4h', + * and return that identifier instead! So, we added this state! + * * The state machine has 7 possible states (INITIAL, config, decl, body, st, il, sfc) * Possible state changes are: * INITIAL -> goto(decl_state) @@ -418,7 +434,8 @@ /* we are parsing sfc code, and expecting the priority token. */ %s sfc_priority_state - +/* we are parsing a TIME# literal. We must not return any {identifier} tokens. */ +%x time_literal_state /*******************/ @@ -598,6 +615,15 @@ /* B.1.2.1 Numeric literals */ /******************************/ integer {digit}((_?{digit})*) + +/* Some helper symbols for parsing TIME literals... */ +integer_0_59 (0(_?))*([0-5](_?))?{digit} +integer_0_19 (0(_?))*([0-1](_?))?{digit} +integer_20_23 (0(_?))*2(_?)[0-3] +integer_0_23 {integer_0_19}|{integer_20_23} +integer_0_999 {digit}((_?{digit})?)((_?{digit})?) + + binary_integer 2#{bit}((_?{bit})*) bit [0-1] octal_integer 8#{octal_digit}((_?{octal_digit})*) @@ -673,21 +699,54 @@ /************************/ fixed_point {integer}\.{integer} -fixed_point_d {fixed_point}d -integer_d {integer}d - -fixed_point_h {fixed_point}h -integer_h {integer}h - -fixed_point_m {fixed_point}m -integer_m {integer}m - -fixed_point_s {fixed_point}s -integer_s {integer}s - -fixed_point_ms {fixed_point}ms -integer_ms {integer}ms - + +/* NOTE: The IEC 61131-3 v2 standard has an incorrect formal syntax definition of duration, + * as its definition does not match the standard's text. + * IEC 61131-3 v3 (committee draft) seems to have this fixed, so we use that + * definition instead! + * + * duration::= ('T' | 'TIME') '#' ['+'|'-'] interval + * interval::= days | hours | minutes | seconds | milliseconds + * fixed_point ::= integer [ '.' integer] + * days ::= fixed_point 'd' | integer 'd' ['_'] [ hours ] + * hours ::= fixed_point 'h' | integer 'h' ['_'] [ minutes ] + * minutes ::= fixed_point 'm' | integer 'm' ['_'] [ seconds ] + * seconds ::= fixed_point 's' | integer 's' ['_'] [ milliseconds ] + * milliseconds ::= fixed_point 'ms' + * + * + * The original IEC 61131-3 v2 definition is: + * duration ::= ('T' | 'TIME') '#' ['-'] interval + * interval ::= days | hours | minutes | seconds | milliseconds + * fixed_point ::= integer [ '.' integer] + * days ::= fixed_point 'd' | integer 'd' ['_'] hours + * hours ::= fixed_point 'h' | integer 'h' ['_'] minutes + * minutes ::= fixed_point 'm' | integer 'm' ['_'] seconds + * seconds ::= fixed_point 's' | integer 's' ['_'] milliseconds + * milliseconds ::= fixed_point 'ms' + + */ + +interval_ms_X ({integer_0_999}(\.{integer})?)ms +interval_s_X {integer_0_59}s(_?{interval_ms_X})? +interval_m_X {integer_0_59}m(_?{interval_s_X})? +interval_h_X {integer_0_23}h(_?{interval_m_X})? + +interval_ms {integer}ms|({fixed_point}ms) +interval_s {integer}s(_?{interval_ms_X})?|({fixed_point}s) +interval_m {integer}m(_?{interval_s_X})?|({fixed_point}m) +interval_h {integer}h(_?{interval_m_X})?|({fixed_point}h) +interval_d {integer}d(_?{interval_h_X})?|({fixed_point}d) + +interval {interval_ms}|{interval_s}|{interval_m}|{interval_h}|{interval_d} + +/* to help provide nice error messages, we also parse an incorrect but plausible interval... */ +/* NOTE that this erroneous interval will be parsed outside the time_literal_state, so must not + * be able to parse any other legal lexcial construct (besides a legal interval, but that + * is OK as this rule will appear _after_ the rule to parse legal intervals!). + */ +fixed_point_or_integer {fixed_point}|{integer} +erroneous_interval ({fixed_point_or_integer}d_?)?({fixed_point_or_integer}h_?)?({fixed_point_or_integer}m_?)?({fixed_point_or_integer}s_?)?({fixed_point_or_integer}ms)? /********************************************/ /* B.1.4.1 Directly Represented Variables */ @@ -719,9 +778,9 @@ * in which case we are currently using "%I3" as the variable * name. */ -direct_variable_matplc %{identifier} - -direct_variable {direct_variable_standard}|{direct_variable_matplc} +/* direct_variable_matplc %{identifier} */ +/* direct_variable {direct_variable_standard}|{direct_variable_matplc} */ +direct_variable {direct_variable_standard} /******************************************/ /* B 1.4.3 - Declaration & Initialisation */ @@ -1541,23 +1600,26 @@ /* B 1.2.3.1 - Duration */ /************************/ {fixed_point} {yylval.ID=strdup(yytext); return fixed_point_token;} - -{fixed_point_d} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_d_token;} -{integer_d} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_d_token;} - -{fixed_point_h} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_h_token;} -{integer_h} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_h_token;} - -{fixed_point_m} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_m_token;} -{integer_m} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_m_token;} - -{fixed_point_s} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_s_token;} -{integer_s} {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_s_token;} - -{fixed_point_ms} {yylval.ID=strdup(yytext); yylval.ID[yyleng-2] = '\0'; return fixed_point_ms_token;} -{integer_ms} {yylval.ID=strdup(yytext); yylval.ID[yyleng-2] = '\0'; return integer_ms_token;} - - +{interval} {/*fprintf(stderr, "entering time_literal_state ##%s##\n", yytext);*/ unput_and_mark('#'); yy_push_state(time_literal_state);} +{erroneous_interval} {return erroneous_interval_token;} + +{ +{integer}d {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_d_token;} +{integer}h {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_h_token;} +{integer}m {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_m_token;} +{integer}s {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return integer_s_token;} +{integer}ms {yylval.ID=strdup(yytext); yylval.ID[yyleng-2] = '\0'; return integer_ms_token;} +{fixed_point}d {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_d_token;} +{fixed_point}h {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_h_token;} +{fixed_point}m {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_m_token;} +{fixed_point}s {yylval.ID=strdup(yytext); yylval.ID[yyleng-1] = '\0'; return fixed_point_s_token;} +{fixed_point}ms {yylval.ID=strdup(yytext); yylval.ID[yyleng-2] = '\0'; return fixed_point_ms_token;} + +_ /* do nothing - eat it up!*/ +\# {/*fprintf(stderr, "poping from time_literal_state (###)\n");*/ yy_pop_state(); return end_interval_token;} +. {ERROR;} +\n {ERROR;} +} /*******************************/ /* B.1.2.2 Character Strings */ /*******************************/ @@ -1645,6 +1707,20 @@ } +/* return all the text in the current token back to the input stream, + * but first return to the stream an additional character to mark the end of the token. + */ +void unput_and_mark(const char c) { + char *yycopy = strdup( yytext ); /* unput() destroys yytext, so we copy it first */ + unput(c); + for (int i = yyleng-1; i >= 0; i--) + unput(yycopy[i]); + + free(yycopy); +} + + + /* Called by flex when it reaches the end-of-file */ int yywrap(void) { diff -r 8cc4c51c4bfc -r dab341e80664 stage4/generate_c/generate_c.cc --- a/stage4/generate_c/generate_c.cc Wed May 09 22:59:10 2012 +0100 +++ b/stage4/generate_c/generate_c.cc Wed May 09 23:00:10 2012 +0100 @@ -353,6 +353,10 @@ unsigned long long get_time(void) {return time;}; + /* NOTE: we should really remove this function, and replace it with extract_integer_value() (in absyntax_utils.h) + * but right now I don't want to spend time checking if this change will introduce some conversion bug + * since it returns a long long, and not a float! + */ void *get_integer_value(token_c *token) { std::string str = ""; for (unsigned int i = 0; i < strlen(token->value); i++) @@ -362,6 +366,10 @@ return NULL; } + /* NOTE: this function is incomplete, as it should also be removing '_' inserted into the literal, + * but we leave it for now. + * In truth, we should really have an extract_real_value() in absyntax_util.h !!! + */ void *get_float_value(token_c *token) { current_value = atof(token->value); return NULL; @@ -388,48 +396,31 @@ /* SYM_TOKEN(fixed_point_c) */ void *visit(fixed_point_c *symbol) {return get_float_value(symbol);} - /* SYM_REF2(days_c, days, hours) */ - void *visit(days_c *symbol) { - if (symbol->hours) - symbol->hours->accept(*this); - symbol->days->accept(*this); - time += (unsigned long long)(current_value * 24 * 3600 * SECOND); - return NULL; - } - - /* SYM_REF2(hours_c, hours, minutes) */ - void *visit(hours_c *symbol) { - if (symbol->minutes) - symbol->minutes->accept(*this); - symbol->hours->accept(*this); - time += (unsigned long long)(current_value * 3600 * SECOND); - return NULL; - } - - /* SYM_REF2(minutes_c, minutes, seconds) */ - void *visit(minutes_c *symbol) { - if (symbol->seconds) - symbol->seconds->accept(*this); - symbol->minutes->accept(*this); + + /* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ + void *visit(interval_c *symbol) { + current_value = 0; + if (NULL != symbol->milliseconds) symbol->milliseconds->accept(*this); + time += (unsigned long long)(current_value * MILLISECOND); + + current_value = 0; + if (NULL != symbol->seconds) symbol->seconds->accept(*this); + time += (unsigned long long)(current_value * SECOND); + + current_value = 0; + if (NULL != symbol->minutes) symbol->minutes->accept(*this); time += (unsigned long long)(current_value * 60 * SECOND); - return NULL; - } - - /* SYM_REF2(seconds_c, seconds, milliseconds) */ - void *visit(seconds_c *symbol) { - if (symbol->milliseconds) - symbol->milliseconds->accept(*this); - symbol->seconds->accept(*this); - time += (unsigned long long)(current_value * SECOND); - return NULL; - } - - /* SYM_REF2(milliseconds_c, milliseconds, unused) */ - void *visit(milliseconds_c *symbol) { - symbol->milliseconds->accept(*this); - time += (unsigned long long)(current_value * MILLISECOND); - return NULL; - } + + current_value = 0; + if (NULL != symbol->hours) symbol->hours->accept(*this); + time += (unsigned long long)(current_value * 60 * 60 * SECOND); + + current_value = 0; + if (NULL != symbol->days) symbol->days->accept(*this); + time += (unsigned long long)(current_value * 60 * 60 * 24 * SECOND); + + return NULL; + } }; /***********************************************************************/ @@ -791,7 +782,7 @@ /* signed_integer DOTDOT signed_integer */ //SYM_REF2(subrange_c, lower_limit, upper_limit) void *visit(subrange_c *symbol) { - int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + int dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1; switch (current_mode) { case arrayname_im: current_array_name += "_"; diff -r 8cc4c51c4bfc -r dab341e80664 stage4/generate_c/generate_c_base.cc --- a/stage4/generate_c/generate_c_base.cc Wed May 09 22:59:10 2012 +0100 +++ b/stage4/generate_c/generate_c_base.cc Wed May 09 23:00:10 2012 +0100 @@ -410,18 +410,12 @@ void *visit(duration_c *symbol) { TRACE("duration_c"); s4o.print("__time_to_timespec("); - if (NULL == symbol->neg) - s4o.print("1"); /* positive time value */ - else - symbol->neg->accept(*this); /* this will print '-1' :-) */ - - s4o.print(", "); - + + if (NULL == symbol->neg) s4o.print("1"); /* positive time value */ + else symbol->neg->accept(*this); /* this will print '-1' :-) */ + + s4o.print(", "); symbol->interval->accept(*this); - if (typeid(*symbol->interval) == typeid(hours_c)) {s4o.print(", 0");} - if (typeid(*symbol->interval) == typeid(minutes_c)) {s4o.print(", 0, 0");} - if (typeid(*symbol->interval) == typeid(seconds_c)) {s4o.print(", 0, 0, 0");} - if (typeid(*symbol->interval) == typeid(milliseconds_c)) {s4o.print(", 0, 0, 0, 0");} s4o.print(")"); return NULL; } @@ -430,73 +424,32 @@ /* SYM_TOKEN(fixed_point_c) */ void *visit(fixed_point_c *symbol) {return print_striped_token(symbol);} - -/* SYM_REF2(days_c, days, hours) */ -void *visit(days_c *symbol) { - TRACE("days_c"); - if (NULL == symbol->hours) - s4o.print("0, 0, 0, 0"); /* milliseconds, seconds, minutes, hours */ - else - symbol->hours->accept(*this); - - s4o.print(", "); - - symbol->days->accept(*this); - return NULL; -} - - -/* SYM_REF2(hours_c, hours, minutes) */ -void *visit(hours_c *symbol) { - TRACE("hours_c"); - if (NULL == symbol->minutes) - s4o.print("0, 0, 0"); /* milliseconds, seconds, minutes */ - else - symbol->minutes->accept(*this); - - s4o.print(", "); - - symbol->hours->accept(*this); - return NULL; -} - - -/* SYM_REF2(minutes_c, minutes, seconds) */ -void *visit(minutes_c *symbol) { - TRACE("minutes_c"); - if (NULL == symbol->seconds) - s4o.print("0, 0"); /* milliseconds, seconds */ - else - symbol->seconds->accept(*this); - - s4o.print(", "); - - symbol->minutes->accept(*this); - return NULL; -} - - -/* SYM_REF2(seconds_c, seconds, milliseconds) */ -void *visit(seconds_c *symbol) { - TRACE("seconds_c"); - if (NULL == symbol->milliseconds) - s4o.print("0"); /* milliseconds */ - else - symbol->milliseconds->accept(*this); - - s4o.print(", "); - - symbol->seconds->accept(*this); - return NULL; -} - - -/* SYM_REF2(milliseconds_c, milliseconds, unused) */ -void *visit(milliseconds_c *symbol) { - TRACE("milliseconds_c"); - symbol->milliseconds->accept(*this); - return NULL; -} +/* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ +void *visit(interval_c *symbol) { + TRACE("interval_c"); + /* s4o.print("0, 0, 0, 0, 0"); // milliseconds, seconds, minutes, hours, days */ + if (NULL == symbol->milliseconds) s4o.print("0"); /* milliseconds */ + else symbol->milliseconds->accept(*this); + s4o.print(", "); + + if (NULL == symbol->seconds) s4o.print("0"); /* seconds */ + else symbol->seconds->accept(*this); + s4o.print(", "); + + if (NULL == symbol->minutes) s4o.print("0"); /* minutes */ + else symbol->minutes->accept(*this); + s4o.print(", "); + + if (NULL == symbol->hours) s4o.print("0"); /* hours */ + else symbol->hours->accept(*this); + s4o.print(", "); + + if (NULL == symbol->days) s4o.print("0"); /* days */ + else symbol->days->accept(*this); + + return NULL; +} + /************************************/ /* B 1.2.3.2 - Time of day and Date */ diff -r 8cc4c51c4bfc -r dab341e80664 stage4/generate_c/generate_c_typedecl.cc --- a/stage4/generate_c/generate_c_typedecl.cc Wed May 09 22:59:10 2012 +0100 +++ b/stage4/generate_c/generate_c_typedecl.cc Wed May 09 23:00:10 2012 +0100 @@ -255,7 +255,7 @@ case array_td: if (current_basetypedeclaration == arraysubrange_bd) { s4o_incl.print("["); - dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1; print_integer_incl(dimension); s4o_incl.print("]"); } diff -r 8cc4c51c4bfc -r dab341e80664 stage4/generate_c/generate_c_vardecl.cc --- a/stage4/generate_c/generate_c_vardecl.cc Wed May 09 22:59:10 2012 +0100 +++ b/stage4/generate_c/generate_c_vardecl.cc Wed May 09 23:00:10 2012 +0100 @@ -211,7 +211,7 @@ /* signed_integer DOTDOT signed_integer */ //SYM_REF2(subrange_c, lower_limit, upper_limit) void *visit(subrange_c *symbol) { - int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + int dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1; switch (current_mode) { case arraysize_am: array_size *= dimension; @@ -264,7 +264,7 @@ switch (current_mode) { case initializationvalue_am: - initial_element_number = extract_integer(symbol->integer); + initial_element_number = extract_integer_value(symbol->integer); if (current_initialization_count < defined_values_count) { int temp_element_number = 0; int diff = defined_values_count - current_initialization_count; @@ -1407,7 +1407,7 @@ /* signed_integer DOTDOT signed_integer */ //SYM_REF2(subrange_c, lower_limit, upper_limit) void *visit(subrange_c *symbol) { - int dimension = extract_integer(symbol->upper_limit) - extract_integer(symbol->lower_limit) + 1; + long long dimension = extract_integer_value(symbol->upper_limit) - extract_integer_value(symbol->lower_limit) + 1; s4o.print("_"); print_integer(dimension); return NULL; diff -r 8cc4c51c4bfc -r dab341e80664 stage4/generate_iec/generate_iec.cc --- a/stage4/generate_iec/generate_iec.cc Wed May 09 22:59:10 2012 +0100 +++ b/stage4/generate_iec/generate_iec.cc Wed May 09 23:00:10 2012 +0100 @@ -234,43 +234,37 @@ void *visit(fixed_point_c *symbol) {return print_token(symbol);} -void *visit(days_c *symbol) { - symbol->days->accept(*this); - s4o.print("d"); - if (symbol->hours != NULL) +/* SYM_REF5(interval_c, days, hours, minutes, seconds, milliseconds) */ +void *visit(interval_c *symbol) { + if (NULL != symbol->days) { + symbol->days->accept(*this); + s4o.print("d"); + } + + if (NULL != symbol->hours) { symbol->hours->accept(*this); - return NULL; -} - -void *visit(hours_c *symbol) { - symbol->hours->accept(*this); - s4o.print("h"); - if (symbol->minutes != NULL) + s4o.print("h"); + } + + if (NULL != symbol->minutes) { symbol->minutes->accept(*this); - return NULL; -} - -void *visit(minutes_c *symbol) { - symbol->minutes->accept(*this); - s4o.print("m"); - if (symbol->seconds != NULL) + s4o.print("m"); + } + + if (NULL != symbol->seconds) { symbol->seconds->accept(*this); - return NULL; -} - -void *visit(seconds_c *symbol) { - symbol->seconds->accept(*this); - s4o.print("s"); - if (symbol->milliseconds != NULL) + s4o.print("s"); + } + + if (NULL != symbol->milliseconds) { symbol->milliseconds->accept(*this); - return NULL; -} - -void *visit(milliseconds_c *symbol) { - symbol->milliseconds->accept(*this); - s4o.print("ms"); - return NULL; -} + s4o.print("ms"); + } + + return NULL; +} + + /************************************/ /* B 1.2.3.2 - Time of day and Date */