ST and IL parsing added into flex-bison analyser
authorlbessard
Wed, 31 Jan 2007 19:23:46 +0100
changeset 3 38850ee685e6
parent 2 cecf2a950ec8
child 4 0d71456312ab
ST and IL parsing added into flex-bison analyser
absyntax/absyntax.def
stage1_2/iec.flex
stage1_2/iec.y
stage4/generate_iec/generate_iec.cc
--- a/absyntax/absyntax.def	Wed Jan 31 16:04:06 2007 +0100
+++ b/absyntax/absyntax.def	Wed Jan 31 19:23:46 2007 +0100
@@ -571,7 +571,7 @@
 
 SYM_REF2(action_qualifier_c, action_qualifier, action_time)
 
-SYM_REF6(transition_c, transition_name, integer, from_steps, to_steps, transition_condition, unused)
+SYM_REF6(transition_c, transition_name, integer, from_steps, to_steps, transition_condition_il, transition_condition_st)
 
 SYM_REF2(steps_c, step_name, step_name_list)
 
--- 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... */
 /***********************************/
--- a/stage1_2/iec.y	Wed Jan 31 16:04:06 2007 +0100
+++ b/stage1_2/iec.y	Wed Jan 31 19:23:46 2007 +0100
@@ -168,7 +168,9 @@
 /************************/
 /* The functions declared here are defined in iec.flex... */
 void print_include_stack(void);
-
+void cmd_goto_body_state(void);
+int  get_goto_body_state(void);
+void rst_goto_body_state(void);
 
 %}
 
@@ -181,7 +183,13 @@
     struct {
       symbol_c	*first;
       symbol_c	*second;
-    } double_symbol; /* used by il_simple_operator_clash_il_operand */
+      symbol_c	*third;
+      symbol_c	*fourth;
+    } tmp_symbol; /* used as a temorary reference to symbols by:
+                                     il_simple_operator_clash_il_operand
+                                     transaction_tmp
+                                     action_tmp
+                             */
 }
 
 
@@ -809,7 +817,10 @@
 %type  <leaf>	transition
 %type  <leaf>	steps
 %type  <list>	step_name_list
-%type  <leaf>	transition_condition
+%type  <tmp_symbol> transition_header
+%type  <leaf>	transition_condition_il
+%type  <leaf>	transition_condition_st
+%type  <tmp_symbol> action_header
 %type  <leaf>	action
 %type  <leaf>	transition_name
 
@@ -946,7 +957,7 @@
 %type  <leaf>	label
 %type  <leaf>	il_simple_operation
 // helper symbol for il_simple_operation
-%type <double_symbol> il_simple_operator_clash_il_operand
+%type <tmp_symbol> il_simple_operator_clash_il_operand
 %type  <leaf>	il_expression
 %type  <leaf>	il_jump_operation
 %type  <leaf>	il_fb_call
@@ -3629,7 +3640,7 @@
 
 /********************************************/
 /* B 1.6 Sequential Function Chart elements *
-/********************************************/////////////////////////////////////////////////////////////////////////////////////////////
+/********************************************/
 /* TODO ... */
 
 sequential_function_chart:
@@ -3728,17 +3739,6 @@
 
 indicator_name: variable_name;
 
-transition:
-  TRANSITION FROM steps TO steps transition_condition END_TRANSITION
-	{$$ = new transition_c(NULL, NULL, $3, $5, $6, NULL);}
-| TRANSITION transition_name FROM steps TO steps transition_condition END_TRANSITION
-	{$$ = new transition_c($2, NULL, $4, $6, $7, NULL);}
-| TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
-	{$$ = new transition_c(NULL, $5, $8, $10, $11, NULL);}
-| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps transition_condition END_TRANSITION
-	{$$ = new transition_c($2, $6, $9, $11, $12, NULL);}
-;
-
 transition_name: identifier;
 
 steps:
@@ -3755,16 +3755,43 @@
 	{$$ = $1; $$->add_element($3);}
 ;
 
-transition_condition:
+transition_header:
+  TRANSITION FROM steps TO steps
+	{$$.first = NULL; $$.second = NULL; $$.third = $3; $$.fourth = $5; cmd_goto_body_state();}
+| TRANSITION transition_name FROM steps TO steps 
+	{$$.first = $2; $$.second = NULL; $$.third = $4; $$.fourth = $6; cmd_goto_body_state();}
+| TRANSITION '(' PRIORITY ASSIGN integer ')' FROM steps TO steps
+	{$$.first = NULL; $$.second = $5; $$.third = $8; $$.fourth = $10; cmd_goto_body_state();}
+| TRANSITION transition_name '(' PRIORITY ASSIGN integer ')' FROM steps TO steps
+	{$$.first = $2; $$.second = $6; $$.third = $9; $$.fourth = $11; cmd_goto_body_state();}
+;
+
+transition_condition_il:
   ':' simple_instr_list
-	{$$ = new transition_condition_c($2, NULL);} 
-| ASSIGN expression ';'
-	{$$ = new transition_condition_c(NULL, $2);} 
-;
+	{$$ = new transition_condition_c($2, NULL);} ;
+
+transition_condition_st:
+  ASSIGN expression ';'
+	{$$ = new transition_condition_c(NULL, $2);};
+
+transition:
+  transition_header transition_condition_il END_TRANSITION
+        {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, $2, 
+NULL);}
+|  transition_header transition_condition_st END_TRANSITION
+        {$$ = new transition_c($1.first, $1.second, $1.third, $1.fourth, NULL, 
+$2);}
+;
+
+action_header:
+  ACTION action_name ':' 
+	{$$.first = $2; cmd_goto_body_state();}
+;
+
 
 action:
-  ACTION action_name ':' function_block_body END_ACTION
-	{$$ = new action_c($2, $4);}
+  action_header function_block_body END_ACTION
+	{$$ = new action_c($1.first, $2);}
 ;
 
 
--- a/stage4/generate_iec/generate_iec.cc	Wed Jan 31 16:04:06 2007 +0100
+++ b/stage4/generate_iec/generate_iec.cc	Wed Jan 31 19:23:46 2007 +0100
@@ -1135,7 +1135,12 @@
   symbol->to_steps->accept(*this);
   s4o.indent_right();
   s4o.print(s4o.indent_spaces);
-  symbol->transition_condition->accept(*this);
+  if (symbol->transition_condition_il != NULL) {
+  	symbol->transition_condition_il->accept(*this);
+  }
+  if (symbol->transition_condition_st != NULL) {
+  	symbol->transition_condition_st->accept(*this);
+  }
   s4o.indent_left();
   s4o.print(s4o.indent_spaces);
   s4o.print("END_TRANSITION");