Allow bison to ask for an END_OF_INPUT token multiple times!
authormjsousa
Sat, 01 Dec 2012 11:30:16 +0000
changeset 761 7b52623a2f37
parent 760 d736dc9e9e51
child 762 a3d917474ae4
child 763 2779f4a5f305
Allow bison to ask for an END_OF_INPUT token multiple times!
stage1_2/iec_bison.yy
stage1_2/iec_flex.ll
stage1_2/stage1_2_priv.hh
--- a/stage1_2/iec_bison.yy	Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/iec_bison.yy	Sat Dec 01 11:30:16 2012 +0000
@@ -8265,8 +8265,9 @@
     fprintf (stderr, "Out of memory. Bailing out!\n");
     return -1;
   }
-
-  if(parse_file(libfilename) < 0) {
+  
+  FILE *libfile = NULL;
+  if((libfile = parse_file(libfilename)) == NULL) {
     char *errmsg = strdup2("Error opening library file ", libfilename);
     perror(errmsg);
     free(errmsg);
@@ -8279,7 +8280,8 @@
   full_token_loc = full_token_loc_;
   if (yyparse() != 0)
       ERROR;
-
+  fclose(libfile);
+      
   if (yynerrs > 0) {
     fprintf (stderr, "\n%d error(s) found in %s. Bailing out!\n", yynerrs /* global variable */, libfilename);
     ERROR;
@@ -8299,8 +8301,8 @@
   #if YYDEBUG
     yydebug = 1;
   #endif
-
-  if(parse_file(filename) < 0) {
+  FILE *mainfile = NULL;
+  if ((mainfile = parse_file(filename)) == NULL) {
     char *errmsg = strdup2("Error opening main file ", filename);
     perror(errmsg);
     free(errmsg);
@@ -8315,7 +8317,8 @@
     fprintf (stderr, "\nParsing failed because of too many consecutive syntax errors. Bailing out!\n");
     exit(EXIT_FAILURE);
   }
-
+  fclose(mainfile);
+  
   if (yynerrs > 0) {
     fprintf (stderr, "\n%d error(s) found. Bailing out!\n", yynerrs /* global variable */);
     exit(EXIT_FAILURE);
--- a/stage1_2/iec_flex.ll	Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/iec_flex.ll	Sat Dec 01 11:30:16 2012 +0000
@@ -884,17 +884,28 @@
 			}
 
 
-<<EOF>>			{     /* NOTE: We must not change the value of include_stack_ptr
-			       *       just yet. We must only decrement it if we are NOT
-			       *       at the end of the main file.
-			       *       If we have finished parsing the main file, then we
-			       *       must leave include_stack_ptr at 0, in case the 
-			       *       parser is called once again with a new file.
-			       *       (In fact, we currently do just that!)
+<<EOF>>			{     /* NOTE: Currently bison is incorrectly using END_OF_INPUT in many rules
+			       *       when checking for syntax errors in the input source code.
+			       *       This means that in reality flex will be asked to carry on reading the input
+			       *       even after it has reached the end of all (including the main) input files.
+			       *       In other owrds, we will be called to return more tokens, even after we have
+			       *       already returned an END_OF_INPUT token. In this case, we must carry on returning
+			       *       more END_OF_INPUT tokens.
+			       * 
+			       *       However, in the above case we will be asked to carry on reading more tokens 
+			       *       from the main input file, after we have reached the end. For this to work
+			       *       correctly, we cannot close the main input file!
+			       * 
+			       *       This is why we WILL be called with include_stack_ptr == 0 multiple times,
+			       *       and why we must handle it as a special case
+			       *       that leaves the include_stack_ptr unchanged, and returns END_OF_INPUT once again.
+			       * 
+			       *       As a corollory, flex can never safely close the main input file, and we must ask
+			       *       bison to close it!
 			       */
-			  fclose(yyin);
-			  free(current_tracking);
 			  if (include_stack_ptr == 0) {
+			      // fclose(yyin);           // Must not do this!!
+			      // free(current_tracking); // Must not do this!!
 			      /* yyterminate() terminates the scanner and returns a 0 to the 
 			       * scanner's  caller, indicating "all done".
 			       *	
@@ -905,6 +916,8 @@
 			       */ 	
 			    yyterminate();
 			  } else {
+			    fclose(yyin);
+			    free(current_tracking);
 			    --include_stack_ptr;
 			    yy_delete_buffer(YY_CURRENT_BUFFER);
 			    yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
@@ -1864,18 +1877,18 @@
 /* Tell flex which file to parse. This function will not imediately start parsing the file.
  * To parse the file, you then need to call yyparse()
  *
- * Returns -1 on error opening the file (and a valid errno), or 0 on success.
- */
-int parse_file(const char *filename) {
+ * Returns NULL on error opening the file (and a valid errno), or 0 on success.
+ * Caller must close the file!
+ */
+FILE *parse_file(const char *filename) {
   FILE *filehandle = NULL;
 
-  if((filehandle = fopen(filename, "r")) == NULL) 
-    return -1;
-
-  yyin = filehandle;
-  current_filename = strdup(filename);
-  current_tracking = GetNewTracking(yyin);
-  return 0;
+  if((filehandle = fopen(filename, "r")) != NULL) {
+    yyin = filehandle;
+    current_filename = strdup(filename);
+    current_tracking = GetNewTracking(yyin);
+  }
+  return filehandle;
 }
 
 
--- a/stage1_2/stage1_2_priv.hh	Sat Dec 01 11:27:48 2012 +0000
+++ b/stage1_2/stage1_2_priv.hh	Sat Dec 01 11:30:16 2012 +0000
@@ -126,10 +126,10 @@
 /* Tell flex which file to parse. This function will not imediately start parsing the file.
  * To parse the file, you then need to call yyparse()
  *
- * Returns -1 on error opening the file (and a valid errno), or 0 on success.
- */
-int parse_file(const char *filename);
-
+ * Returns NULL on error opening the file (and a valid errno), or 0 on success.
+ * Caller must close the file!
+ */
+FILE *parse_file(const char *filename);