stage1_2/iec_flex.ll
changeset 756 634f476cb60f
parent 737 f6bc5230aadd
child 757 f1fc4aa6f0e3
equal deleted inserted replaced
755:7b90dd17f0ba 756:634f476cb60f
   245 void unput_text(unsigned int n);
   245 void unput_text(unsigned int n);
   246 /* return all the text in the current token back to the input stream, 
   246 /* return all the text in the current token back to the input stream, 
   247  * but first return to the stream an additional character to mark the end of the token. 
   247  * but first return to the stream an additional character to mark the end of the token. 
   248  */
   248  */
   249 void unput_and_mark(const char c);
   249 void unput_and_mark(const char c);
       
   250 
       
   251 void include_file(const char *include_filename);
   250 %}
   252 %}
   251 
   253 
   252 
   254 
   253 
   255 
   254 /****************************/
   256 /****************************/
   865 	/* Handle the file includes!     */
   867 	/* Handle the file includes!     */
   866 	/*********************************/
   868 	/*********************************/
   867 <include_beg>{file_include_pragma_beg}	BEGIN(include_filename);
   869 <include_beg>{file_include_pragma_beg}	BEGIN(include_filename);
   868 
   870 
   869 <include_filename>{file_include_pragma_filename}	{
   871 <include_filename>{file_include_pragma_filename}	{
   870 			  /* got the include file name */
   872 			  /* set the internal state variables of lexical analyser to process a new include file */
   871 			  int i;
   873 			  include_file(yytext);
   872 
       
   873 			  if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
       
   874 			    fprintf(stderr, "Includes nested too deeply\n");
       
   875 			    exit( 1 );
       
   876 			  }
       
   877 			  include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER;
       
   878 			  include_stack[include_stack_ptr].env = current_tracking;
       
   879 			  include_stack[include_stack_ptr].filename = current_filename;
       
   880 			  
       
   881 			  for (i = 0, yyin = NULL; (INCLUDE_DIRECTORIES[i] != NULL) && (yyin == NULL); i++) {
       
   882 			    char *full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", yytext);
       
   883 			    if (full_name == NULL) {
       
   884 			      fprintf(stderr, "Out of memory!\n");
       
   885 			      exit( 1 );
       
   886 			    }
       
   887 			    yyin = fopen(full_name, "r");
       
   888 			    free(full_name);
       
   889 			  }
       
   890 
       
   891 			  if (!yyin) {
       
   892 			    fprintf(stderr, "Error opening included file %s\n", yytext);
       
   893 			    exit( 1 );
       
   894 			  }
       
   895 
       
   896 			  current_filename = strdup(yytext);
       
   897 			  current_tracking = GetNewTracking(yyin);
       
   898 			  include_stack_ptr++;
       
   899 
       
   900 			  /* switch input buffer to new file... */
       
   901 			  yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
       
   902 			  /* switch to whatever state was active before the include file */
   874 			  /* switch to whatever state was active before the include file */
   903 			  yy_pop_state();
   875 			  yy_pop_state();
   904 			  /* now process the new file... */
   876 			  /* now process the new file... */
   905 			}
   877 			}
   906 
   878 
   945 			    yy_push_state(include_end);
   917 			    yy_push_state(include_end);
   946 			  }
   918 			  }
   947 			}
   919 			}
   948 
   920 
   949 <include_end>{file_include_pragma_end}	yy_pop_state();
   921 <include_end>{file_include_pragma_end}	yy_pop_state();
       
   922 	/* handle the artificial file includes created by include_string(), which do not end with a '}' */
       
   923 <include_end>.				unput_text(0); yy_pop_state(); 
   950 
   924 
   951 
   925 
   952 	/*********************************/
   926 	/*********************************/
   953 	/* Handle all the state changes! */
   927 	/* Handle all the state changes! */
   954 	/*********************************/
   928 	/*********************************/
  1688   for (i = include_stack_ptr - 1; i >= 0; i--)
  1662   for (i = include_stack_ptr - 1; i >= 0; i--)
  1689     fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].env->lineNumber);
  1663     fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].env->lineNumber);
  1690 }
  1664 }
  1691 
  1665 
  1692 
  1666 
       
  1667 
       
  1668 /* set the internal state variables of lexical analyser to process a new include file */
       
  1669 void handle_include_file_(FILE *filehandle, const char *filename) {
       
  1670   if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
       
  1671     fprintf(stderr, "Includes nested too deeply\n");
       
  1672     exit( 1 );
       
  1673   }
       
  1674   
       
  1675   yyin = filehandle;
       
  1676   
       
  1677   include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER;
       
  1678   include_stack[include_stack_ptr].env = current_tracking;
       
  1679   include_stack[include_stack_ptr].filename = current_filename;
       
  1680   
       
  1681   current_filename = strdup(filename);
       
  1682   current_tracking = GetNewTracking(yyin);
       
  1683   include_stack_ptr++;
       
  1684 
       
  1685   /* switch input buffer to new file... */
       
  1686   yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
       
  1687 }
       
  1688 
       
  1689 
       
  1690 
       
  1691 /* insert the code (in <source_code>) into the source code we are parsing.
       
  1692  * This is done by creating an artificial file with that new source code, and then 'including' the file
       
  1693  */
       
  1694 void include_string(const char *source_code) {
       
  1695   FILE *tmp_file = tmpfile();
       
  1696   
       
  1697   if(tmp_file == NULL) {
       
  1698     perror("Error creating temp file.");
       
  1699     exit(EXIT_FAILURE);
       
  1700   }
       
  1701 
       
  1702   fwrite((void *)source_code, 1, strlen(source_code), tmp_file);
       
  1703   rewind(tmp_file);
       
  1704 
       
  1705   /* now parse the tmp file, by asking flex to handle it as if it had been included with the (*#include ... *) pragma... */
       
  1706   handle_include_file_(tmp_file, "");
       
  1707 //fclose(tmp_file);  /* do NOT close file. It must only be closed when we finish reading from it! */
       
  1708 }
       
  1709 
       
  1710 
       
  1711 
       
  1712 /* Open an include file, and set the internal state variables of lexical analyser to process a new include file */
       
  1713 void include_file(const char *filename) {
       
  1714   FILE *filehandle = NULL;
       
  1715   
       
  1716   for (int i = 0; (INCLUDE_DIRECTORIES[i] != NULL) && (filehandle == NULL); i++) {
       
  1717     char *full_name;
       
  1718     full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", filename);
       
  1719     if (full_name == NULL) {
       
  1720       fprintf(stderr, "Out of memory!\n");
       
  1721       exit( 1 );
       
  1722     }
       
  1723     filehandle = fopen(full_name, "r");
       
  1724     free(full_name);
       
  1725   }
       
  1726 
       
  1727   if (NULL == filehandle) {
       
  1728     fprintf(stderr, "Error opening included file %s\n", filename);
       
  1729     exit( 1 );
       
  1730   }
       
  1731 
       
  1732   /* now process the new file... */
       
  1733   handle_include_file_(filehandle, filename);
       
  1734 }
       
  1735 
       
  1736 
       
  1737 
       
  1738 
       
  1739 
  1693 /* return all the text in the current token back to the input stream, except the first n chars. */
  1740 /* return all the text in the current token back to the input stream, except the first n chars. */
  1694 void unput_text(unsigned int n) {
  1741 void unput_text(unsigned int n) {
  1695   /* it seems that flex has a bug in that it will not correctly count the line numbers
  1742   /* it seems that flex has a bug in that it will not correctly count the line numbers
  1696    * if we return newlines back to the input stream. These newlines will be re-counted
  1743    * if we return newlines back to the input stream. These newlines will be re-counted
  1697    * a second time when they are processed again by flex.
  1744    * a second time when they are processed again by flex.