# HG changeset patch # User mario # Date 1195026865 -3600 # Node ID a6e651ba55c2d6f108dba4659b2312dfeec5a0a8 # Parent a74c279f0a2ebfe69ca192410b3de32cb88211ca Fixing handling of enumeration values; Adding syntax check in formal and non-formal FB invocations Cleaning up some rules. diff -r a74c279f0a2e -r a6e651ba55c2 stage1_2/iec.y --- a/stage1_2/iec.y Sat Nov 10 07:12:12 2007 +0100 +++ b/stage1_2/iec.y Wed Nov 14 08:54:25 2007 +0100 @@ -561,7 +561,7 @@ /* helper symbol for enumerated_value */ %type enumerated_value_list %type enumerated_value -%type enumerated_value_without_identifier +//%type enumerated_value_without_identifier %type array_type_declaration %type array_spec_init @@ -835,10 +835,7 @@ %type transition %type steps %type step_name_list -%type transition_header -%type transition_condition_il -%type transition_condition_st -%type action_header +%type transition_condition %type action %type transition_name @@ -1174,9 +1171,12 @@ %type subprogram_control_statement %type return_statement %type fb_invocation -%type param_assignment -/* helper symbol for fb_invocation */ -%type param_assignment_list +// %type param_assignment +%type param_assignment_formal +%type param_assignment_nonformal +/* helper symbols for fb_invocation */ +%type param_assignment_formal_list +%type param_assignment_nonformal_list // %token ASSIGN // %token SENDTO /* "=>" */ @@ -2287,16 +2287,18 @@ enumerated_value: - identifier + identifier | prev_declared_enumerated_type_name '#' any_identifier {$$ = new enumerated_value_c($1, $3, locloc(@$));} ; +/* enumerated_value_without_identifier: prev_declared_enumerated_type_name '#' any_identifier {$$ = new enumerated_value_c($1, $3, locloc(@$));} ; +*/ array_type_declaration: @@ -3772,49 +3774,49 @@ ; -transition_header: - TRANSITION FROM steps TO steps - {$$.first = NULL; $$.second = NULL; $$.third = $3; $$.fourth = $5; cmd_goto_body_state();} -| TRANSITION transition_name FROM steps TO steps -//| TRANSITION identifier FROM steps TO steps - {$$.first = $2; $$.second = NULL; $$.third = $4; $$.fourth = $6; cmd_goto_body_state();} -| TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps - {$$.first = NULL; $$.second = $5; $$.third = $8; $$.fourth = $10; cmd_goto_body_state();} -| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps -//| TRANSITION identifier '(' PRIORITY ASSIGN integer ')' FROM steps TO steps - {$$.first = $2; $$.second = $6; $$.third = $9; $$.fourth = $11; cmd_goto_body_state();} -; - -transition_condition_il: +/* NOTE: flex will automatically pop() out of body_state to previous state. + * We do not need to give a command from bison to return to previous flex state! + */ +transition: + TRANSITION + FROM steps TO steps + {cmd_goto_body_state();} transition_condition + END_TRANSITION + {$$ = new transition_c(NULL, NULL, $3, $5, $7, NULL, locloc(@$));} +//| TRANSITION identifier FROM steps TO steps ... +| TRANSITION transition_name + FROM steps TO steps + {cmd_goto_body_state();} transition_condition + END_TRANSITION + {$$ = new transition_c($2, NULL, $4, $6, $8, NULL, locloc(@$));} +| TRANSITION '(' PRIORITY ASSIGN integer ')' + FROM steps TO steps + {cmd_goto_body_state();} transition_condition + END_TRANSITION + {$$ = new transition_c(NULL, $5, $8, $10, $12, NULL, locloc(@$));} +//| TRANSITION identifier '(' PRIORITY ASSIGN integer ')' FROM steps TO steps ... +| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' + FROM steps TO steps + {cmd_goto_body_state();} transition_condition + END_TRANSITION + {$$ = new transition_c($2, $6, $9, $11, $13, NULL, locloc(@$));} +; + + + +transition_condition: ':' eol_list simple_instr_list {$$ = $3;} -; - -transition_condition_st: - ASSIGN expression ';' +| ASSIGN expression ';' {$$ = $2} ; -/* TODO: Can't we clean this up a bit ? */ -transition: - transition_header transition_condition_il END_TRANSITION - {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, $2, NULL, locloc(@$));} - /* TODO: free the memory used up by the no longer used object $1 */ -| transition_header transition_condition_st END_TRANSITION - {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, NULL, $2, locloc(@$));} -; - -action_header: - ACTION action_name ':' -// ACTION identifier ':' - {$$.first = $2; cmd_goto_body_state();} -; - action: - action_header function_block_body END_ACTION - {$$ = new action_c($1.first, $2, locloc(@$));} +// ACTION identifier ':' ... + ACTION action_name ':' {cmd_goto_body_state();} function_block_body END_ACTION + {$$ = new action_c($2, $5, locloc(@$));} ; @@ -3903,7 +3905,7 @@ {$$ = new configuration_declaration_c($2, $3, $4, $5, $6, locloc(@$)); library_element_symtable.insert($2, prev_declared_configuration_name_token); variable_name_symtable.pop(); - } +} /* ERROR_CHECK_BEGIN */ | CONFIGURATION error END_CONFIGURATION {$$ = NULL; @@ -4560,7 +4562,8 @@ */ il_operand: variable -| enumerated_value_without_identifier +//| enumerated_value_without_identifier +| enumerated_value | constant ; @@ -4937,14 +4940,16 @@ * identifier to a variable or an enumerated_value. * * This change follows the IEC specification. The specification seems to - * imply (or is it explicit?) that in case the same identifier id used + * imply (by introducing syntax that allows to unambiguosly reference an + * enumerated value - enum_type#enum_value) that in case the same identifier is used * for a variable and an enumerated value, then the variable shall be - * considered?????????????? + * considered. */ primary_expression: /* constant */ non_negative_constant -| enumerated_value_without_identifier +//| enumerated_value_without_identifier +| enumerated_value | variable | '(' expression ')' {$$ = $2;} @@ -4979,8 +4984,10 @@ * letting names clash! */ function_invocation: -/* function_name '(' param_assignment_list ')' */ - function_name_no_NOT_clashes '(' param_assignment_list ')' +/* function_name '(' [param_assignment_list] ')' */ + function_name_no_NOT_clashes '(' param_assignment_formal_list ')' + {$$ = new function_invocation_c($1, $3, locloc(@$));} +| function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')' {$$ = new function_invocation_c($1, $3, locloc(@$));} ; @@ -5045,7 +5052,9 @@ fb_invocation: prev_declared_fb_name '(' ')' {$$ = new fb_invocation_c($1, NULL, locloc(@$)); } -| prev_declared_fb_name '(' param_assignment_list ')' +| prev_declared_fb_name '(' param_assignment_formal_list ')' + {$$ = new fb_invocation_c($1, $3, locloc(@$));} +| prev_declared_fb_name '(' param_assignment_nonformal_list ')' {$$ = new fb_invocation_c($1, $3, locloc(@$));} ; @@ -5054,25 +5063,65 @@ * - fb_invocation * - function_invocation */ -param_assignment_list: - param_assignment +param_assignment_formal_list: + param_assignment_formal {$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);} -| param_assignment_list ',' param_assignment +| param_assignment_formal_list ',' param_assignment_formal {$$ = $1; $$->add_element($3);} ; - - +/* helper symbol for + * - fb_invocation + * - function_invocation + */ +param_assignment_nonformal_list: + param_assignment_nonformal + {$$ = new param_assignment_list_c(locloc(@$)); $$->add_element($1);} +| param_assignment_nonformal_list ',' param_assignment_nonformal + {$$ = $1; $$->add_element($3);} +; + + +/* NOTE: According to the IEC 61131-3 standard, there are two possible + * syntaxes for calling function blocks within ST. + * The formal method has the form: + * fb ( invar := x, inoutvar := var1, outvar => var2); + * The non-formal method has the form: + * fb (x, var1, var2); + * In the text of IEC 61131-3 (where the semantics are defined), + * it is obvious that mixing the two syntaxes is considered incorrect. + * The following should therefore be incorrect: + * fb ( invar := x, var1, var2); + * However, according to the syntax definition, as defined in IEC 61131-3, + * mixing the formal and non-formal methods of invocation is allowed. + * We have two alternatives: + * (a) implement the syntax here in iec.y according to the standard, + * and leave it to the semantic analyser stage to find this error + * (b) or implement the syntax in iec.y correctly, not allowing + * the mixing of formal and non-formal invocation syntaxes. + * Considering that this is a syntax issue, and not semantic issue, + * I (Mario) have decided to go with alternative (a). + * In other words, in iec.y we do not follow the syntax as defined in + * Annex B of the IEC 61131-3 standard, but rather implement + * the syntax also taking into account the textual part of the standard too. + */ +/* param_assignment: -/* variable_name ASSIGN expression */ + variable_name ASSIGN expression +*/ +param_assignment_nonformal: + expression +; + + +param_assignment_formal: any_identifier ASSIGN expression {$$ = new input_variable_param_assignment_c($1, $3, locloc(@$));} -| expression /*| variable_name SENDTO variable */ /*| any_identifier SENDTO variable */ | sendto_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(NULL,$1, $3, locloc(@$));} -/*| variable_name SENDTO variable */ +/*| NOT variable_name SENDTO variable */ /*| NOT any_identifier SENDTO variable*/ | NOT sendto_identifier SENDTO variable {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)),$2, $4, locloc(@$));} @@ -5453,8 +5502,12 @@ yylineno = 1; allow_function_overloading = false; current_filename = filename; - if (yyparse() != 0) - exit(EXIT_FAILURE); + {int res; + if ((res = yyparse()) != 0) { + fprintf (stderr, "\nInternal error while parsing file - yyparse() returned %d. Bailing out!\n", res); + ERROR; + } + } if (yynerrs > 0) { fprintf (stderr, "\nFound %d error(s). Bailing out!\n", yynerrs /* global variable */);