stage1_2/iec.flex
changeset 3 38850ee685e6
parent 1 5d893a68be6e
child 4 0d71456312ab
--- a/stage1_2/iec.flex	Wed Jan 31 16:04:06 2007 +0100
+++ b/stage1_2/iec.flex	Wed Jan 31 19:23:46 2007 +0100
@@ -171,7 +171,7 @@
 
 /* Function only called from within flex, but defined
  * in iec.y!
- * We delcare it here...
+ * We declare it here...
  *
  * Search for a symbol in either of the two symbol tables
  * and return the token id of the first symbol found.
@@ -183,6 +183,19 @@
 %}
 
 
+/*********************************************/
+/* Change parse state to body definitions... */
+/*********************************************/
+
+%{
+static int goto_body_state__ = 0;
+
+void cmd_goto_body_state(void) {goto_body_state__ = 1;}
+int  get_goto_body_state(void) {return goto_body_state__;}
+void rst_goto_body_state(void) {goto_body_state__ = 0;}
+%}
+
+
 /***************************************************/
 /* Forward Declaration of functions defined later. */
 /***************************************************/
@@ -270,38 +283,38 @@
  * to be later matched correctly by the apropriate language parser (st or il).
  * The state machine has 6 possible states (INITIAL, config, decl, body, st, il)
  * Possible state changes are:
- *   INITIAL -> decl (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
+ *   INITIAL -> decl_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
  *                    and followed by a VAR declaration)
- *   INITIAL -> body (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
+ *   INITIAL -> il_st_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
  *                    and _not_ followed by a VAR declaration)
- *   INITIAL -> config (when a CONFIGURATION is found)
- *   decl    -> body (when the last END_VAR is found, i.e. the function body starts)
- *   body    -> sfc (when it figures out it is parsing sfc language)
- *   body    -> st (when it figures out it is parsing st language)
- *   body    -> il (when it figures out it is parsing il language)
- *   decl    -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- *   st      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- *   sfc     -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- *   il      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
- *   config  -> INITIAL (when a END_CONFIGURATION is found)
+ *   INITIAL -> config_state (when a CONFIGURATION is found)
+ *   decl_state    -> il_st_state (when the last END_VAR is found, i.e. the function body starts)
+ *   il_st_state   -> sfc_state (when it figures out it is parsing sfc language)
+ *   il_st_state   -> st_state (when it figures out it is parsing st language)
+ *   il_st_state   -> il_state (when it figures out it is parsing il language)
+ *   decl_state    -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ *   st_state      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ *   sfc_state     -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ *   il_state      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
+ *   config_state  -> INITIAL (when a END_CONFIGURATION is found)
  */
 /* we are parsing a configuration. */
-%s config
+%s config_state
 
 /* we are parsing a function, program or function block declaration */
-%s decl
+%s decl_state
 
 /* we will be parsing a function body. Whether il/st is remains unknown */
-%x body
+%x il_st_state
 
 /* we are parsing il code -> flex must return the EOL tokens!       */
-%s il
+%s il_state
 
 /* we are parsing st code -> flex must not return the EOL tokens!   */
-%s st
+%s st_state
 
 /* we are parsing sfc code -> flex must not return the EOL tokens!   */
-%s sfc
+%s sfc_state
 
 
 
@@ -620,6 +633,11 @@
 	/*****************************************************/
 	/*****************************************************/
 
+  	if (goto_body_state__) {
+    	yy_push_state(il_st_state);
+    	goto_body_state__ = 0;
+  	}
+
 	/*********************************/
 	/* Handle the pragmas!     */
 	/*********************************/
@@ -634,7 +652,7 @@
 		 yylval.ID=strdup(yytext+1);
 		 return pragma_token;
 		}
-<body>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
+<il_st_state>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
 		 yytext[strlen(yytext)-2] = '\0';
 		 yylval.ID=strdup(yytext+1);
 		 return pragma_token;
@@ -710,9 +728,9 @@
 	/* Handle all the state changes! */
 	/*********************************/
 
-	/* INITIAL -> decl */
+	/* INITIAL -> decl_state */
 <INITIAL>{
-	/* NOTE: how about functions that do not delcare variables, and go directly to the body???
+	/* NOTE: how about functions that do not declare variables, and go directly to the il_st_state???
 	 *      - According to Section 2.5.1.3 (Function Declaration), item 2 in the list, a FUNCTION
 	 *        must have at least one input argument, so a correct declaration will have at least
 	 *        one VAR_INPUT ... VAR_END construct!
@@ -724,65 +742,76 @@
 	 *        construct!
 	 *
 	 *       All the above means that we needn't worry about PROGRAMs, FUNCTIONs or
-	 *       FUNCTION_BLOCKs that do not have at least one VAR_END before the body.
+	 *       FUNCTION_BLOCKs that do not have at least one VAR_END before the il_st_state.
 	 *       If the code has an error, and no VAR_END before the body, we will simply
-	 *       continue in the <decl> state, untill the end of the FUNCTION, FUNCTION_BLOCK
+	 *       continue in the <decl_state> state, untill the end of the FUNCTION, FUNCTION_BLOCK
 	 *       or PROGAM.
 	 */
-FUNCTION				BEGIN(decl); return FUNCTION;
-FUNCTION_BLOCK				BEGIN(decl); return FUNCTION_BLOCK;
-PROGRAM					BEGIN(decl); return PROGRAM;
-CONFIGURATION				BEGIN(config); return CONFIGURATION;
+FUNCTION				BEGIN(decl_state); return FUNCTION;
+FUNCTION_BLOCK				BEGIN(decl_state); return FUNCTION_BLOCK;
+PROGRAM					BEGIN(decl_state); return PROGRAM;
+CONFIGURATION				BEGIN(config_state); return CONFIGURATION;
 }
 
