Correctly identify errors when parsing erroneous code (make sure flex goes back to INITIAL state when code contains errors that do not allow determining whether ST or IL is being parsed)
authormjsousa
Sat, 07 May 2016 21:17:49 +0100
changeset 1010 242907849850
parent 1004 c25446920923
child 1011 76175defb87b
Correctly identify errors when parsing erroneous code (make sure flex goes back to INITIAL state when code contains errors that do not allow determining whether ST or IL is being parsed)
stage1_2/iec_flex.ll
--- a/stage1_2/iec_flex.ll	Fri Oct 02 10:31:20 2015 +0100
+++ b/stage1_2/iec_flex.ll	Sat May 07 21:17:49 2016 +0100
@@ -1101,9 +1101,9 @@
 
 <ignore_pou_state>{
 END_FUNCTION			unput_text(0); BEGIN(INITIAL);
-END_FUNCTION_BLOCK		unput_text(0); BEGIN(INITIAL); 
-END_PROGRAM			unput_text(0); BEGIN(INITIAL); 
-END_CONFIGURATION		unput_text(0); BEGIN(INITIAL); 
+END_FUNCTION_BLOCK		unput_text(0); BEGIN(INITIAL);
+END_PROGRAM			unput_text(0); BEGIN(INITIAL);
+END_CONFIGURATION		unput_text(0); BEGIN(INITIAL);
 .|\n				{}/* Ignore text inside POU! (including the '\n' character!)) */
 }
 
@@ -1147,9 +1147,9 @@
 VAR_ACCESS			|
 VAR				unput_text(0); yy_push_state(vardecl_state);
 
-END_FUNCTION			unput_text(0); BEGIN(INITIAL); 
-END_FUNCTION_BLOCK		unput_text(0); BEGIN(INITIAL); 
-END_PROGRAM			unput_text(0); BEGIN(INITIAL); 
+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! */
 }
@@ -1480,28 +1480,49 @@
 	/***********************/
 	/* B 1.5.1 - Functions */
 	/***********************/
-FUNCTION	return FUNCTION;	/* Keyword */
-END_FUNCTION	return END_FUNCTION;	/* Keyword */
-VAR		return VAR;		/* Keyword */
-CONSTANT	return CONSTANT;	/* Keyword */
+	/* Note: The following END_FUNCTION rule includes a BEGIN(INITIAL); command.
+	 *       This is necessary in case the input program being pased has syntax errors that force
+	 *       flex's main state machine to never change to the il_state or the st_state
+	 *       after changing to the body_state.
+	 *       Ths BEGIN(INITIAL) command forces the flex state machine to re-synchronise with 
+	 *       the input stream even in the presence of buggy code!
+	 */
+FUNCTION			return FUNCTION;			/* Keyword */
+END_FUNCTION	BEGIN(INITIAL);	return END_FUNCTION;			/* Keyword */  /* see Note above */
+VAR				return VAR;				/* Keyword */
+CONSTANT			return CONSTANT;			/* Keyword */
 
 
 	/*****************************/
 	/* B 1.5.2 - Function Blocks */
 	/*****************************/
-FUNCTION_BLOCK		return FUNCTION_BLOCK;		/* Keyword */
-END_FUNCTION_BLOCK	return END_FUNCTION_BLOCK;	/* Keyword */
-VAR_TEMP		return VAR_TEMP;		/* Keyword */
-VAR			return VAR;			/* Keyword */
-NON_RETAIN		return NON_RETAIN;		/* Keyword */
-END_VAR			return END_VAR;			/* Keyword */
+	/* Note: The following END_FUNCTION_BLOCK rule includes a BEGIN(INITIAL); command.
+	 *       This is necessary in case the input program being pased has syntax errors that force
+	 *       flex's main state machine to never change to the il_state or the st_state
+	 *       after changing to the body_state.
+	 *       Ths BEGIN(INITIAL) command forces the flex state machine to re-synchronise with 
+	 *       the input stream even in the presence of buggy code!
+	 */
+FUNCTION_BLOCK				return FUNCTION_BLOCK;		/* Keyword */
+END_FUNCTION_BLOCK	BEGIN(INITIAL);	return END_FUNCTION_BLOCK;	/* Keyword */  /* see Note above */
+VAR_TEMP				return VAR_TEMP;		/* Keyword */
+VAR					return VAR;			/* Keyword */
+NON_RETAIN				return NON_RETAIN;		/* Keyword */
+END_VAR					return END_VAR;			/* Keyword */
 
 
 	/**********************/
 	/* B 1.5.3 - Programs */
 	/**********************/
