stage1_2/iec_flex.ll
changeset 868 23f271534a7c
parent 867 a435684a5223
child 869 d88f47549408
--- a/stage1_2/iec_flex.ll	Sun Feb 16 00:37:40 2014 +0000
+++ b/stage1_2/iec_flex.ll	Sun Feb 16 14:27:06 2014 +0000
@@ -356,23 +356,36 @@
  *       Unfortunately, flex will join '_' and '4h' to create a legal {identifier} '_4h',
  *       and return that identifier instead! So, we added this state!
  *
- * There is a main state machine (
- *    +------> INITIAL <-------> config
- *    |           \
- *    |           V
- *    |     header_state
- *    |           |
- *    |           V
- *    |  vardecl_list_state <------> var_decl
- *    |           | 
- *    |           V
- *    +----------body, 
- *                ^
- *                | 
- *    -----------------------
- *    |           |         |
- *    v           v         v
- *   st          il       sfc
+ * There is a main state machine...
+ * 
+ *       +---> INITIAL <-------> config
+ *       |        \
+ *       |        V
+ *       |   header_state
+ *       |        |
+ *       |        V
+ *     vardecl_list_state <------> var_decl
+ *       ^        | 
+ *       |        | [using push()]
+ *       |        |
+ *       |        V
+ *       |       body, 
+ *       |        |
+ *       |        | 
+ *       |   -------------------
+ *       |   |       |         |
+ *       |   v       v         v
+ *       |  st      il        sfc
+ *       |   |       |         |  [using pop() when leaving st/il/sfc => goes to vardecl_list_state]
+ *       |   |       |         |
+ *       -----------------------
+ *
+ * NOTE:- When inside sfc, and an action or transition in ST/IL is found, then 
+ *        we also push() to the body state. This means that sometimes, when pop()ing
+ *        from st and il, the state machine may return to the sfc state!
+ *      - The transitions form sfc to body will be decided by bison, which will
+ *        tell flex to do the transition by calling cmd_goto_body_state().
+ *   
  * 
  * Possible state changes are:
  *   INITIAL -> goto(config_state)
@@ -388,25 +401,25 @@
  *   vardecl_state -> pop() to (vardecl_list_state) 
  *                (when a END_VAR token is found)
  * 
- *   vardecl_list_state -> goto(body_state) 
+ *   vardecl_list_state -> push current state (vardecl_list_state), and goto(body_state) 
  *                (when the last END_VAR is found!)
  *
- *   body_state    -> push current state(body_state); goto(sfc_state)
+ *   body_state    -> goto(sfc_state)
  *                     (when it figures out it is parsing sfc language)
- *   body_state    -> push current state(body_state); goto(st_state)
+ *   body_state    -> goto(st_state)
  *                     (when it figures out it is parsing st language)
- *   body_state    -> push current state(body_state); goto(il_state)
+ *   body_state    -> goto(il_state)
  *                     (when it figures out it is parsing il language)
- *   st_state      -> pop() to body_sate
+ *   st_state      -> pop() to vardecl_list_state
  *                     (when a END_FUNCTION, END_FUNCTION_BLOCK, END_PROGRAM,
  *                      END_ACTION or END_TRANSITION is found)
- *   il_state      -> pop() to body_sate
+ *   il_state      -> pop() to vardecl_list_state
  *                     (when a END_FUNCTION, END_FUNCTION_BLOCK, END_PROGRAM,
  *                      END_ACTION or END_TRANSITION is found)
- *   sfc_state     -> pop() to body_sate
+ *   sfc_state     -> pop() to vardecl_list_state
  *                     (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
  * 
- *   body_sate -> goto(INITIAL)
+ *   vardecl_list_state -> goto(INITIAL)
  *                     (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
  *   config_state  -> goto(INITIAL)
  *                     (when a END_CONFIGURATION is found)
@@ -441,6 +454,7 @@
 %s task_init_state
 
 /* we are looking for the first VAR inside a function's, program's or function block's declaration */
+/* This is not exclusive (%x) as we must be able to parse the identifier and data types of a function/FB */
 %s header_state
 
 /* we are parsing a function, program or function block sequence of VAR..END_VAR delcarations */
@@ -448,7 +462,7 @@
 /* a substate of the vardecl_list_state: we are inside a specific VAR .. END_VAR */
 %s vardecl_state
 
-/* we will be parsing a function body. Whether il/st/sfc remains to be determined */
+/* we will be parsing a function body/action/transition. Whether il/st/sfc remains to be determined */
 %x body_state
 
 /* we are parsing il code -> flex must return the EOL tokens!       */
@@ -559,9 +573,8 @@
 
 /* Any other pragma... */
 pragma "{"[^}]*"}"|"{{"([^}]|"}"[^}])*"}}"
