Allow use of ENO keyword in structured variable field selector.
authorMario de Sousa <msousa@fe.up.pt>
Wed, 08 Jun 2011 11:42:19 +0100
changeset 315 c62a4078f269
parent 314 41d4ac0b4821
child 316 baa7a1585585
Allow use of ENO keyword in structured variable field selector.
main.cc
stage1_2/iec.y
--- 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;
--- 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