-PROGRAM		return PROGRAM;			/* Keyword */
-END_PROGRAM	return END_PROGRAM;		/* Keyword */
+	/* Note: The following END_PROGRAM rule includes a BEGIN(INITIAL); command.
+	 *       This is necessary in case the input program being pased has syntax errors that force
+	 *       flex's main state machine to never change to the il_state or the st_state
+	 *       after changing to the body_state.
+	 *       Ths BEGIN(INITIAL) command forces the flex state machine to re-synchronise with 
+	 *       the input stream even in the presence of buggy code!
+	 */
+PROGRAM				return PROGRAM;				/* Keyword */
+END_PROGRAM	BEGIN(INITIAL);	return END_PROGRAM;			/* Keyword */  /* see Note above */
 
 
 	/********************************************/
@@ -1549,21 +1570,28 @@
 	/********************************/
 	/* B 1.7 Configuration elements */
 	/********************************/
-CONFIGURATION		return CONFIGURATION;		/* Keyword */
-END_CONFIGURATION	return END_CONFIGURATION;	/* Keyword */
-TASK			return TASK;			/* Keyword */
-RESOURCE		return RESOURCE;		/* Keyword */
-ON			return ON;			/* Keyword */
-END_RESOURCE		return END_RESOURCE;		/* Keyword */
-VAR_CONFIG		return VAR_CONFIG;		/* Keyword */
-VAR_ACCESS		return VAR_ACCESS;		/* Keyword */
-END_VAR			return END_VAR;			/* Keyword */
-WITH			return WITH;			/* Keyword */
-PROGRAM			return PROGRAM;			/* Keyword */
-RETAIN			return RETAIN;			/* Keyword */
-NON_RETAIN		return NON_RETAIN;		/* Keyword */
-READ_WRITE		return READ_WRITE;		/* Keyword */
-READ_ONLY		return READ_ONLY;		/* Keyword */
+	/* Note: The following END_CONFIGURATION rule will never get to be used, as we have
+	 *       another identical rule above (closer to the rules handling the transitions
+	 *       of the main state machine) that will always execute before this one.
+	 * Note: The following END_CONFIGURATION rule includes a BEGIN(INITIAL); command.
+	 *       This is nt strictly necessary, but I place it here so it follwos the same
+	 *       pattern used in END_FUNCTION, END_PROGRAM, and END_FUNCTION_BLOCK
+	 */
+CONFIGURATION				return CONFIGURATION;		/* Keyword */
+END_CONFIGURATION	BEGIN(INITIAL); return END_CONFIGURATION;	/* Keyword */   /* see 2 Notes above! */
+TASK					return TASK;			/* Keyword */
+RESOURCE				return RESOURCE;		/* Keyword */
+ON					return ON;			/* Keyword */
+END_RESOURCE				return END_RESOURCE;		/* Keyword */
+VAR_CONFIG				return VAR_CONFIG;		/* Keyword */
+VAR_ACCESS				return VAR_ACCESS;		/* Keyword */
+END_VAR					return END_VAR;			/* Keyword */
+WITH					return WITH;			/* Keyword */
+PROGRAM					return PROGRAM;			/* Keyword */
+RETAIN					return RETAIN;			/* Keyword */
+NON_RETAIN				return NON_RETAIN;		/* Keyword */
+READ_WRITE				return READ_WRITE;		/* Keyword */
+READ_ONLY				return READ_ONLY;		/* Keyword */
 
 	/* PRIORITY, SINGLE and INTERVAL are not a keywords, so we only return them when 
 	 * it is explicitly required and we are not expecting any identifiers