195 * input parameters, such as AND(word#33, word#44, word#55, word#66). |
195 * input parameters, such as AND(word#33, word#44, word#55, word#66). |
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 |
|
201 /* A global flag used to tell the parser whether to include the full variable location when printing out error messages... */ |
|
202 extern bool full_token_loc; |
|
203 |
|
204 /* A global flag used to tell the parser whether to generate conversion function for enumerated data types. */ |
|
205 extern bool conversion_functions; |
|
206 |
|
207 /* A global flag used to tell the parser whether to disable generation of implicit EN and ENO parameters. */ |
|
208 extern bool disable_implicit_en_eno; |
|
209 |
200 |
210 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */ |
201 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */ |
211 extern bool allow_ref_dereferencing; |
202 extern bool allow_ref_dereferencing; |
212 |
203 |
213 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension to IEC 61131-3 v3) */ |
204 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension to IEC 61131-3 v3) */ |
2574 structure_type_name: identifier; |
2565 structure_type_name: identifier; |
2575 */ |
2566 */ |
2576 |
2567 |
2577 data_type_declaration: |
2568 data_type_declaration: |
2578 TYPE type_declaration_list END_TYPE |
2569 TYPE type_declaration_list END_TYPE |
2579 {$$ = new data_type_declaration_c($2, locloc(@$)); if (conversion_functions) include_string((create_enumtype_conversion_functions_c::get_declaration($$)).c_str());} |
2570 {$$ = new data_type_declaration_c($2, locloc(@$)); if (runtime_options.conversion_functions) include_string((create_enumtype_conversion_functions_c::get_declaration($$)).c_str());} |
2580 /* ERROR_CHECK_BEGIN */ |
2571 /* ERROR_CHECK_BEGIN */ |
2581 | TYPE END_TYPE |
2572 | TYPE END_TYPE |
2582 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no data type declared in data type(s) declaration."); yynerrs++;} |
2573 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "no data type declared in data type(s) declaration."); yynerrs++;} |
2583 | TYPE error type_declaration_list END_TYPE |
2574 | TYPE error type_declaration_list END_TYPE |
2584 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'TYPE' in data type(s) declaration."); yyerrok;} |
2575 {$$ = NULL; print_err_msg(locf(@2), locl(@2), "unexpected token after 'TYPE' in data type(s) declaration."); yyerrok;} |
5002 else {print_err_msg(locl(@1), locf(@3), "FUNCTION with no variable declarations and no body."); yynerrs++;} |
4993 else {print_err_msg(locl(@1), locf(@3), "FUNCTION with no variable declarations and no body."); yynerrs++;} |
5003 } |
4994 } |
5004 /* POST_PARSING and STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
4995 /* POST_PARSING and STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */ |
5005 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4996 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
5006 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4997 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
5007 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4998 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5008 variable_name_symtable.pop(); |
4999 variable_name_symtable.pop(); |
5009 direct_variable_symtable.pop(); |
5000 direct_variable_symtable.pop(); |
5010 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
5001 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
5011 } |
5002 } |
5012 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
5003 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
5013 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
5004 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
5014 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
5005 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
5015 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5006 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5016 variable_name_symtable.pop(); |
5007 variable_name_symtable.pop(); |
5017 direct_variable_symtable.pop(); |
5008 direct_variable_symtable.pop(); |
5018 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
5009 library_element_symtable.insert($1, prev_declared_derived_function_name_token); |
5019 } |
5010 } |
5020 /* ERROR_CHECK_BEGIN */ |
5011 /* ERROR_CHECK_BEGIN */ |
5221 else {print_err_msg(locl(@1), locf(@3), "FUNCTION_BLOCK with no variable declarations and no body."); yynerrs++;} |
5212 else {print_err_msg(locl(@1), locf(@3), "FUNCTION_BLOCK with no variable declarations and no body."); yynerrs++;} |
5222 } |
5213 } |
5223 /* POST_PARSING: The rules expected to be applied after the preparser runs. Will only run if pre-parsing command line option is ON. */ |
5214 /* POST_PARSING: The rules expected to be applied after the preparser runs. Will only run if pre-parsing command line option is ON. */ |
5224 | FUNCTION_BLOCK prev_declared_derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5215 | FUNCTION_BLOCK prev_declared_derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5225 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5216 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5226 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5217 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5227 /* Clear the variable_name_symtable. Since we have finished parsing the function block, |
5218 /* Clear the variable_name_symtable. Since we have finished parsing the function block, |
5228 * the variable names are now out of scope, so are no longer valid! |
5219 * the variable names are now out of scope, so are no longer valid! |
5229 */ |
5220 */ |
5230 variable_name_symtable.pop(); |
5221 variable_name_symtable.pop(); |
5231 direct_variable_symtable.pop(); |
5222 direct_variable_symtable.pop(); |
5232 } |
5223 } |
5233 /* STANDARD_PARSING: The rules expected to be applied in single-phase parsing. Will only run if pre-parsing command line option is OFF. */ |
5224 /* STANDARD_PARSING: The rules expected to be applied in single-phase parsing. Will only run if pre-parsing command line option is OFF. */ |
5234 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5225 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
5235 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5226 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
5236 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); |
5227 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); |
5237 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5228 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
5238 /* Clear the variable_name_symtable. Since we have finished parsing the function block, |
5229 /* Clear the variable_name_symtable. Since we have finished parsing the function block, |
5239 * the variable names are now out of scope, so are no longer valid! |
5230 * the variable names are now out of scope, so are no longer valid! |
5240 */ |
5231 */ |
5241 variable_name_symtable.pop(); |
5232 variable_name_symtable.pop(); |
5242 direct_variable_symtable.pop(); |
5233 direct_variable_symtable.pop(); |
7813 /* function_name '(' [param_assignment_list] ')' */ |
7804 /* function_name '(' [param_assignment_list] ')' */ |
7814 function_name_no_NOT_clashes '(' param_assignment_formal_list ')' |
7805 function_name_no_NOT_clashes '(' param_assignment_formal_list ')' |
7815 {$$ = new function_invocation_c($1, $3, NULL, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c |
7806 {$$ = new function_invocation_c($1, $3, NULL, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c |
7816 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')' |
7807 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')' |
7817 {$$ = new function_invocation_c($1, NULL, $3, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c |
7808 {$$ = new function_invocation_c($1, NULL, $3, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c |
|
7809 | function_name_no_NOT_clashes '(' ')' |
|
7810 {if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR; // $1 should be a poutype_identifier_c |
|
7811 if (runtime_options.allow_missing_var_in) |
|
7812 {$$ = new function_invocation_c($1, NULL, NULL, locloc(@$));} |
|
7813 else |
|
7814 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;} |
|
7815 } |
7818 /* ERROR_CHECK_BEGIN */ |
7816 /* ERROR_CHECK_BEGIN */ |
7819 | function_name_no_NOT_clashes param_assignment_formal_list ')' |
7817 | function_name_no_NOT_clashes param_assignment_formal_list ')' |
7820 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;} |
7818 {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;} |
7821 | function_name_no_NOT_clashes '(' ')' |
|
7822 {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;} |
|
7823 | function_name_no_NOT_clashes '(' error ')' |
7819 | function_name_no_NOT_clashes '(' error ')' |
7824 {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter(s) defined in function invocation of ST expression."); yyerrok;} |
7820 {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter(s) defined in function invocation of ST expression."); yyerrok;} |
7825 | function_name_no_NOT_clashes '(' param_assignment_formal_list error |
7821 | function_name_no_NOT_clashes '(' param_assignment_formal_list error |
7826 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;} |
7822 {$$ = NULL; print_err_msg(locl(@3), locf(@4), "')' missing at the end of function invocation in ST expression."); yyerrok;} |
7827 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list error |
7823 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list error |
8444 * written code, so we only allow this extra syntax while parsing the |
8440 * written code, so we only allow this extra syntax while parsing the |
8445 * 'header' file that declares all the standard IEC 61131-3 functions. |
8441 * 'header' file that declares all the standard IEC 61131-3 functions. |
8446 */ |
8442 */ |
8447 bool allow_extensible_function_parameters = false; |
8443 bool allow_extensible_function_parameters = false; |
8448 |
8444 |
8449 /* A global flag indicating whether to include the full variable location when printing out error messages... */ |
|
8450 bool full_token_loc; |
|
8451 /* A global flag used to tell the parser whether to generate conversion function for enumerated data types. */ |
|
8452 bool conversion_functions = false; |
|
8453 /* A global flag used to tell the parser whether to disable generation of implicit EN and ENO parameters. */ |
|
8454 bool disable_implicit_en_eno; |
|
8455 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */ |
8445 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */ |
8456 bool allow_ref_dereferencing; |
8446 bool allow_ref_dereferencing; |
8457 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */ |
8447 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */ |
8458 bool allow_ref_to_any = false; |
8448 bool allow_ref_to_any = false; |
8459 /* A global flag used to tell the parser whether to allow use of REF_TO as a struct or array element (non-standard extension) */ |
8449 /* A global flag used to tell the parser whether to allow use of REF_TO as a struct or array element (non-standard extension) */ |
8525 |
8515 |
8526 const char *unknown_file = "<unknown_file>"; |
8516 const char *unknown_file = "<unknown_file>"; |
8527 if (first_filename == NULL) first_filename = unknown_file; |
8517 if (first_filename == NULL) first_filename = unknown_file; |
8528 if ( last_filename == NULL) last_filename = unknown_file; |
8518 if ( last_filename == NULL) last_filename = unknown_file; |
8529 |
8519 |
8530 if (full_token_loc) { |
8520 if (runtime_options.full_token_loc) { |
8531 if (first_filename == last_filename) |
8521 if (first_filename == last_filename) |
8532 fprintf(stderr, "%s:%d-%d..%d-%d: error: %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg); |
8522 fprintf(stderr, "%s:%d-%d..%d-%d: error: %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg); |
8533 else |
8523 else |
8534 fprintf(stderr, "%s:%d-%d..%s:%d-%d: error: %s\n", first_filename, first_line, first_column, last_filename, last_line, last_column, additional_error_msg); |
8524 fprintf(stderr, "%s:%d-%d..%s:%d-%d: error: %s\n", first_filename, first_line, first_column, last_filename, last_line, last_column, additional_error_msg); |
8535 } else { |
8525 } else { |
8711 return -1; |
8701 return -1; |
8712 } |
8702 } |
8713 |
8703 |
8714 allow_function_overloading = true; |
8704 allow_function_overloading = true; |
8715 allow_extensible_function_parameters = true; |
8705 allow_extensible_function_parameters = true; |
8716 full_token_loc = runtime_options.full_token_loc; |
|
8717 conversion_functions = runtime_options.conversion_functions; |
|
8718 disable_implicit_en_eno = runtime_options.disable_implicit_en_eno; |
|
8719 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8706 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8720 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8707 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8721 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8708 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8722 if (yyparse() != 0) { |
8709 if (yyparse() != 0) { |
8723 fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors in standard library. Bailing out!\n"); |
8710 fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors in standard library. Bailing out!\n"); |
8749 return -3; |
8736 return -3; |
8750 } |
8737 } |
8751 |
8738 |
8752 allow_function_overloading = false; |
8739 allow_function_overloading = false; |
8753 allow_extensible_function_parameters = false; |
8740 allow_extensible_function_parameters = false; |
8754 full_token_loc = runtime_options.full_token_loc; |
|
8755 conversion_functions = runtime_options.conversion_functions; |
|
8756 disable_implicit_en_eno = runtime_options.disable_implicit_en_eno; |
|
8757 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8741 allow_ref_dereferencing = runtime_options.ref_standard_extensions; |
8758 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8742 allow_ref_to_any = runtime_options.ref_nonstand_extensions; |
8759 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8743 allow_ref_to_in_derived_datatypes = runtime_options.ref_nonstand_extensions; |
8760 //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 */ |
8744 //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 */ |
8761 |
8745 |