stage1_2/iec.flex
changeset 3 38850ee685e6
parent 1 5d893a68be6e
child 4 0d71456312ab
equal deleted inserted replaced
2:cecf2a950ec8 3:38850ee685e6
   169 #endif
   169 #endif
   170 
   170 
   171 
   171 
   172 /* Function only called from within flex, but defined
   172 /* Function only called from within flex, but defined
   173  * in iec.y!
   173  * in iec.y!
   174  * We delcare it here...
   174  * We declare it here...
   175  *
   175  *
   176  * Search for a symbol in either of the two symbol tables
   176  * Search for a symbol in either of the two symbol tables
   177  * and return the token id of the first symbol found.
   177  * and return the token id of the first symbol found.
   178  * Searches first in the variables, and only if not found
   178  * Searches first in the variables, and only if not found
   179  * does it continue searching in the library elements
   179  * does it continue searching in the library elements
   180  */
   180  */
   181 //token_id_t get_identifier_token(const char *identifier_str);
   181 //token_id_t get_identifier_token(const char *identifier_str);
   182 int get_identifier_token(const char *identifier_str);
   182 int get_identifier_token(const char *identifier_str);
       
   183 %}
       
   184 
       
   185 
       
   186 /*********************************************/
       
   187 /* Change parse state to body definitions... */
       
   188 /*********************************************/
       
   189 
       
   190 %{
       
   191 static int goto_body_state__ = 0;
       
   192 
       
   193 void cmd_goto_body_state(void) {goto_body_state__ = 1;}
       
   194 int  get_goto_body_state(void) {return goto_body_state__;}
       
   195 void rst_goto_body_state(void) {goto_body_state__ = 0;}
   183 %}
   196 %}
   184 
   197 
   185 
   198 
   186 /***************************************************/
   199 /***************************************************/
   187 /* Forward Declaration of functions defined later. */
   200 /* Forward Declaration of functions defined later. */
   268  * to make it easier to remove them later on if need be.
   281  * to make it easier to remove them later on if need be.
   269  * The body state returns any matched text back to the buffer with unput(),
   282  * The body state returns any matched text back to the buffer with unput(),
   270  * to be later matched correctly by the apropriate language parser (st or il).
   283  * to be later matched correctly by the apropriate language parser (st or il).
   271  * The state machine has 6 possible states (INITIAL, config, decl, body, st, il)
   284  * The state machine has 6 possible states (INITIAL, config, decl, body, st, il)
   272  * Possible state changes are:
   285  * Possible state changes are:
   273  *   INITIAL -> decl (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
   286  *   INITIAL -> decl_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
   274  *                    and followed by a VAR declaration)
   287  *                    and followed by a VAR declaration)
   275  *   INITIAL -> body (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
   288  *   INITIAL -> il_st_state (when a FUNCTION, FUNCTION_BLOCK, or PROGRAM is found,
   276  *                    and _not_ followed by a VAR declaration)
   289  *                    and _not_ followed by a VAR declaration)
   277  *   INITIAL -> config (when a CONFIGURATION is found)
   290  *   INITIAL -> config_state (when a CONFIGURATION is found)
   278  *   decl    -> body (when the last END_VAR is found, i.e. the function body starts)
   291  *   decl_state    -> il_st_state (when the last END_VAR is found, i.e. the function body starts)
   279  *   body    -> sfc (when it figures out it is parsing sfc language)
   292  *   il_st_state   -> sfc_state (when it figures out it is parsing sfc language)
   280  *   body    -> st (when it figures out it is parsing st language)
   293  *   il_st_state   -> st_state (when it figures out it is parsing st language)
   281  *   body    -> il (when it figures out it is parsing il language)
   294  *   il_st_state   -> il_state (when it figures out it is parsing il language)
   282  *   decl    -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   295  *   decl_state    -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   283  *   st      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   296  *   st_state      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   284  *   sfc     -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   297  *   sfc_state     -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   285  *   il      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   298  *   il_state      -> INITIAL (when a END_FUNCTION, END_FUNCTION_BLOCK, or END_PROGRAM is found)
   286  *   config  -> INITIAL (when a END_CONFIGURATION is found)
   299  *   config_state  -> INITIAL (when a END_CONFIGURATION is found)
   287  */
   300  */
   288 /* we are parsing a configuration. */
   301 /* we are parsing a configuration. */
   289 %s config
   302 %s config_state
   290 
   303 
   291 /* we are parsing a function, program or function block declaration */
   304 /* we are parsing a function, program or function block declaration */
   292 %s decl
   305 %s decl_state
   293 
   306 
   294 /* we will be parsing a function body. Whether il/st is remains unknown */
   307 /* we will be parsing a function body. Whether il/st is remains unknown */
   295 %x body
   308 %x il_st_state
   296 
   309 
   297 /* we are parsing il code -> flex must return the EOL tokens!       */
   310 /* we are parsing il code -> flex must return the EOL tokens!       */
   298 %s il
   311 %s il_state
   299 
   312 
   300 /* we are parsing st code -> flex must not return the EOL tokens!   */
   313 /* we are parsing st code -> flex must not return the EOL tokens!   */
   301 %s st
   314 %s st_state
   302 
   315 
   303 /* we are parsing sfc code -> flex must not return the EOL tokens!   */
   316 /* we are parsing sfc code -> flex must not return the EOL tokens!   */
   304 %s sfc
   317 %s sfc_state
   305 
   318 
   306 
   319 
   307 
   320 
   308 /*******************/
   321 /*******************/
   309 /* File #include's */
   322 /* File #include's */
   618 	/*****                                           *****/
   631 	/*****                                           *****/
   619 	/*****************************************************/
   632 	/*****************************************************/
   620 	/*****************************************************/
   633 	/*****************************************************/
   621 	/*****************************************************/
   634 	/*****************************************************/
   622 
   635 
       
   636   	if (goto_body_state__) {
       
   637     	yy_push_state(il_st_state);
       
   638     	goto_body_state__ = 0;
       
   639   	}
       
   640 
   623 	/*********************************/
   641 	/*********************************/
   624 	/* Handle the pragmas!     */
   642 	/* Handle the pragmas!     */
   625 	/*********************************/
   643 	/*********************************/
   626 
   644 
   627 	/* We start off by searching for the pragmas we handle in the lexical parser. */
   645 	/* We start off by searching for the pragmas we handle in the lexical parser. */
   632 {pragma}	{/* return the pragmma without the enclosing '{' and '}' */
   650 {pragma}	{/* return the pragmma without the enclosing '{' and '}' */
   633 		 yytext[strlen(yytext)-2] = '\0';
   651 		 yytext[strlen(yytext)-2] = '\0';
   634 		 yylval.ID=strdup(yytext+1);
   652 		 yylval.ID=strdup(yytext+1);
   635 		 return pragma_token;
   653 		 return pragma_token;
   636 		}
   654 		}
   637 <body>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
   655 <il_st_state>{pragma} {/* return the pragmma without the enclosing '{' and '}' */
   638 		 yytext[strlen(yytext)-2] = '\0';
   656 		 yytext[strlen(yytext)-2] = '\0';
   639 		 yylval.ID=strdup(yytext+1);
   657 		 yylval.ID=strdup(yytext+1);
   640 		 return pragma_token;
   658 		 return pragma_token;
   641 		}
   659 		}
   642 
   660 
   708 
   726 
   709 	/*********************************/
   727 	/*********************************/
   710 	/* Handle all the state changes! */
   728 	/* Handle all the state changes! */
   711 	/*********************************/
   729 	/*********************************/
   712 
   730 
   713 	/* INITIAL -> decl */
   731 	/* INITIAL -> decl_state */
   714 <INITIAL>{
   732 <INITIAL>{
   715 	/* NOTE: how about functions that do not delcare variables, and go directly to the body???
   733 	/* NOTE: how about functions that do not declare variables, and go directly to the il_st_state???
   716 	 *      - According to Section 2.5.1.3 (Function Declaration), item 2 in the list, a FUNCTION
   734 	 *      - According to Section 2.5.1.3 (Function Declaration), item 2 in the list, a FUNCTION
   717 	 *        must have at least one input argument, so a correct declaration will have at least
   735 	 *        must have at least one input argument, so a correct declaration will have at least
   718 	 *        one VAR_INPUT ... VAR_END construct!
   736 	 *        one VAR_INPUT ... VAR_END construct!
   719 	 *      - According to Section 2.5.2.2 (Function Block Declaration), a FUNCTION_BLOCK
   737 	 *      - According to Section 2.5.2.2 (Function Block Declaration), a FUNCTION_BLOCK
   720 	 *        must have at least one input argument, so a correct declaration will have at least
   738 	 *        must have at least one input argument, so a correct declaration will have at least
   722 	 *      - According to Section 2.5.3 (Programs), a PROGRAM must have at least one input
   740 	 *      - According to Section 2.5.3 (Programs), a PROGRAM must have at least one input
   723 	 *        argument, so a correct declaration will have at least one VAR_INPUT ... VAR_END
   741 	 *        argument, so a correct declaration will have at least one VAR_INPUT ... VAR_END
   724 	 *        construct!
   742 	 *        construct!
   725 	 *
   743 	 *
   726 	 *       All the above means that we needn't worry about PROGRAMs, FUNCTIONs or
   744 	 *       All the above means that we needn't worry about PROGRAMs, FUNCTIONs or
   727 	 *       FUNCTION_BLOCKs that do not have at least one VAR_END before the body.
   745 	 *       FUNCTION_BLOCKs that do not have at least one VAR_END before the il_st_state.
   728 	 *       If the code has an error, and no VAR_END before the body, we will simply
   746 	 *       If the code has an error, and no VAR_END before the body, we will simply
   729 	 *       continue in the <decl> state, untill the end of the FUNCTION, FUNCTION_BLOCK
   747 	 *       continue in the <decl_state> state, untill the end of the FUNCTION, FUNCTION_BLOCK
   730 	 *       or PROGAM.
   748 	 *       or PROGAM.
   731 	 */
   749 	 */
   732 FUNCTION				BEGIN(decl); return FUNCTION;
   750 FUNCTION				BEGIN(decl_state); return FUNCTION;
   733 FUNCTION_BLOCK				BEGIN(decl); return FUNCTION_BLOCK;
   751 FUNCTION_BLOCK				BEGIN(decl_state); return FUNCTION_BLOCK;
   734 PROGRAM					BEGIN(decl); return PROGRAM;
   752 PROGRAM					BEGIN(decl_state); return PROGRAM;
   735 CONFIGURATION				BEGIN(config); return CONFIGURATION;
   753 CONFIGURATION				BEGIN(config_state); return CONFIGURATION;
   736 }
   754 }
   737 
   755 
   738 	/* INITIAL -> body */
   756 	/* INITIAL -> il_st_state */
   739 	/* required if the function, program, etc.. has no VAR block! */
   757 	/* required if the function, program, etc.. has no VAR block! */
   740 <INITIAL>{
   758 <INITIAL>{
   741 FUNCTION	BEGIN(body); return FUNCTION;
   759 FUNCTION	BEGIN(il_st_state); return FUNCTION;
   742 FUNCTION_BLOCK	BEGIN(body); return FUNCTION_BLOCK;
   760 FUNCTION_BLOCK	BEGIN(il_st_state); return FUNCTION_BLOCK;
   743 PROGRAM		BEGIN(body); return PROGRAM;
   761 PROGRAM		BEGIN(il_st_state); return PROGRAM;
   744 }
   762 }
   745 
   763 
   746 	/* decl -> body */
   764 	/* decl_state -> il_st_state */
   747 <decl>{
   765 <decl_state>{
   748 END_VAR{st_whitespace}VAR			unput_text(strlen("END_VAR")); return END_VAR;
   766 END_VAR{st_whitespace}VAR			unput_text(strlen("END_VAR")); return END_VAR;
   749 END_VAR{st_whitespace}				unput_text(strlen("END_VAR")); BEGIN(body); return END_VAR;
   767 END_VAR{st_whitespace}				unput_text(strlen("END_VAR")); BEGIN(il_st_state); return END_VAR;
   750 }
   768 }
   751 
   769 
   752 	/* body -> (il | st | sfc) */
   770 	/* il_st_state -> (il_state | st_state | sfc_state) */
   753 <body>INITIAL_STEP				unput_text(0); BEGIN(sfc);
   771 <il_st_state>{
   754 
   772 INITIAL_STEP				unput_text(0); BEGIN(sfc_state);
   755 <body>{
   773 {qualified_identifier}{st_whitespace}":="	unput_text(0); BEGIN(st_state);
   756 {qualified_identifier}{st_whitespace}":="	unput_text(0); BEGIN(st);
   774 {qualified_identifier}"["			unput_text(0); BEGIN(st_state);
   757 {qualified_identifier}"["			unput_text(0); BEGIN(st);
   775 
   758 
   776 RETURN						unput_text(0); BEGIN(st_state);
   759 RETURN						unput_text(0); BEGIN(st);
   777 IF						unput_text(0); BEGIN(st_state);
   760 IF						unput_text(0); BEGIN(st);
   778 CASE						unput_text(0); BEGIN(st_state);
   761 CASE						unput_text(0); BEGIN(st);
   779 FOR						unput_text(0); BEGIN(st_state);
   762 FOR						unput_text(0); BEGIN(st);
   780 WHILE						unput_text(0); BEGIN(st_state);
   763 WHILE						unput_text(0); BEGIN(st);
   781 REPEAT						unput_text(0); BEGIN(st_state);
   764 REPEAT						unput_text(0); BEGIN(st);
   782 EXIT						unput_text(0); BEGIN(st_state);
   765 EXIT						unput_text(0); BEGIN(st);
   783 :=						unput_text(0); BEGIN(st_state);  /* occurs only in transitions, and not FB bodies! */
       
   784 
   766 
   785 
   767 
   786 
   768 {identifier}	{int token = get_identifier_token(yytext);
   787 {identifier}	{int token = get_identifier_token(yytext);
   769 		 if (token == prev_declared_fb_name_token) {
   788 		 if (token == prev_declared_fb_name_token) {
   770 		   /* the code has a call to a function block */
   789 		   /* the code has a call to a function block */
   771 		   BEGIN(st);
   790 		   BEGIN(st_state);
   772 		 } else {
   791 		 } else {
   773 		   BEGIN(il);
   792 		   BEGIN(il_state);
   774 		 }
   793 		 }
   775 		 unput_text(0);
   794 		 unput_text(0);
   776 		}
   795 		}
   777 .		unput_text(0); BEGIN(il);
   796 .		unput_text(0); BEGIN(il_state);
   778 
   797 
   779 }	/* end of body lexical parser */
   798 }	/* end of il_st_state lexical parser */
   780 
   799 
   781 	/* (decl | body | il | st | sfc) -> INITIAL */
   800 	/* (il_state | st_state) -> $previous_state (decl_state or sfc_state) */
       
   801 <il_state,st_state>{
       
   802 END_FUNCTION		yy_pop_state(); unput_text(0);
       
   803 END_FUNCTION_BLOCK	yy_pop_state(); unput_text(0);
       
   804 END_PROGRAM		yy_pop_state(); unput_text(0);
       
   805 END_TRANSITION		yy_pop_state(); unput_text(0);
       
   806 END_ACTION			yy_pop_state(); unput_text(0);
       
   807 }
       
   808 
       
   809 	/* (decl_state | sfc_state) -> INITIAL */
       
   810 <decl_state,sfc_state>{
   782 END_FUNCTION		BEGIN(INITIAL); return END_FUNCTION;
   811 END_FUNCTION		BEGIN(INITIAL); return END_FUNCTION;
   783 END_FUNCTION_BLOCK	BEGIN(INITIAL); return END_FUNCTION_BLOCK;
   812 END_FUNCTION_BLOCK	BEGIN(INITIAL); return END_FUNCTION_BLOCK;
   784 END_PROGRAM		BEGIN(INITIAL); return END_PROGRAM;
   813 END_PROGRAM		BEGIN(INITIAL); return END_PROGRAM;
   785 
   814 }
   786 	/* config -> INITIAL */
   815 	/* config -> INITIAL */
   787 END_CONFIGURATION	BEGIN(INITIAL); return END_CONFIGURATION;
   816 END_CONFIGURATION	BEGIN(INITIAL); return END_CONFIGURATION;
   788 
   817 
   789 
   818 
   790 
   819 
   791 	/***************************************/
   820 	/***************************************/
   792 	/* Next is to to remove all whitespace */
   821 	/* Next is to to remove all whitespace */
   793 	/***************************************/
   822 	/***************************************/
   794 	/* NOTE: pragmas are handled right at the beginning... */
   823 	/* NOTE: pragmas are handled right at the beginning... */
   795 
   824 
   796 <INITIAL,config,decl,st,sfc,body>{st_whitespace_no_pragma}	/* Eat any whitespace */
   825 <INITIAL,config_state,decl_state,st_state,sfc_state,il_st_state>{st_whitespace_no_pragma}	/* Eat any whitespace */
   797 <il,body>{il_whitespace_no_pragma}		/* Eat any whitespace */
   826 <il_state,il_st_state>{il_whitespace_no_pragma}		/* Eat any whitespace */
   798 
   827 
   799 
   828 
   800 	/*****************************************/
   829 	/*****************************************/
   801 	/* B.1.1 Letters, digits and identifiers */
   830 	/* B.1.1 Letters, digits and identifiers */
   802 	/*****************************************/
   831 	/*****************************************/
   998 	.* as other identifiers that may be used as variable names inside IL and ST programs.
  1027 	.* as other identifiers that may be used as variable names inside IL and ST programs.
   999 	 * They will have to be handled when we include parsing of SFC... For now, simply
  1028 	 * They will have to be handled when we include parsing of SFC... For now, simply
  1000 	 * ignore them!
  1029 	 * ignore them!
  1001 	 */
  1030 	 */
  1002 	 
  1031 	 
  1003 <sfc>{
  1032 <sfc_state>{
  1004 ACTION		return ACTION;
  1033 ACTION		return ACTION;
  1005 END_ACTION	return END_ACTION;
  1034 END_ACTION	return END_ACTION;
  1006 
  1035 
  1007 TRANSITION	return TRANSITION;
  1036 TRANSITION	return TRANSITION;
  1008 END_TRANSITION	return END_TRANSITION;
  1037 END_TRANSITION	return END_TRANSITION;
  1052 
  1081 
  1053 
  1082 
  1054 	/***********************************/
  1083 	/***********************************/
  1055 	/* B 2.1 Instructions and Operands */
  1084 	/* B 2.1 Instructions and Operands */
  1056 	/***********************************/
  1085 	/***********************************/
  1057 <il>\n		return EOL;
  1086 <il_state>\n		return EOL;
  1058 
  1087 
  1059 
  1088 
  1060 	/*******************/
  1089 	/*******************/
  1061 	/* B 2.2 Operators */
  1090 	/* B 2.2 Operators */
  1062 	/*******************/
  1091 	/*******************/
  1245 
  1274 
  1246 
  1275 
  1247 	/*****************************************/
  1276 	/*****************************************/
  1248 	/* B.1.1 Letters, digits and identifiers */
  1277 	/* B.1.1 Letters, digits and identifiers */
  1249 	/*****************************************/
  1278 	/*****************************************/
  1250 <st>{identifier}/({st_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
  1279 <st_state>{identifier}/({st_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
  1251 <il>{identifier}/({il_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
  1280 <il_state>{identifier}/({il_whitespace})"=>"	{yylval.ID=strdup(yytext); return sendto_identifier_token;}
  1252 {identifier} 				{yylval.ID=strdup(yytext);
  1281 {identifier} 				{yylval.ID=strdup(yytext);
  1253 					 /*printf("returning identifier...: %s, %d\n", yytext, get_identifier_token(yytext));*/
  1282 					 /*printf("returning identifier...: %s, %d\n", yytext, get_identifier_token(yytext));*/
  1254 					 return get_identifier_token(yytext);}
  1283 					 return get_identifier_token(yytext);}
  1255 
  1284 
  1256 
  1285 
  1276 	 */
  1305 	 */
  1277 .	{return yytext[0];}
  1306 .	{return yytext[0];}
  1278 
  1307 
  1279 
  1308 
  1280 %%
  1309 %%
  1281 
       
  1282 
       
  1283 
       
  1284 
  1310 
  1285 
  1311 
  1286 /***********************************/
  1312 /***********************************/
  1287 /* Utility function definitions... */
  1313 /* Utility function definitions... */
  1288 /***********************************/
  1314 /***********************************/