# HG changeset patch # User Mario de Sousa # Date 1307529739 -3600 # Node ID c62a4078f2690f362cc4e78001c234631de486ee # Parent 41d4ac0b4821d8f7ea58109f23b9f1a81b50dceb Allow use of ENO keyword in structured variable field selector. diff -r 41d4ac0b4821 -r c62a4078f269 main.cc --- a/main.cc Mon Jun 06 16:28:41 2011 +0200 +++ b/main.cc Wed Jun 08 11:42:19 2011 +0100 @@ -182,10 +182,12 @@ return EXIT_FAILURE; /* 2nd Pass */ - absyntax_utils_init(tree_root); - add_en_eno_param_decl_c::add_to(tree_root); - - /* not yet implemented... */ + /* basically loads some symbol tables to speed up look ups later on */ + absyntax_utils_init(tree_root); + /* moved to bison, although it could perfectly well still be here instead of in bison code. */ + //add_en_eno_param_decl_c::add_to(tree_root); + + /* Only very simple (not yet complete) data type checking currently implemented... */ if (stage3(tree_root) < 0) return EXIT_FAILURE; @@ -195,6 +197,7 @@ return EXIT_FAILURE; /* 4th Pass */ + /* Call gcc, g++, or whatever... */ /* Currently implemented in the Makefile! */ return 0; diff -r 41d4ac0b4821 -r c62a4078f269 stage1_2/iec.y --- a/stage1_2/iec.y Mon Jun 06 16:28:41 2011 +0200 +++ b/stage1_2/iec.y Wed Jun 08 11:42:19 2011 +0100 @@ -91,6 +91,8 @@ #include "stage1_2_priv.hh" +#include "../absyntax_utils/add_en_eno_param_decl.hh" /* required for add_en_eno_param_decl_c */ + /* an ugly hack!! * We will probably not need it when we decide * to cut down the abstract syntax down to size. @@ -387,6 +389,8 @@ * missing from the standard. However, their location in the annex B is * relatively obvious, so they have been inserted in what seems to us their * correct place in order to ease understanding of the parser... + * + * please read the comment above the definition of 'variable' in section B1.4 for details. */ %token EN %token ENO @@ -3234,18 +3238,53 @@ /*********************/ /* NOTE: The standard is erroneous in it's definition of 'variable' because: * - The standard considers 'ENO' as a keyword... - * - ...which means that it may never be parsed as an 'identifier'... - * - ...and therefore may never be used as the name of a variable inside an expression. + * - ...=> which means that it may never be parsed as an 'identifier'... + * - ...=> and therefore may never be used as the name of a variable inside an expression. * - However, a function/FB must be able to assign the ENO parameter * it's value, doing it in an assignment statement, and therefore using the 'ENO' * character sequence as an identifier! - * The solution we found was to also allow the ENO keyword to be + * The obvious solution is to also allow the ENO keyword to be * used as the name of a variable. Note that this variable may be used * even though it is not explicitly declared as a function/FB variable, * as the standard requires us to define it implicitly in this case! - * We could not therefore handle the ENO as a normal variable that would - * go into the previously_declared_variable symbol table, as we may need to - * allow it to be used as a variable even though it is not declared as such! + * There are three ways of achieving this: + * (i) simply not define EN and ENO as keywords in flex (lexical analyser) + * and let them be considered 'identifiers'. Aditionally, add some code + * so that if they are not explicitly declared, we add them automatically to + * the declaration of each Functions and FB, where they would then be parsed + * as a previously_declared_variable. + * This approach has the advantage the EN and ENO would automatically be valid + * in every location where it needs to be valid, namely in the explicit declaration + * of these same variables, or when they are used within expressions. + * However, this approach has the drawback that + * EN and ENO could then also be used anywhere a standard identifier is allowed, + * including in the naming of Functions, FBs, Programs, Configurations, Resources, + * SFC Actions, SFC Steps, etc... + * This would mean that we would then have to add a lexical analysis check + * within the bison code (syntax analyser) to all the above constructs to make sure + * that the identifier being used is not EN or ENO. + * (ii) The other approach is to define EN and ENO as keywords / tokens in flex + * (lexical analyser) and then change the syntax in bison to acomodate + * these tokens wherever they could correctly appear. + * This has the drawback that we need to do some changes to the synax defintion. + * (iii) Yet a another option is to mix the above two methods. + * Define EN and ENO as tokens in flex, but change (only) the syntax for + * variable declaration to allow these tokens to also be used in declaring variables. + * From this point onwards these tokens are then considered a previously_declared_variable, + * since flex will first check for this before even checking for tokens. + * + * I (Mario) cuurretnly (2011) believe the cleanest method of achieving this goal + * is to use option (iii) + * However, considering that: + * - I have already previously implemented option (ii); + * - option (iii) requires that flex parse the previously_declared_variable + * before parsing any token. We already support this (remeber that this is + * used mainly to allow some IL operators as well as PRIORITY, etc. tokens + * to be used as identifiers, since the standard does not define them as keywords), + * but this part of the code in flex is often commented out as usually people do not expect + * us to follow the standard in the strict sense, but rather consider those + * tokens as keywords; + * considering the above, we currently carry on using option (ii). */ variable: symbolic_variable @@ -3379,7 +3418,10 @@ ; -field_selector: any_identifier; +field_selector: + any_identifier +| eno_identifier +; @@ -3484,6 +3526,8 @@ * The semantic description of the languages clearly states that these may be * used in several ways. One of them is to declare an EN input parameter. * We have added the 'en_param_declaration' clause to cover for this. + * + * Please read the comment above the definition of 'variable' in section B1.4 for details. */ en_param_declaration: en_identifier ':' BOOL ASSIGN boolean_literal @@ -3705,6 +3749,8 @@ * as it does not allow a user defined 'ENO' output parameter. However, * The semantic description of the languages clearly states that this is allowed. * We have added the 'eno_param_declaration' clause to cover for this. + * + * Please read the comment above the definition of 'variable' in section B1.4 for details. */ var_output_init_decl: var_init_decl @@ -3730,6 +3776,8 @@ * The semantic description of the languages clearly states that these may be * used in several ways. One of them is to declare an ENO output parameter. * We have added the 'eno_param_declaration' clause to cover for this. + * + * Please read the comment above the definition of 'variable' in section B1.4 for details. */ eno_param_declaration: eno_identifier ':' BOOL @@ -4629,6 +4677,7 @@ /* FUNCTION derived_function_name ':' elementary_type_name io_OR_function_var_declarations_list function_body END_FUNCTION */ 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(@$)); + 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(); if (allow_function_overloading) { @@ -4651,6 +4700,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(@$)); + 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(); if (allow_function_overloading) { @@ -4861,6 +4911,7 @@ function_block_declaration: 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(@$)); + add_en_eno_param_decl_c::add_to($$); /* add EN and ENO declarations, if not already there */ library_element_symtable.insert($2, prev_declared_derived_function_block_name_token); /* Clear the variable_name_symtable. Since * we have finished parsing the function block, @@ -6827,6 +6878,9 @@ * The resulting abstract syntax tree is identical with or without this following rule, * as both the eno_identifier and the sendto_identifier are stored as * an identifier_c !! + * + * To understand why we must even explicitly consider the use of ENO here, + * please read the comment above the definition of 'variable' in section B1.4 for details. */ /* | eno_identifier SENDTO @@ -6841,6 +6895,9 @@ * as both the eno_identifier and the sendto_identifier are stored as * an identifier_c !! * + * To understand why we must even explicitly consider the use of ENO here, + * please read the comment above the definition of 'variable' in section B1.4 for details. + * * NOTE: Removing the following rule also removes a shift/reduce conflict from the parser. * This conflict is not really an error/ambiguity in the syntax, but rather * due to the fact that more than a single look-ahead token would be required @@ -7422,6 +7479,9 @@ * The resulting abstract syntax tree is identical with or without this following rule, * as both the eno_identifier and the sendto_identifier are stored as * an identifier_c !! + * + * To understand why we must even explicitly consider the use of ENO here, + * please read the comment above the definition of 'variable' in section B1.4 for details. */ /* | eno_identifier SENDTO variable @@ -7436,6 +7496,9 @@ * The resulting abstract syntax tree is identical with or without this following rule, * as both the eno_identifier and the sendto_identifier are stored as * an identifier_c !! + * + * To understand why we must even explicitly consider the use of ENO here, + * please read the comment above the definition of 'variable' in section B1.4 for details. */ /* | NOT eno_identifier SENDTO variable