-	/* INITIAL -> body */
+	/* INITIAL -> il_st_state */
 	/* required if the function, program, etc.. has no VAR block! */
 <INITIAL>{
-FUNCTION	BEGIN(body); return FUNCTION;
-FUNCTION_BLOCK	BEGIN(body); return FUNCTION_BLOCK;
-PROGRAM		BEGIN(body); return PROGRAM;
+FUNCTION	BEGIN(il_st_state); return FUNCTION;
+FUNCTION_BLOCK	BEGIN(il_st_state); return FUNCTION_BLOCK;
+PROGRAM		BEGIN(il_st_state); return PROGRAM;
 }
 
-	/* decl -> body */
-<decl>{
+	/* decl_state -> il_st_state */
+<decl_state>{
 END_VAR{st_whitespace}VAR			unput_text(strlen("END_VAR")); return END_VAR;
-END_VAR{st_whitespace}				unput_text(strlen("END_VAR")); BEGIN(body); return END_VAR;
+END_VAR{st_whitespace}				unput_text(strlen("END_VAR")); BEGIN(il_st_state); return END_VAR;
 }
 
-	/* body -> (il | st | sfc) */
-<body>INITIAL_STEP				unput_text(0); BEGIN(sfc);
-
-<body>{
-{qualified_identifier}{st_whitespace}":="	unput_text(0); BEGIN(st);
-{qualified_identifier}"["			unput_text(0); BEGIN(st);
-
-RETURN						unput_text(0); BEGIN(st);
-IF						unput_text(0); BEGIN(st);
-CASE						unput_text(0); BEGIN(st);
-FOR						unput_text(0); BEGIN(st);
-WHILE						unput_text(0); BEGIN(st);
-REPEAT						unput_text(0); BEGIN(st);
-EXIT						unput_text(0); BEGIN(st);
+	/* il_st_state -> (il_state | st_state | sfc_state) */
+<il_st_state>{
+INITIAL_STEP				unput_text(0); BEGIN(sfc_state);
+{qualified_identifier}{st_whitespace}":="	unput_text(0); BEGIN(st_state);
+{qualified_identifier}"["			unput_text(0); BEGIN(st_state);
+
+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);
+REPEAT						unput_text(0); BEGIN(st_state);
+EXIT						unput_text(0); BEGIN(st_state);
+:=						unput_text(0); BEGIN(st_state);  /* occurs only in transitions, and not FB bodies! */
+
 
 
 {identifier}	{int token = get_identifier_token(yytext);
 		 if (token == prev_declared_fb_name_token) {
 		   /* the code has a call to a function block */
-		   BEGIN(st);
+		   BEGIN(st_state);
 		 } else {
-		   BEGIN(il);
+		   BEGIN(il_state);
 		 }
 		 unput_text(0);
 		}
-.		unput_text(0); BEGIN(il);
-
-}	/* end of body lexical parser */
-
-	/* (decl | body | il | st | sfc) -> INITIAL */
+.		unput_text(0); BEGIN(il_state);
+
+}	/* end of il_st_state lexical parser */
+
+	/* (il_state | st_state) -> $previous_state (decl_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);
+END_PROGRAM		yy_pop_state(); unput_text(0);
+END_TRANSITION		yy_pop_state(); unput_text(0);
+END_ACTION			yy_pop_state(); unput_text(0);
+}
+
+	/* (decl_state | sfc_state) -> INITIAL */
+<decl_state,sfc_state>{
 END_FUNCTION		BEGIN(INITIAL); return END_FUNCTION;
 END_FUNCTION_BLOCK	BEGIN(INITIAL); return END_FUNCTION_BLOCK;
 END_PROGRAM		BEGIN(INITIAL); return END_PROGRAM;
-
+}
 	/* config -> INITIAL */
 END_CONFIGURATION	BEGIN(INITIAL); return END_CONFIGURATION;
 
@@ -793,8 +822,8 @@
 	/***************************************/
 	/* NOTE: pragmas are handled right at the beginning... */
 
-<INITIAL,config,decl,st,sfc,body>{st_whitespace_no_pragma}	/* Eat any whitespace */
-<il,body>{il_whitespace_no_pragma}		/* Eat any whitespace */
+<INITIAL,config_state,decl_state,st_state,sfc_state,il_st_state>{st_whitespace_no_pragma}	/* Eat any whitespace */
+<il_state,il_st_state>{il_whitespace_no_pragma}		/* Eat any whitespace */
 
 
 	/*****************************************/
@@ -1000,7 +1029,7 @@
 	 * ignore them!
 	 */
 	 
-<sfc>{
+<sfc_state>{
 ACTION		return ACTION;
 END_ACTION	return END_ACTION;
 
@@ -1054,7 +1083,7 @@
 	/***********************************/
 	/* B 2.1 Instructions and Operands */
 	/***********************************/
-<il>\n		return EOL;
+<il_state>\n		return EOL;
 
 
 	/*******************/
@@ -1247,8 +1276,8 @@
 	/*****************************************/
 	/* B.1.1 Letters, digits and identifiers */
 	/*****************************************/
-<st>{identifier}/({st_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
-<il>{identifier}/({il_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
+<st_state>{identifier}/({st_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
+<il_state>{identifier}/({il_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
 {identifier} 				{yylval.ID=strdup(yytext);
 					 /*printf("returning identifier...: %s, %d\n", yytext, get_identifier_token(yytext));*/
 					 return get_identifier_token(yytext);}
@@ -1280,9 +1309,6 @@
 %%
 
 
-
-
-
 /***********************************/
 /* Utility function definitions... */
 /***********************************/