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(@$));} |
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; |
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); |