-/*
-pragma "{"[^}]*"}"
-*/
+
+
 
 /* COMMENTS */
 /* ======== */
@@ -798,7 +811,6 @@
  *       minutes      ::= fixed_point 'm' | integer 'm' ['_'] seconds
  *       seconds      ::= fixed_point 's' | integer 's' ['_'] milliseconds
  *       milliseconds ::= fixed_point 'ms'
-
  */
 
 interval_ms_X		({integer_0_999}(\.{integer})?)ms
@@ -924,7 +936,7 @@
 	/* Any other pragma we find, we just pass it up to the syntax parser...   */
 	/* Note that the <body_state> state is exclusive, so we have to include it here too. */
 {pragma}	{/* return the pragmma without the enclosing '{' and '}' */
-         int cut = yytext[1]=='{'?2:1;
+		 int cut = yytext[1]=='{'?2:1;
 		 yytext[strlen(yytext)-cut] = '\0';
 		 yylval.ID=strdup(yytext+cut);
 		 return pragma_token;
@@ -1034,9 +1046,9 @@
 	 *       continue in the <vardecl_state> state, untill the end of the FUNCTION, FUNCTION_BLOCK
 	 *       or PROGAM.
 	 */
-FUNCTION				BEGIN(header_state); return FUNCTION;
-FUNCTION_BLOCK				BEGIN(header_state); return FUNCTION_BLOCK;
-PROGRAM					BEGIN(header_state); return PROGRAM;
+FUNCTION				yy_push_state(header_state); return FUNCTION;
+FUNCTION_BLOCK				yy_push_state(header_state); return FUNCTION_BLOCK;
+PROGRAM					yy_push_state(header_state); return PROGRAM;
 CONFIGURATION				BEGIN(config_state); return CONFIGURATION;
 }
 
@@ -1054,65 +1066,84 @@
 }
 	*/
 
-	/* header_state -> (vardecl_state | body_state) */
+	/* header_state -> (vardecl_list_state) */
 <header_state>{
-VAR				unput_text(0); BEGIN(vardecl_list_state);
-}
-
-
+VAR				| /* execute the next rule's action, i.e. fall-through! */
+VAR_INPUT			|
+VAR_OUTPUT			|
+VAR_IN_OUT			|
+VAR_EXTERNAL			|
+VAR_GLOBAL			|
+VAR_TEMP			|
+VAR_CONFIG			|
+VAR_ACCESS			unput_text(0); BEGIN(vardecl_list_state);
+}
+
+
+	/* vardecl_list_state -> (vardecl_state | body_state | INITIAL) */
 <vardecl_list_state>{
+VAR_INPUT			| /* execute the next rule's action, i.e. fall-through! */
+VAR_OUTPUT			|
+VAR_IN_OUT			|
+VAR_EXTERNAL			|
+VAR_GLOBAL			|
+VAR_TEMP			|
+VAR_CONFIG			|
+VAR_ACCESS			|
 VAR				unput_text(0); yy_push_state(vardecl_state);
-.				unput_text(0); BEGIN(body_state); /* anything else, just change to body_state! */
-}
-
-
+
+END_FUNCTION			unput_text(0); BEGIN(INITIAL); 
+END_FUNCTION_BLOCK		unput_text(0); BEGIN(INITIAL); 
+END_PROGRAM			unput_text(0); BEGIN(INITIAL); 
+
+.				unput_text(0); yy_push_state(body_state); /* anything else, just change to body_state! */
+}
+
+
+	/* vardecl_list_state -> pop to $previous_state (vardecl_list_state) */
 <vardecl_state>{
 END_VAR				yy_pop_state(); return END_VAR; /* pop back to header_state */
 }
 
 
