Allow use of type#value syntax when defining default initial value inside a TYPE..END_TYPE declaration.
authorMario de Sousa <msousa@fe.up.pt>
Thu, 15 Nov 2012 14:14:00 +0000
changeset 734 49853bded539
parent 733 246b4ef78da6
child 735 0304ff59fd7f
child 745 26cb3fa00d29
Allow use of type#value syntax when defining default initial value inside a TYPE..END_TYPE declaration.
stage1_2/iec_bison.yy
--- a/stage1_2/iec_bison.yy	Thu Nov 15 12:57:04 2012 +0000
+++ b/stage1_2/iec_bison.yy	Thu Nov 15 14:14:00 2012 +0000
@@ -2549,10 +2549,13 @@
 
 simple_type_declaration:
 /*  simple_type_name ':' simple_spec_init */
-  identifier ':' simple_spec_init
-	{$$ = new simple_type_declaration_c($1, $3, locloc(@$));
-	 library_element_symtable.insert($1, prev_declared_simple_type_name_token);
-	}
+/* To understand why simple_spec_init was brocken up into its consituent components in the following rules, please see note in the definition of 'enumerated_type_declaration'. */
+  identifier ':' simple_specification           {library_element_symtable.insert($1, prev_declared_simple_type_name_token);}
+	{$$ = new simple_type_declaration_c($1, $3, locloc(@$));}
+| identifier ':' elementary_type_name           {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant
+	{$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));}
+| identifier ':' prev_declared_simple_type_name {library_element_symtable.insert($1, prev_declared_simple_type_name_token);} ASSIGN constant
+	{$$ = new simple_type_declaration_c($1, new simple_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | error ':' simple_spec_init
 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for data type declaration.");yyerrok;}
@@ -2687,10 +2690,23 @@
 
 enumerated_type_declaration:
 /*  enumerated_type_name ':' enumerated_spec_init */
-  identifier ':' enumerated_spec_init
-	{$$ = new enumerated_type_declaration_c($1, $3, locloc(@$));
-	 library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);
-	}
+/* NOTE: The 'identifier' used for the name of the new enumerated type is inserted early into the library_element_symtable so it may be used
+ *       in defining the default initial value of this type, using the fully qualified enumerated constant syntax: type_name#enum_value
+ *       In other words, this allows us to correclty parse the following IEC 61131-3 code:
+ *           TYPE enum_t : (x1, x2, x3) := enum_t#x3; END_TYPE
+ *                                         ^^^^^^^
+ *
+ *       However, we can only introduce it after we are sure we are parsing an enumerated_spec. For this reason, instead of using the
+ *       symbol enumerated_spec_init in this rule, we decompose it here instead!
+ *       
+ *       If it were not for the above, we could use the rule
+ *           identifier ':' enumerated_spec_init
+ *       and include the library_element_symtable.insert(...) code in the rule actions!
+ */
+  identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);}
+	{$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, NULL, locloc(@3)), locloc(@$));}
+| identifier ':' enumerated_specification {library_element_symtable.insert($1, prev_declared_enumerated_type_name_token);} ASSIGN enumerated_value
+	{$$ = new enumerated_type_declaration_c($1, new enumerated_spec_init_c($3, $6, locf(@3), locl(@6)), locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | error ':' enumerated_spec_init
 	{$$ = NULL; print_err_msg(locf(@1), locl(@1), "invalid name defined for enumerated type declaration."); yyerrok;}