Fixing handling of enumeration values;
authormario
Wed, 14 Nov 2007 08:54:25 +0100
changeset 85 a6e651ba55c2
parent 84 a74c279f0a2e
child 86 1988bf1634da
Fixing handling of enumeration values;
Adding syntax check in formal and non-formal FB invocations
Cleaning up some rules.
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  <list>	enumerated_value_list
 %type  <leaf>	enumerated_value
-%type  <leaf>	enumerated_value_without_identifier
+//%type  <leaf>	enumerated_value_without_identifier
 
 %type  <leaf>	array_type_declaration
 %type  <leaf>	array_spec_init
@@ -835,10 +835,7 @@
 %type  <leaf>	transition
 %type  <leaf>	steps
 %type  <list>	step_name_list
-%type  <tmp_symbol> transition_header
-%type  <leaf>	transition_condition_il
-%type  <leaf>	transition_condition_st
-%type  <tmp_symbol> action_header
+%type  <leaf>	transition_condition
 %type  <leaf>	action
 %type  <leaf>	transition_name
 
@@ -1174,9 +1171,12 @@
 %type <leaf>	subprogram_control_statement
 %type <leaf>	return_statement
 %type <leaf>	fb_invocation
-%type <leaf>	param_assignment
-/* helper symbol for fb_invocation */
-%type <list> param_assignment_list
+// %type <leaf>	param_assignment
+%type <leaf>	param_assignment_formal
+%type <leaf>	param_assignment_nonformal
+/* helper symbols for fb_invocation */
+%type <list> param_assignment_formal_list
+%type <list> 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 */);