-	/* body_state -> (il_state | st_state) */
+	/* body_state -> (il_state | st_state | sfc_state) */
 <body_state>{
-END_FUNCTION			BEGIN(INITIAL); return END_FUNCTION;
-END_FUNCTION_BLOCK		BEGIN(INITIAL); return END_FUNCTION_BLOCK;
-END_PROGRAM			BEGIN(INITIAL); return END_PROGRAM;
-
-INITIAL_STEP			unput_text(0); yy_push_state(sfc_state); 
-
-{qualified_identifier}		unput_text(0); yy_push_state(st_state); /* will always be followed by '[' for an array access, or ':=' as the left hand of an assignment statement */
-{direct_variable_standard}	unput_text(0); yy_push_state(st_state); /* will always be followed by ':=' as the left hand of an assignment statement */
-
-RETURN				unput_text(0); yy_push_state(st_state);
-IF				unput_text(0); yy_push_state(st_state);
-CASE				unput_text(0); yy_push_state(st_state);
-FOR				unput_text(0); yy_push_state(st_state);
-WHILE				unput_text(0); yy_push_state(st_state);
-EXIT				unput_text(0); yy_push_state(st_state);
-REPEAT				unput_text(0); yy_push_state(st_state);
+INITIAL_STEP			unput_text(0); BEGIN(sfc_state); 
+
+{qualified_identifier}		unput_text(0); BEGIN(st_state); /* will always be followed by '[' for an array access, or ':=' as the left hand of an assignment statement */
+{direct_variable_standard}	unput_text(0); BEGIN(st_state); /* will always be followed by ':=' as the left hand of an assignment statement */
+
+RETURN				unput_text(0); BEGIN(st_state);
+IF				unput_text(0); BEGIN(st_state);
+CASE				unput_text(0); BEGIN(st_state);
+FOR				unput_text(0); BEGIN(st_state);
+WHILE				unput_text(0); BEGIN(st_state);
+EXIT				unput_text(0); BEGIN(st_state);
+REPEAT				unput_text(0); BEGIN(st_state);
 
 	/* ':=' occurs only in transitions, and not Function or FB bodies! */
-:=				unput_text(0); yy_push_state(st_state);
+:=				unput_text(0); BEGIN(st_state);
 
 {identifier}	{int token = get_identifier_token(yytext);
 		 if ((token == prev_declared_fb_name_token) || (token == prev_declared_variable_name_token)) {
 		   /* the code has a call to a function block OR has an assingment with a variable as the lvalue */
-		   unput_text(0); yy_push_state(st_state);
+		   unput_text(0); BEGIN(st_state);
 		 } else
  		 if (token == prev_declared_derived_function_name_token) {
 		   /* the code has a call to a function - must be IL */
-		   unput_text(0); yy_push_state(il_state);
+		   unput_text(0); BEGIN(il_state);
 		 } else {
 		   /* Might be a lable in IL, or a bug in ST/IL code. We jump to IL */
-		   unput_text(0); yy_push_state(il_state);
+		   unput_text(0); BEGIN(il_state);
 		 }
 		}
 
-.		unput_text(0); yy_push_state(il_state); /* Don't know what it could be. This is most likely a bug. Let's just to a random state... */
+.		unput_text(0); BEGIN(il_state); /* Don't know what it could be. This is most likely a bug. Let's just to a random state... */
 }	/* end of body_state lexical parser */
 
 
 
-	/* (il_state | st_state) -> $previous_state (vardecl_state or sfc_state) */
+	/* (il_state | st_state) -> pop to $previous_state (vardecl_list_state or sfc_state) */
 <il_state,st_state>{
 END_FUNCTION		yy_pop_state(); unput_text(0);
 END_FUNCTION_BLOCK	yy_pop_state(); unput_text(0);
@@ -1121,7 +1152,7 @@
 END_ACTION		yy_pop_state(); unput_text(0);
 }
 
-	/* sfc_state -> INITIAL */
+	/* sfc_state -> pop to $previous_state (vardecl_list_state or sfc_state) */
 <sfc_state>{
 END_FUNCTION		yy_pop_state(); unput_text(0);
 END_FUNCTION_BLOCK	yy_pop_state(); unput_text(0);