--- a/stage1_2/iec_bison.yy Thu May 26 14:26:33 2016 +0100
+++ b/stage1_2/iec_bison.yy Thu May 26 15:00:20 2016 +0100
@@ -373,6 +373,32 @@
%type <leaf> prev_declared_derived_function_block_name
%type <leaf> prev_declared_program_type_name
+/* Tokens used to help resolve a reduce/reduce conflict */
+/* The mentioned conflict only arises due to a non-standard feature added to matiec.
+ * Namely, the permission to call functions returning VOID as an ST statement.
+ * e.g.: FUNCTION foo: VOID
+ * VAR_INPUT i: INT; END_VAR;
+ * ...
+ * END_FUNCTION
+ *
+ * FUNCTION BAR: BOOL
+ * VAR b: bool; END_VAR
+ * foo(i:=42); <--- Calling foo outside an expression. Function invocation is considered an ST statement!!
+ * END_FUNCTION
+ *
+ * The above function invocation may also be reduced to a formal IL function invocation, so we get a
+ * reduce/reduce conflict to st_statement_list/instruction_list (or something equivalent).
+ *
+ * We solve this by having flex determine if it is ST or IL invocation (ST ends with a ';' !!).
+ * At the start of a function/FB/program body, flex will tell bison whether to expect ST or IL code!
+ * This is why we need the following two tokens!
+ *
+ * NOTE: flex was already determing whther it was parsing ST or IL code as it can only send
+ * EOL tokens when parsing IL. However, did this silently without telling bison about this.
+ * Now, it does
+ */
+%token start_ST_body_token
+%token start_IL_body_token
@@ -5013,7 +5039,7 @@
}
/* | FUNCTION derived_function_name ':' VOID io_OR_function_var_declarations_list function_body END_FUNCTION */
| function_name_declaration ':' VOID io_OR_function_var_declarations_list function_body END_FUNCTION
- {$$ = new function_declaration_c($1, new void_c(locloc(@3)), $4, $5, locloc(@$));
+ {$$ = new function_declaration_c($1, new void_type_name_c(locloc(@3)), $4, $5, locloc(@$));
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();
@@ -5183,8 +5209,8 @@
function_body:
- statement_list {$$ = $1;} /* if we leave it for the default action we get a type clash! */
-| instruction_list {$$ = $1;} /* if we leave it for the default action we get a type clash! */
+ start_ST_body_token statement_list {$$ = $2;}
+| start_IL_body_token instruction_list {$$ = $2;}
/*
| ladder_diagram
| function_block_diagram
@@ -5257,7 +5283,7 @@
{$$ = NULL; print_err_msg(locl(@2), locf(@3), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}
*/
| FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_OF_INPUT
- {$$ = NULL; print_err_msg(locf(@1), locl(@2), "no variable(s) declared and body defined in function block declaration."); yynerrs++;}
+ {$$ = NULL; print_err_msg(locf(@1), locl(@2), "expecting END_FUNCTION_BLOCK before end of file."); yynerrs++;}
| FUNCTION_BLOCK error END_FUNCTION_BLOCK
{$$ = NULL; print_err_msg(locf(@2), locl(@2), "unknown error in function block declaration."); yyerrok;}
/* ERROR_CHECK_END */
@@ -5366,9 +5392,21 @@
function_block_body:
- statement_list {$$ = $1;}
-| instruction_list {$$ = $1;}
-| sequential_function_chart {$$ = $1;}
+ /* NOTE: start_ST_body_token is a dummy token generated by flex when it determines it is starting to parse a POU body in ST
+ * start_IL_body_token is a dummy token generated by flex when it determines it is starting to parse a POU body in IL
+ * These tokens help remove a reduce/reduce conflict in bison, between a formal function invocation in IL, and a
+ * function invocation used as a statement (a non-standard extension added to matiec)
+ * e.g: FUNCTION_BLOCK foo
+ * VAR ... END_VAR
+ * func_returning_void(in1 := 3
+ * ); --> only the presence or absence of ';' will determine whether this is a IL or ST
+ * function invocation. (In standard ST this would be ilegal, in matiec we allow it
+ * when activated by a command line option)
+ * END_FUNCTION
+ */
+ start_ST_body_token statement_list {$$ = $2;}
+| start_IL_body_token instruction_list {$$ = $2;}
+| sequential_function_chart {$$ = $1;}
/*
| ladder_diagram
| function_block_diagram
@@ -7867,6 +7905,7 @@
| subprogram_control_statement
| selection_statement
| iteration_statement
+| function_invocation /* TODO: this must be conditional on command line parameter! */
;