diff -r 9414b0785849 -r 91bef6704b44 stage1_2/iec_bison.yy --- 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 prev_declared_derived_function_block_name %type 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! */ ;