Add support for non standard feature: allow POUs with no in, out and inout parameters
authormjsousa
Wed, 11 May 2016 18:41:45 +0100
changeset 1012 1f2af384fb1f
parent 1011 76175defb87b
child 1013 d41dc551a326
Add support for non standard feature: allow POUs with no in, out and inout parameters
main.cc
main.hh
stage1_2/iec_bison.yy
stage3/fill_candidate_datatypes.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_st.cc
--- a/main.cc	Sun May 08 20:01:15 2016 +0100
+++ b/main.cc	Wed May 11 18:41:45 2016 +0100
@@ -121,9 +121,11 @@
   printf(" -R : allow use of REF_TO ANY datatypes              (a non-standard extension!)\n");
   printf("        as well as REF_TO in ARRAYs and STRUCTs      (a non-standard extension!)\n");
   printf(" -a : allow use of non-literals in array size limits (a non-standard extension!)\n");
+  printf(" -i : allow POUs with no in out and inout parameters (a non-standard extension!)\n");
   printf(" -e : disable generation of implicit EN and ENO parameters.\n");
   printf(" -c : create conversion functions for enumerated data types\n");
   printf(" -O : options for output (code generation) stage. Available options for %s are...\n", cmd);
+  runtime_options.allow_missing_var_in    = false; /* disable: allow definition and invocation of POUs with no input, output and in_out parameters! */
   stage4_print_options();
   printf("\n");
   printf("%s - Copyright (C) 2003-2014 \n"
@@ -143,6 +145,7 @@
   int path_len;
 
   /* Default values for the command line options... */
+  runtime_options.allow_missing_var_in    = false; /* disable: allow definition and invocation of POUs with no input, output and in_out parameters! */
   runtime_options.disable_implicit_en_eno = false; /* disable: do not generate EN and ENO parameters */
   runtime_options.pre_parsing             = false; /* disable: allow use of forward references (run pre-parsing phase before the definitive parsing phase that builds the AST) */
   runtime_options.safe_extensions         = false; /* disable: allow use of SAFExxx datatypes */
@@ -160,7 +163,7 @@
   /******************************************/
   /*   Parse command line options...        */
   /******************************************/
-  while ((optres = getopt(argc, argv, ":nehvfplsrRacI:T:O:")) != -1) {
+  while ((optres = getopt(argc, argv, ":nehvfplsrRaicI:T:O:")) != -1) {
     switch(optres) {
     case 'h':
       printusage(argv[0]);
@@ -176,6 +179,7 @@
               runtime_options.ref_nonstand_extensions  = true;  break;
     case 'r': runtime_options.ref_standard_extensions  = true;  break;
     case 'a': runtime_options.nonliteral_in_array_size = true;  break;
+    case 'i': runtime_options.allow_missing_var_in     = true;  break;
     case 'c': runtime_options.conversion_functions     = true;  break;
     case 'n': runtime_options.nested_comments          = true;  break;
     case 'e': runtime_options.disable_implicit_en_eno  = true;  break;
--- a/main.hh	Sun May 08 20:01:15 2016 +0100
+++ b/main.hh	Wed May 11 18:41:45 2016 +0100
@@ -40,6 +40,7 @@
 
 typedef struct {
    /* options specific to stage1_2 */
+	bool allow_missing_var_in;     /* Allow definition and invocation of POUs with no input, output and in_out parameters! */
 	bool disable_implicit_en_eno;  /* Disable the generation of implicit EN and ENO parameters on functions and Function Blocks */
 	bool pre_parsing;              /* Support forward references (Run a pre-parsing phase before the defintive parsing phase that builds the AST) */
 	bool safe_extensions;          /* support SAFE_* datatypes defined in PLCOpen TC5 "Safety Software Technical Specification - Part 1" v1.0 */
--- a/stage1_2/iec_bison.yy	Sun May 08 20:01:15 2016 +0100
+++ b/stage1_2/iec_bison.yy	Wed May 11 18:41:45 2016 +0100
@@ -198,15 +198,6 @@
  */
 extern bool allow_extensible_function_parameters;
 
-/* A global flag used to tell the parser whether to include the full variable location when printing out error messages... */
-extern bool full_token_loc;
-
-/* A global flag used to tell the parser whether to generate conversion function for enumerated data types. */
-extern bool conversion_functions;
-
-/* A global flag used to tell the parser whether to disable generation of implicit EN and ENO parameters. */
-extern bool disable_implicit_en_eno;
-
 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */
 extern bool allow_ref_dereferencing;
 
@@ -2576,7 +2567,7 @@
 
 data_type_declaration:
   TYPE type_declaration_list END_TYPE
-	{$$ = new data_type_declaration_c($2, locloc(@$)); if (conversion_functions) include_string((create_enumtype_conversion_functions_c::get_declaration($$)).c_str());}
+	{$$ = new data_type_declaration_c($2, locloc(@$)); if (runtime_options.conversion_functions) include_string((create_enumtype_conversion_functions_c::get_declaration($$)).c_str());}
 /* ERROR_CHECK_BEGIN */
 | TYPE END_TYPE
 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "no data type declared in data type(s) declaration."); yynerrs++;}
@@ -5004,7 +4995,7 @@
 /* POST_PARSING and STANDARD_PARSING: The rules expected to be applied after the preparser has finished. */
 | function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
 	{$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
-	 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
+	 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
 	 variable_name_symtable.pop();
 	 direct_variable_symtable.pop();
 	 library_element_symtable.insert($1, prev_declared_derived_function_name_token);
@@ -5012,7 +5003,7 @@
 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */
 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION
 	{$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$));
-	 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
+	 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
 	 variable_name_symtable.pop();
 	 direct_variable_symtable.pop();
 	 library_element_symtable.insert($1, prev_declared_derived_function_name_token);
@@ -5223,7 +5214,7 @@
 /* POST_PARSING: The rules expected to be applied after the preparser runs. Will only run if pre-parsing command line option is ON. */
 | FUNCTION_BLOCK prev_declared_derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
 	{$$ = new function_block_declaration_c($2, $3, $4, locloc(@$));
-	 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
+	 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
 	 /* Clear the variable_name_symtable. Since we have finished parsing the function block,
 	  * the variable names are now out of scope, so are no longer valid!
 	  */
@@ -5234,7 +5225,7 @@
 | FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK
 	{$$ = new function_block_declaration_c($2, $3, $4, locloc(@$));
 	 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token);
-	 if (!disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
+	 if (!runtime_options.disable_implicit_en_eno) add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */
 	 /* Clear the variable_name_symtable. Since we have finished parsing the function block,
 	  * the variable names are now out of scope, so are no longer valid!
 	  */
@@ -7815,11 +7806,16 @@
 	{$$ = new function_invocation_c($1, $3, NULL, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c
 | function_name_no_NOT_clashes '(' param_assignment_nonformal_list ')'
 	{$$ = new function_invocation_c($1, NULL, $3, locloc(@$)); if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR;} // $1 should be a poutype_identifier_c
+| function_name_no_NOT_clashes '(' ')'
+	{if (NULL == dynamic_cast<poutype_identifier_c*>($1)) ERROR; // $1 should be a poutype_identifier_c
+	 if (runtime_options.allow_missing_var_in)
+		{$$ = new function_invocation_c($1, NULL, NULL, locloc(@$));}
+	 else
+		{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;}
+	}
 /* ERROR_CHECK_BEGIN */ 
 | function_name_no_NOT_clashes param_assignment_formal_list ')'
   {$$ = NULL; print_err_msg(locl(@1), locf(@2), "'(' missing after function name in ST expression."); yynerrs++;}
-| function_name_no_NOT_clashes '(' ')'
-  {$$ = NULL; print_err_msg(locl(@2), locf(@3), "no parameter defined in function invocation of ST expression."); yynerrs++;}
 | function_name_no_NOT_clashes '(' error ')'
   {$$ = NULL; print_err_msg(locf(@3), locl(@3), "invalid parameter(s) defined in function invocation of ST expression."); yyerrok;}
 | function_name_no_NOT_clashes '(' param_assignment_formal_list error
@@ -8446,12 +8442,6 @@
  */
 bool allow_extensible_function_parameters = false;
 
-/* A global flag indicating whether to include the full variable location when printing out error messages... */
-bool full_token_loc;
-/* A global flag used to tell the parser whether to generate conversion function for enumerated data types. */
-bool conversion_functions = false;
-/* A global flag used to tell the parser whether to disable generation of implicit EN and ENO parameters. */
-bool disable_implicit_en_eno;
 /* A global flag used to tell the parser whether to allow use of DREF and '^' operators (defined in IEC 61131-3 v3) */
 bool allow_ref_dereferencing;
 /* A global flag used to tell the parser whether to allow use of REF_TO ANY datatypes (non-standard extension) */
@@ -8527,7 +8517,7 @@
   if (first_filename == NULL) first_filename = unknown_file;
   if ( last_filename == NULL)  last_filename = unknown_file;
 
-  if (full_token_loc) {
+  if (runtime_options.full_token_loc) {
     if (first_filename == last_filename)
       fprintf(stderr, "%s:%d-%d..%d-%d: error: %s\n", first_filename, first_line, first_column, last_line, last_column, additional_error_msg);
     else
@@ -8713,9 +8703,6 @@
 
   allow_function_overloading           = true;
   allow_extensible_function_parameters = true;
-  full_token_loc                       = runtime_options.full_token_loc;
-  conversion_functions                 = runtime_options.conversion_functions;
-  disable_implicit_en_eno              = runtime_options.disable_implicit_en_eno;
   allow_ref_dereferencing              = runtime_options.ref_standard_extensions;
   allow_ref_to_any                     = runtime_options.ref_nonstand_extensions;
   allow_ref_to_in_derived_datatypes    = runtime_options.ref_nonstand_extensions;
@@ -8751,9 +8738,6 @@
 
   allow_function_overloading           = false;
   allow_extensible_function_parameters = false;
-  full_token_loc                       = runtime_options.full_token_loc;
-  conversion_functions                 = runtime_options.conversion_functions;
-  disable_implicit_en_eno              = runtime_options.disable_implicit_en_eno;
   allow_ref_dereferencing              = runtime_options.ref_standard_extensions;
   allow_ref_to_any                     = runtime_options.ref_nonstand_extensions;
   allow_ref_to_in_derived_datatypes    = runtime_options.ref_nonstand_extensions;
--- a/stage3/fill_candidate_datatypes.cc	Sun May 08 20:01:15 2016 +0100
+++ b/stage3/fill_candidate_datatypes.cc	Wed May 11 18:41:45 2016 +0100
@@ -2170,7 +2170,7 @@
 void *fill_candidate_datatypes_c::visit(function_invocation_c *symbol) {
 	if      (NULL != symbol->formal_param_list)        symbol->   formal_param_list->accept(*this);
 	else if (NULL != symbol->nonformal_param_list)     symbol->nonformal_param_list->accept(*this);
-	else ERROR;
+	// else ERROR;  NOTE-> We support the non-standard feature of POUS with no in, out and inout parameters, so this is no longer an internal error!
 
 	generic_function_call_t fcall_param = {
 			  function_name:                symbol->function_name,
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Sun May 08 20:01:15 2016 +0100
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Wed May 11 18:41:45 2016 +0100
@@ -764,7 +764,8 @@
       symbol_c *parameter_assignment_list = NULL;
       if (NULL != symbol->   formal_param_list) parameter_assignment_list = symbol->   formal_param_list;
       if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
-      if (NULL == parameter_assignment_list) ERROR;
+      // NOTE-> We support the non-standard feature of POUS with no in, out and inout parameters, so this is no longer an internal error!
+      // if (NULL == parameter_assignment_list) ERROR; 
 
       function_call_param_iterator_c function_call_param_iterator(symbol);
 
--- a/stage4/generate_c/generate_c_st.cc	Sun May 08 20:01:15 2016 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Wed May 11 18:41:45 2016 +0100
@@ -726,7 +726,8 @@
   symbol_c *parameter_assignment_list = NULL;
   if (NULL != symbol->   formal_param_list) parameter_assignment_list = symbol->   formal_param_list;
   if (NULL != symbol->nonformal_param_list) parameter_assignment_list = symbol->nonformal_param_list;
-  if (NULL == parameter_assignment_list) ERROR;
+  // NOTE-> We support the non-standard feature of POUS with no in, out and inout parameters, so this is no longer an internal error!
+  //if (NULL == parameter_assignment_list) ERROR;
 
   function_call_param_iterator_c function_call_param_iterator(symbol);