stage1_2/iec_bison.yy
changeset 932 061824c45a5b
parent 924 9e824bb0c3d4
child 933 76324f461aed
equal deleted inserted replaced
931:c0c245197b5a 932:061824c45a5b
   196  * This is an extension to the standard syntax.
   196  * This is an extension to the standard syntax.
   197  * See comments below for details why we support this!
   197  * See comments below for details why we support this!
   198  */
   198  */
   199 extern bool allow_extensible_function_parameters;
   199 extern bool allow_extensible_function_parameters;
   200 
   200 
   201 /* A global flag used to tell the parser whether to include the full variable location
   201 /* A global flag used to tell the parser whether to include the full variable location when printing out error messages... */
   202  * when printing out error messages...
       
   203  */
       
   204 extern bool full_token_loc;
   202 extern bool full_token_loc;
   205 
   203 
   206 /* A global flag used to tell the parser whether to generate conversion function
   204 /* A global flag used to tell the parser whether to generate conversion function for enumerated data types. */
   207  * for enumerated data types.
       
   208  */
       
   209 extern bool conversion_functions_;
   205 extern bool conversion_functions_;
   210 
   206 
   211 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */
   207 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */
   212 extern bool allow_ref_to_any;
   208 extern bool allow_ref_to_any;
   213 
   209 
   214 /* A pointer to the root of the parsing tree that will be generated 
   210 /* A global flag used to tell the parser whether to allow use of REF_TO as a struct or array element (non-standard extension) */
   215  * by bison.
   211 extern bool allow_ref_to_in_derived_datatypes;
   216  */
   212 
       
   213 /* A pointer to the root of the parsing tree that will be generated  by bison. */
   217 extern symbol_c *tree_root;
   214 extern symbol_c *tree_root;
   218 
   215 
   219 
   216 
   220 
   217 
   221 /************************/
   218 /************************/
   783 %token OF
   780 %token OF
   784 %token STRUCT
   781 %token STRUCT
   785 %token END_STRUCT
   782 %token END_STRUCT
   786 
   783 
   787 
   784 
   788 %type  <leaf>	ref_spec      /* defined in IEC 61131-3 v3 */
   785 %type  <leaf>	ref_spec                 /* defined in IEC 61131-3 v3 */
   789 %type  <leaf>	ref_spec_init /* defined in IEC 61131-3 v3 */
   786 %type  <leaf>	ref_spec_non_recursive   /* helper symbol */
   790 %type  <leaf>	ref_type_decl /* defined in IEC 61131-3 v3 */
   787 %type  <leaf>	ref_spec_init            /* defined in IEC 61131-3 v3 */
       
   788 %type  <leaf>	ref_type_decl            /* defined in IEC 61131-3 v3 */
   791 
   789 
   792 
   790 
   793 
   791 
   794 /*********************/
   792 /*********************/
   795 /* B 1.4 - Variables */
   793 /* B 1.4 - Variables */
  2876 
  2874 
  2877 array_specification:
  2875 array_specification:
  2878   prev_declared_array_type_name
  2876   prev_declared_array_type_name
  2879 | ARRAY '[' array_subrange_list ']' OF non_generic_type_name
  2877 | ARRAY '[' array_subrange_list ']' OF non_generic_type_name
  2880 	{$$ = new array_specification_c($3, $6, locloc(@$));}
  2878 	{$$ = new array_specification_c($3, $6, locloc(@$));}
       
  2879 | ARRAY '[' array_subrange_list ']' OF ref_spec_non_recursive
       
  2880 	/* non standard extension: Allow use of arrays storing REF_TO datatypes that are declared as 'ARRAY [1..3] OF REF_TO INT' */
       
  2881 	/*                                                                                                            ^^^^^^      */
       
  2882 	/* NOTE: We use ref_spec and not ref_spec_init as for the moment I do not want to allow direct specification of initial value.
       
  2883 	 *       I (MJS) am not too sure whether this is currently supported in code generation, so leave it out for now.
       
  2884 	 *       It also does not seem to be a very good idea to allow initial value specification when declaring the array,
       
  2885 	 *       since the standard syntax does not allow it either for any other datatype!
       
  2886 	 * NOTE: We use ref_spec_non_recursive instead of ref_spec in order to remove a reduce/reduce conflict.
       
  2887 	 *       Note that non_generic_type_name that is used in the previous rule already include the prev_declared_ref_type_name.
       
  2888 	 *       which leads to the reduce/reduce conflict, as it is also included in ref_spec.
       
  2889 	 */
       
  2890 	{$$ = new array_specification_c($3, $6, locloc(@$));
       
  2891 	 if (!allow_ref_to_in_derived_datatypes) {
       
  2892 	   print_err_msg(locf(@$), locl(@$), "REF_TO may not be used in an ARRAY specification (use -R option to activate support for this non-standard syntax)."); 
       
  2893 	   yynerrs++;
       
  2894 	 }
       
  2895 	}
  2881 /* ERROR_CHECK_BEGIN */
  2896 /* ERROR_CHECK_BEGIN */
  2882 | ARRAY array_subrange_list ']' OF non_generic_type_name
  2897 | ARRAY array_subrange_list ']' OF non_generic_type_name
  2883 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'[' missing before subrange list in array specification."); yynerrs++;}
  2898 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'[' missing before subrange list in array specification."); yynerrs++;}
  2884 | ARRAY '[' ']' OF non_generic_type_name
  2899 | ARRAY '[' ']' OF non_generic_type_name
  2885 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange list defined in array specification."); yynerrs++;}
  2900 	{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no subrange list defined in array specification."); yynerrs++;}
  3063 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
  3078 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
  3064 | structure_element_name ':' array_spec_init
  3079 | structure_element_name ':' array_spec_init
  3065 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
  3080 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
  3066 | structure_element_name ':' initialized_structure
  3081 | structure_element_name ':' initialized_structure
  3067 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
  3082 	{$$ = new structure_element_declaration_c($1, $3, locloc(@$));}
       
  3083 | structure_element_name ':' ref_spec_init                              /* non standard extension: Allow use of struct elements storing REF_TO datatypes (either using REF_TO or a previosuly declared ref type) */
       
  3084 	{ $$ = new structure_element_declaration_c($1, $3, locloc(@$));
       
  3085 	  if (!allow_ref_to_in_derived_datatypes) {
       
  3086 	    print_err_msg(locf(@$), locl(@$), "REF_TO and reference datatypes may not be used in a STRUCT element (use -R option to activate support for this non-standard syntax)."); 
       
  3087 	    yynerrs++;
       
  3088 	  }
       
  3089 	}
  3068 /* ERROR_CHECK_BEGIN */
  3090 /* ERROR_CHECK_BEGIN */
  3069 | structure_element_name simple_spec_init
  3091 | structure_element_name simple_spec_init
  3070 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and simple specification."); yynerrs++;}
  3092 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and simple specification."); yynerrs++;}
  3071 | structure_element_name subrange_spec_init
  3093 | structure_element_name subrange_spec_init
  3072 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and subrange specification."); yynerrs++;}
  3094 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "':' missing between structure element name and subrange specification."); yynerrs++;}
  3218 /* NOTE: in IEC 61131-3 v3, the formal syntax definition does not define non_generic_type_name to include FB type names.
  3240 /* NOTE: in IEC 61131-3 v3, the formal syntax definition does not define non_generic_type_name to include FB type names.
  3219  *       However, in section "6.3.4.10 References", example 4 includes a  REF_TO a FB type!
  3241  *       However, in section "6.3.4.10 References", example 4 includes a  REF_TO a FB type!
  3220  *       We have therefore explicitly added the "REF_TO function_block_type_name" to this rule!
  3242  *       We have therefore explicitly added the "REF_TO function_block_type_name" to this rule!
  3221  * NOTE: the REF_TO ANY is a non-standard extension to the standard. This is basically equivalent to a (void *)
  3243  * NOTE: the REF_TO ANY is a non-standard extension to the standard. This is basically equivalent to a (void *)
  3222  */
  3244  */
  3223 ref_spec: /* defined in IEC 61131-3 v3 */
  3245 ref_spec_non_recursive: /* helper symbol, used to remove a reduce/reduce conflict in a non-standard syntax I (Mario) have added!! */
  3224   REF_TO non_generic_type_name
  3246   REF_TO non_generic_type_name
  3225 	{$$ = new ref_spec_c($2, locloc(@$));}
  3247 	{$$ = new ref_spec_c($2, locloc(@$));}
  3226 | REF_TO function_block_type_name
  3248 | REF_TO function_block_type_name
  3227 	{$$ = new ref_spec_c($2, locloc(@$));}
  3249 	{$$ = new ref_spec_c($2, locloc(@$));}
  3228 | REF_TO ANY
  3250 | REF_TO ANY
  3230 	 if (!allow_ref_to_any) {
  3252 	 if (!allow_ref_to_any) {
  3231 	   print_err_msg(locf(@$), locl(@$), "REF_TO ANY datatypes are not allowed (use -R option to activate support for this non-standard syntax)."); 
  3253 	   print_err_msg(locf(@$), locl(@$), "REF_TO ANY datatypes are not allowed (use -R option to activate support for this non-standard syntax)."); 
  3232 	   yynerrs++;
  3254 	   yynerrs++;
  3233 	 }
  3255 	 }
  3234 	}
  3256 	}
  3235 /* The following line is actually not included in IEC 61131-3, but we add it anyway otherwise it will not be possible to
  3257 ;
  3236  * define a REF_TO datatype as an alias to an already previously declared REF_TO datatype.
  3258 
       
  3259 ref_spec: /* defined in IEC 61131-3 v3 */
       
  3260   ref_spec_non_recursive
       
  3261 | prev_declared_ref_type_name 
       
  3262 ;
       
  3263 
       
  3264 
       
  3265 /* The IEC 61131-3 v3 standard actually only defines the following syntax:
       
  3266  * 
       
  3267  *  Ref_Type_Decl: Ref_Type_Name ':' Ref_Spec_Init;
       
  3268  *  Ref_Spec_Init: Ref_Spec ( ':=' Ref_Value )?;
       
  3269  *  Ref_Spec     : 'REF_TO' + Data_Type_Access;
       
  3270  *
       
  3271  * Note that the above syntax it is not possible to define a REF_TO datatype as 
       
  3272  * an alias to an already previously declared REF_TO datatype.
       
  3273  *
       
  3274  * I (Mario) believe that this is probably a bug in the IEC 61131-3 syntax, and I have therefore
       
  3275  * changed that standard definition to...
       
  3276  *
       
  3277  *  Ref_Type_Decl: Ref_Type_Name ':' Ref_Spec_Init;
       
  3278  *  Ref_Spec_Init: Ref_Spec ( ':=' Ref_Value )?;
       
  3279  *  Ref_Spec     : ('REF_TO' + Data_Type_Access) | Ref_Type_Name;
       
  3280  *  
  3237  * For example:
  3281  * For example:
  3238  *       TYPE
  3282  *       TYPE
  3239  *          ref1: REF_TO INT;
  3283  *          ref1_t: REF_TO INT;
  3240  *          ref2: ref1;    <-- without the following rule, this would not be allowed!!
  3284  *          ref2_t: ref1_t;    <-- without the above changes, this would not be allowed!!
  3241  *       END_TYPE
  3285  *       END_TYPE
  3242  *
  3286  *
  3243  * This extra rule also makes it possible to declare variables using a previously declared REF_TO datatype
  3287  * This change also makes it possible to declare variables using a previously declared REF_TO datatype
  3244  *  For example:
  3288  *  For example:
  3245  *     VAR  refvar: ref1; END_VAR
  3289  *     VAR  refvar: ref1_t; END_VAR
  3246  */
  3290  *
  3247 | prev_declared_ref_type_name 
  3291  * This change also makes it possible to declare arrays containing a previously declared ref type.
  3248 ;
  3292  *  For example:
       
  3293  *     VAR  refvar: ARRAY [1..3] OF ref1_t;     END_VAR   <--- becomes OK
       
  3294  *     VAR  refvar: ARRAY [1..3] OF REF_TO INT; END_VAR   <--- still not OK. (Only becomes OK with other non-standard rules in another location of this file!)
       
  3295  *
       
  3296  * Interestingly, this change does NOT make it possible to declare structure elements of a previously declared ref type.
       
  3297  *  For example:
       
  3298  *     TYPE struct_t: STRUCT elem1: ref1_t;     END_STRUCT; END_TYPE;    <--- still not OK. (Only becomes OK with other non-standard rules in another location of this file!)
       
  3299  *     TYPE struct_t: STRUCT elem1: REF_TO INT; END_STRUCT; END_TYPE;    <--- still not OK. (Only becomes OK with other non-standard rules in another location of this file!)
       
  3300  */
       
  3301 
  3249 
  3302 
  3250 
  3303 
  3251 ref_spec_init: /* defined in IEC 61131-3 v3 */
  3304 ref_spec_init: /* defined in IEC 61131-3 v3 */
  3252   ref_spec
  3305   ref_spec
  3253 	{$$ = new ref_spec_init_c($1, NULL, locloc(@$));}
  3306 	{$$ = new ref_spec_init_c($1, NULL, locloc(@$));}
  3261   identifier ':' ref_spec_init
  3314   identifier ':' ref_spec_init
  3262 	{$$ = new ref_type_decl_c($1, $3, locloc(@$));
  3315 	{$$ = new ref_type_decl_c($1, $3, locloc(@$));
  3263 	 library_element_symtable.insert($1, prev_declared_ref_type_name_token);
  3316 	 library_element_symtable.insert($1, prev_declared_ref_type_name_token);
  3264 	}
  3317 	}
  3265 ;
  3318 ;
       
  3319 
       
  3320 
       
  3321 
  3266 
  3322 
  3267 
  3323 
  3268 
  3324 
  3269 
  3325 
  3270 /*********************/
  3326 /*********************/
  8157  * written code, so we only allow this extra syntax while parsing the 
  8213  * written code, so we only allow this extra syntax while parsing the 
  8158  * 'header' file that declares all the standard IEC 61131-3 functions.
  8214  * 'header' file that declares all the standard IEC 61131-3 functions.
  8159  */
  8215  */
  8160 bool allow_extensible_function_parameters = false;
  8216 bool allow_extensible_function_parameters = false;
  8161 
  8217 
  8162 /* A global flag used to tell the parser whether to include the full variable location
  8218 /* A global flag indicating whether to include the full variable location when printing out error messages... */
  8163  * when printing out error messages...
       
  8164  */
       
  8165 bool full_token_loc;
  8219 bool full_token_loc;
  8166 
       
  8167 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */
  8220 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */
  8168 bool allow_ref_to_any = false;
  8221 bool allow_ref_to_any = false;
  8169 
  8222 /* A global flag used to tell the parser whether to allow use of REF_TO as a struct or array element (non-standard extension) */
  8170 /* A pointer to the root of the parsing tree that will be generated 
  8223 bool allow_ref_to_in_derived_datatypes = false;
  8171  * by bison.
  8224 
  8172  */
  8225 /* A pointer to the root of the parsing tree that will be generated by bison. */
  8173 symbol_c *tree_root;
  8226 symbol_c *tree_root;
  8174 
  8227 
  8175 
  8228 
  8176 
  8229 
  8177 /* The following function is called automatically by bison whenever it comes across
  8230 /* The following function is called automatically by bison whenever it comes across
  8390 extern const char *INCLUDE_DIRECTORIES[];
  8443 extern const char *INCLUDE_DIRECTORIES[];
  8391 
  8444 
  8392 
  8445 
  8393 
  8446 
  8394 int stage2__(const char *filename, 
  8447 int stage2__(const char *filename, 
  8395              const char *includedir,     /* Include directory, where included files will be searched for... */
  8448              const char *includedir,   /* Include directory, where included files will be searched for... */
  8396              symbol_c **tree_root_ref,
  8449              symbol_c **tree_root_ref,
  8397              bool full_token_loc_,       /* error messages specify full token location */
  8450              bool full_token_loc_,                     /* error messages specify full token location */
  8398              bool ref_to_any_            /* allow use of non-standard REF_TO ANY datatypes */
  8451              bool allow_ref_to_nonstandard_extensions_ /* allow use of non-standard REF_TO ANY datatypes, and REF_TO inside structs and arrays */
  8399             ) {
  8452             ) {
  8400   char *libfilename = NULL;
  8453   char *libfilename = NULL;
  8401 
  8454 
  8402   if (includedir != NULL) {
  8455   if (includedir != NULL) {
  8403     INCLUDE_DIRECTORIES[0] = includedir;
  8456     INCLUDE_DIRECTORIES[0] = includedir;
  8425     return -1;
  8478     return -1;
  8426   }
  8479   }
  8427 
  8480 
  8428   allow_function_overloading           = true;
  8481   allow_function_overloading           = true;
  8429   allow_extensible_function_parameters = true;
  8482   allow_extensible_function_parameters = true;
  8430   full_token_loc   = full_token_loc_;
  8483   full_token_loc                       = full_token_loc_;
  8431   allow_ref_to_any = ref_to_any_;
  8484   allow_ref_to_any                     = allow_ref_to_nonstandard_extensions_;
       
  8485   allow_ref_to_in_derived_datatypes    = allow_ref_to_nonstandard_extensions_;
  8432   if (yyparse() != 0)
  8486   if (yyparse() != 0)
  8433       ERROR;
  8487       ERROR;
  8434   fclose(libfile);
  8488   fclose(libfile);
  8435       
  8489       
  8436   if (yynerrs > 0) {
  8490   if (yynerrs > 0) {
  8459     return -1;
  8513     return -1;
  8460   }
  8514   }
  8461 
  8515 
  8462   allow_function_overloading           = false;
  8516   allow_function_overloading           = false;
  8463   allow_extensible_function_parameters = false;
  8517   allow_extensible_function_parameters = false;
  8464   full_token_loc   = full_token_loc_;
  8518   full_token_loc                       = full_token_loc_;
  8465   allow_ref_to_any = ref_to_any_;
  8519   allow_ref_to_any                     = allow_ref_to_nonstandard_extensions_;
       
  8520   allow_ref_to_in_derived_datatypes    = allow_ref_to_nonstandard_extensions_;  
  8466   //allow_ref_to_any = false;    /* we only allow REF_TO ANY in library functions/FBs, no matter what the user asks for in the command line */
  8521   //allow_ref_to_any = false;    /* we only allow REF_TO ANY in library functions/FBs, no matter what the user asks for in the command line */
  8467 
  8522 
  8468   if (yyparse() != 0) {
  8523   if (yyparse() != 0) {
  8469     fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
  8524     fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
  8470     exit(EXIT_FAILURE);
  8525     exit(EXIT_FAILURE);