385 /* Where do these tokens belong?? They are missing from the standard! */ |
387 /* Where do these tokens belong?? They are missing from the standard! */ |
386 /* NOTE: There are other tokens related to these 'EN' ENO', that are also |
388 /* NOTE: There are other tokens related to these 'EN' ENO', that are also |
387 * missing from the standard. However, their location in the annex B is |
389 * missing from the standard. However, their location in the annex B is |
388 * relatively obvious, so they have been inserted in what seems to us their |
390 * relatively obvious, so they have been inserted in what seems to us their |
389 * correct place in order to ease understanding of the parser... |
391 * correct place in order to ease understanding of the parser... |
|
392 * |
|
393 * please read the comment above the definition of 'variable' in section B1.4 for details. |
390 */ |
394 */ |
391 %token EN |
395 %token EN |
392 %token ENO |
396 %token ENO |
393 %type <leaf> en_identifier |
397 %type <leaf> en_identifier |
394 %type <leaf> eno_identifier |
398 %type <leaf> eno_identifier |
3232 /*********************/ |
3236 /*********************/ |
3233 /* B 1.4 - Variables */ |
3237 /* B 1.4 - Variables */ |
3234 /*********************/ |
3238 /*********************/ |
3235 /* NOTE: The standard is erroneous in it's definition of 'variable' because: |
3239 /* NOTE: The standard is erroneous in it's definition of 'variable' because: |
3236 * - The standard considers 'ENO' as a keyword... |
3240 * - The standard considers 'ENO' as a keyword... |
3237 * - ...which means that it may never be parsed as an 'identifier'... |
3241 * - ...=> which means that it may never be parsed as an 'identifier'... |
3238 * - ...and therefore may never be used as the name of a variable inside an expression. |
3242 * - ...=> and therefore may never be used as the name of a variable inside an expression. |
3239 * - However, a function/FB must be able to assign the ENO parameter |
3243 * - However, a function/FB must be able to assign the ENO parameter |
3240 * it's value, doing it in an assignment statement, and therefore using the 'ENO' |
3244 * it's value, doing it in an assignment statement, and therefore using the 'ENO' |
3241 * character sequence as an identifier! |
3245 * character sequence as an identifier! |
3242 * The solution we found was to also allow the ENO keyword to be |
3246 * The obvious solution is to also allow the ENO keyword to be |
3243 * used as the name of a variable. Note that this variable may be used |
3247 * used as the name of a variable. Note that this variable may be used |
3244 * even though it is not explicitly declared as a function/FB variable, |
3248 * even though it is not explicitly declared as a function/FB variable, |
3245 * as the standard requires us to define it implicitly in this case! |
3249 * as the standard requires us to define it implicitly in this case! |
3246 * We could not therefore handle the ENO as a normal variable that would |
3250 * There are three ways of achieving this: |
3247 * go into the previously_declared_variable symbol table, as we may need to |
3251 * (i) simply not define EN and ENO as keywords in flex (lexical analyser) |
3248 * allow it to be used as a variable even though it is not declared as such! |
3252 * and let them be considered 'identifiers'. Aditionally, add some code |
|
3253 * so that if they are not explicitly declared, we add them automatically to |
|
3254 * the declaration of each Functions and FB, where they would then be parsed |
|
3255 * as a previously_declared_variable. |
|
3256 * This approach has the advantage the EN and ENO would automatically be valid |
|
3257 * in every location where it needs to be valid, namely in the explicit declaration |
|
3258 * of these same variables, or when they are used within expressions. |
|
3259 * However, this approach has the drawback that |
|
3260 * EN and ENO could then also be used anywhere a standard identifier is allowed, |
|
3261 * including in the naming of Functions, FBs, Programs, Configurations, Resources, |
|
3262 * SFC Actions, SFC Steps, etc... |
|
3263 * This would mean that we would then have to add a lexical analysis check |
|
3264 * within the bison code (syntax analyser) to all the above constructs to make sure |
|
3265 * that the identifier being used is not EN or ENO. |
|
3266 * (ii) The other approach is to define EN and ENO as keywords / tokens in flex |
|
3267 * (lexical analyser) and then change the syntax in bison to acomodate |
|
3268 * these tokens wherever they could correctly appear. |
|
3269 * This has the drawback that we need to do some changes to the synax defintion. |
|
3270 * (iii) Yet a another option is to mix the above two methods. |
|
3271 * Define EN and ENO as tokens in flex, but change (only) the syntax for |
|
3272 * variable declaration to allow these tokens to also be used in declaring variables. |
|
3273 * From this point onwards these tokens are then considered a previously_declared_variable, |
|
3274 * since flex will first check for this before even checking for tokens. |
|
3275 * |
|
3276 * I (Mario) cuurretnly (2011) believe the cleanest method of achieving this goal |
|
3277 * is to use option (iii) |
|
3278 * However, considering that: |
|
3279 * - I have already previously implemented option (ii); |
|
3280 * - option (iii) requires that flex parse the previously_declared_variable |
|
3281 * before parsing any token. We already support this (remeber that this is |
|
3282 * used mainly to allow some IL operators as well as PRIORITY, etc. tokens |
|
3283 * to be used as identifiers, since the standard does not define them as keywords), |
|
3284 * but this part of the code in flex is often commented out as usually people do not expect |
|
3285 * us to follow the standard in the strict sense, but rather consider those |
|
3286 * tokens as keywords; |
|
3287 * considering the above, we currently carry on using option (ii). |
3249 */ |
3288 */ |
3250 variable: |
3289 variable: |
3251 symbolic_variable |
3290 symbolic_variable |
3252 | prev_declared_direct_variable |
3291 | prev_declared_direct_variable |
3253 | eno_identifier |
3292 | eno_identifier |
3482 /* NOTE: The formal definition of the standard is erroneous, as it simply does not |
3524 /* NOTE: The formal definition of the standard is erroneous, as it simply does not |
3483 * consider the EN and ENO keywords! |
3525 * consider the EN and ENO keywords! |
3484 * The semantic description of the languages clearly states that these may be |
3526 * The semantic description of the languages clearly states that these may be |
3485 * used in several ways. One of them is to declare an EN input parameter. |
3527 * used in several ways. One of them is to declare an EN input parameter. |
3486 * We have added the 'en_param_declaration' clause to cover for this. |
3528 * We have added the 'en_param_declaration' clause to cover for this. |
|
3529 * |
|
3530 * Please read the comment above the definition of 'variable' in section B1.4 for details. |
3487 */ |
3531 */ |
3488 en_param_declaration: |
3532 en_param_declaration: |
3489 en_identifier ':' BOOL ASSIGN boolean_literal |
3533 en_identifier ':' BOOL ASSIGN boolean_literal |
3490 {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));} |
3534 {$$ = new en_param_declaration_c($1, new bool_type_name_c(locloc(@$)), $5, new explicit_definition_c(), locloc(@$));} |
3491 | en_identifier ':' BOOL ASSIGN integer |
3535 | en_identifier ':' BOOL ASSIGN integer |
3728 /* NOTE: The formal definition of the standard is erroneous, as it simply does not |
3774 /* NOTE: The formal definition of the standard is erroneous, as it simply does not |
3729 * consider the EN and ENO keywords! |
3775 * consider the EN and ENO keywords! |
3730 * The semantic description of the languages clearly states that these may be |
3776 * The semantic description of the languages clearly states that these may be |
3731 * used in several ways. One of them is to declare an ENO output parameter. |
3777 * used in several ways. One of them is to declare an ENO output parameter. |
3732 * We have added the 'eno_param_declaration' clause to cover for this. |
3778 * We have added the 'eno_param_declaration' clause to cover for this. |
|
3779 * |
|
3780 * Please read the comment above the definition of 'variable' in section B1.4 for details. |
3733 */ |
3781 */ |
3734 eno_param_declaration: |
3782 eno_param_declaration: |
3735 eno_identifier ':' BOOL |
3783 eno_identifier ':' BOOL |
3736 /* NOTE We do _NOT_ include this variable in the previously_declared_variable symbol table! |
3784 /* NOTE We do _NOT_ include this variable in the previously_declared_variable symbol table! |
3737 * Please read the comment above the definition of 'variable' for the reason for this. |
3785 * Please read the comment above the definition of 'variable' for the reason for this. |
4627 |
4675 |
4628 function_declaration: |
4676 function_declaration: |
4629 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4677 /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4630 function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4678 function_name_declaration ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4631 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4679 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
|
4680 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4632 variable_name_symtable.pop(); |
4681 variable_name_symtable.pop(); |
4633 direct_variable_symtable.pop(); |
4682 direct_variable_symtable.pop(); |
4634 if (allow_function_overloading) { |
4683 if (allow_function_overloading) { |
4635 switch (library_element_symtable.find_value($1)) { |
4684 switch (library_element_symtable.find_value($1)) { |
4636 case prev_declared_derived_function_name_token: |
4685 case prev_declared_derived_function_name_token: |
4649 } |
4698 } |
4650 } |
4699 } |
4651 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4700 /* | FUNCTION derived_function_name ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ |
4652 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4701 | function_name_declaration ':' derived_type_name io_OR_function_var_declarations_list function_body END_FUNCTION |
4653 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
4702 {$$ = new function_declaration_c($1, $3, $4, $5, locloc(@$)); |
|
4703 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4654 variable_name_symtable.pop(); |
4704 variable_name_symtable.pop(); |
4655 direct_variable_symtable.pop(); |
4705 direct_variable_symtable.pop(); |
4656 if (allow_function_overloading) { |
4706 if (allow_function_overloading) { |
4657 switch (library_element_symtable.find_value($1)) { |
4707 switch (library_element_symtable.find_value($1)) { |
4658 case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break; |
4708 case prev_declared_derived_function_name_token: /* do nothing, already in map. */ break; |
4859 |
4909 |
4860 |
4910 |
4861 function_block_declaration: |
4911 function_block_declaration: |
4862 FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
4912 FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations_list function_block_body END_FUNCTION_BLOCK |
4863 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
4913 {$$ = new function_block_declaration_c($2, $3, $4, locloc(@$)); |
|
4914 add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ |
4864 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); |
4915 library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); |
4865 /* Clear the variable_name_symtable. Since |
4916 /* Clear the variable_name_symtable. Since |
4866 * we have finished parsing the function block, |
4917 * we have finished parsing the function block, |
4867 * the variable names are now out of scope, so |
4918 * the variable names are now out of scope, so |
4868 * are no longer valid! |
4919 * are no longer valid! |
6825 /* The following is not required, as the sendto_identifier_token returned by flex will |
6876 /* The following is not required, as the sendto_identifier_token returned by flex will |
6826 * also include the 'ENO' identifier. |
6877 * also include the 'ENO' identifier. |
6827 * The resulting abstract syntax tree is identical with or without this following rule, |
6878 * The resulting abstract syntax tree is identical with or without this following rule, |
6828 * as both the eno_identifier and the sendto_identifier are stored as |
6879 * as both the eno_identifier and the sendto_identifier are stored as |
6829 * an identifier_c !! |
6880 * an identifier_c !! |
|
6881 * |
|
6882 * To understand why we must even explicitly consider the use of ENO here, |
|
6883 * please read the comment above the definition of 'variable' in section B1.4 for details. |
6830 */ |
6884 */ |
6831 /* |
6885 /* |
6832 | eno_identifier SENDTO |
6886 | eno_identifier SENDTO |
6833 {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));} |
6887 {$$ = new il_assign_out_operator_c(NULL, $1, locloc(@$));} |
6834 */ |
6888 */ |
6838 /* The following is not required, as the sendto_identifier_token returned by flex will |
6892 /* The following is not required, as the sendto_identifier_token returned by flex will |
6839 * also include the 'ENO' identifier. |
6893 * also include the 'ENO' identifier. |
6840 * The resulting abstract syntax tree is identical with or without this following rule, |
6894 * The resulting abstract syntax tree is identical with or without this following rule, |
6841 * as both the eno_identifier and the sendto_identifier are stored as |
6895 * as both the eno_identifier and the sendto_identifier are stored as |
6842 * an identifier_c !! |
6896 * an identifier_c !! |
|
6897 * |
|
6898 * To understand why we must even explicitly consider the use of ENO here, |
|
6899 * please read the comment above the definition of 'variable' in section B1.4 for details. |
6843 * |
6900 * |
6844 * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser. |
6901 * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser. |
6845 * This conflict is not really an error/ambiguity in the syntax, but rather |
6902 * This conflict is not really an error/ambiguity in the syntax, but rather |
6846 * due to the fact that more than a single look-ahead token would be required |
6903 * due to the fact that more than a single look-ahead token would be required |
6847 * to correctly parse the syntax, something that bison does not support. |
6904 * to correctly parse the syntax, something that bison does not support. |
7420 /* The following is not required, as the sendto_identifier_token returned by flex will |
7477 /* The following is not required, as the sendto_identifier_token returned by flex will |
7421 * also include the 'ENO' identifier. |
7478 * also include the 'ENO' identifier. |
7422 * The resulting abstract syntax tree is identical with or without this following rule, |
7479 * The resulting abstract syntax tree is identical with or without this following rule, |
7423 * as both the eno_identifier and the sendto_identifier are stored as |
7480 * as both the eno_identifier and the sendto_identifier are stored as |
7424 * an identifier_c !! |
7481 * an identifier_c !! |
|
7482 * |
|
7483 * To understand why we must even explicitly consider the use of ENO here, |
|
7484 * please read the comment above the definition of 'variable' in section B1.4 for details. |
7425 */ |
7485 */ |
7426 /* |
7486 /* |
7427 | eno_identifier SENDTO variable |
7487 | eno_identifier SENDTO variable |
7428 {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));} |
7488 {$$ = new output_variable_param_assignment_c(NULL, $1, $3, locloc(@$));} |
7429 */ |
7489 */ |
7434 /* The following is not required, as the sendto_identifier_token returned by flex will |
7494 /* The following is not required, as the sendto_identifier_token returned by flex will |
7435 * also include the 'ENO' identifier. |
7495 * also include the 'ENO' identifier. |
7436 * The resulting abstract syntax tree is identical with or without this following rule, |
7496 * The resulting abstract syntax tree is identical with or without this following rule, |
7437 * as both the eno_identifier and the sendto_identifier are stored as |
7497 * as both the eno_identifier and the sendto_identifier are stored as |
7438 * an identifier_c !! |
7498 * an identifier_c !! |
|
7499 * |
|
7500 * To understand why we must even explicitly consider the use of ENO here, |
|
7501 * please read the comment above the definition of 'variable' in section B1.4 for details. |
7439 */ |
7502 */ |
7440 /* |
7503 /* |
7441 | NOT eno_identifier SENDTO variable |
7504 | NOT eno_identifier SENDTO variable |
7442 {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));} |
7505 {$$ = new output_variable_param_assignment_c(new not_paramassign_c(locloc(@$)), $2, $4, locloc(@$));} |
7443 */ |
7506 */ |