stage1_2/iec_flex.ll
changeset 879 c61b2e370181
parent 876 e2c4f6f4abe2
child 880 599e88d12f9a
equal deleted inserted replaced
878:89eb85bab58f 879:c61b2e370181
   175 #define YY_INPUT(buf,result,max_size)  {\
   175 #define YY_INPUT(buf,result,max_size)  {\
   176     result = GetNextChar(buf, max_size);\
   176     result = GetNextChar(buf, max_size);\
   177     if (  result <= 0  )\
   177     if (  result <= 0  )\
   178       result = YY_NULL;\
   178       result = YY_NULL;\
   179     }
   179     }
   180 
       
   181 
       
   182 /* A counter to track the order by which each token is processed.
       
   183  * NOTE: This counter is not exactly linear (i.e., it does not get incremented by 1 for each token).
       
   184  *       i.e.. it may get incremented by more than one between two consecutive tokens.
       
   185  *       This is due to the fact that the counter gets incremented every 'user action' in flex,
       
   186  *       however not every user action will result in a token being passed to bison.
       
   187  *       Nevertheless this is still OK, as we are only interested in the relative
       
   188  *       ordering of tokens...
       
   189  */
       
   190 static long int current_order = 0;
       
   191 
   180 
   192 
   181 
   193 /* Macro that is executed for every action.
   182 /* Macro that is executed for every action.
   194  * We use it to pass the location of the token
   183  * We use it to pass the location of the token
   195  * back to the bison parser...
   184  * back to the bison parser...
   204 	yylloc.last_file = current_filename;					\
   193 	yylloc.last_file = current_filename;					\
   205 	yylloc.last_order = current_order;					\
   194 	yylloc.last_order = current_order;					\
   206 	current_tracking->currentTokenStart = current_tracking->currentChar;	\
   195 	current_tracking->currentTokenStart = current_tracking->currentChar;	\
   207 	current_order++;							\
   196 	current_order++;							\
   208 	}
   197 	}
       
   198 
       
   199 
   209 
   200 
   210 /* Since this lexical parser we defined only works in ASCII based
   201 /* Since this lexical parser we defined only works in ASCII based
   211  * systems, we might as well make sure it is being compiled on
   202  * systems, we might as well make sure it is being compiled on
   212  * one...
   203  * one...
   213  * Lets check a few random characters...
   204  * Lets check a few random characters...
   508 file_include_pragma_end		\"{st_whitespace}"}"
   499 file_include_pragma_end		\"{st_whitespace}"}"
   509 file_include_pragma			{file_include_pragma_beg}{file_include_pragma_filename}{file_include_pragma_end}
   500 file_include_pragma			{file_include_pragma_beg}{file_include_pragma_filename}{file_include_pragma_end}
   510 
   501 
   511 
   502 
   512 %{
   503 %{
   513 #define MAX_INCLUDE_DEPTH 16
   504 
   514 
   505 /* A counter to track the order by which each token is processed.
       
   506  * NOTE: This counter is not exactly linear (i.e., it does not get incremented by 1 for each token).
       
   507  *       i.e.. it may get incremented by more than one between two consecutive tokens.
       
   508  *       This is due to the fact that the counter gets incremented every 'user action' in flex,
       
   509  *       however not every user action will result in a token being passed to bison.
       
   510  *       Nevertheless this is still OK, as we are only interested in the relative
       
   511  *       ordering of tokens...
       
   512  */
       
   513 static long int current_order = 0;
       
   514   
   515 typedef struct {
   515 typedef struct {
   516     int eof;
   516     int eof;
   517     int lineNumber;
   517     int lineNumber;
   518     int currentChar;
   518     int currentChar;
   519     int lineLength;
   519     int lineLength;
   520     int currentTokenStart;
   520     int currentTokenStart;
   521     char *buffer;
   521     char *buffer;
   522     FILE *in_file;
   522     FILE *in_file;
   523   } tracking_t;
   523   } tracking_t;
       
   524 
       
   525 /* A forward declaration of a function defined at the end of this file. */
       
   526 void FreeTracking(tracking_t *tracking);
       
   527 
       
   528 
       
   529 #define MAX_INCLUDE_DEPTH 16
   524 
   530 
   525 typedef struct {
   531 typedef struct {
   526 	  YY_BUFFER_STATE buffer_state;
   532 	  YY_BUFFER_STATE buffer_state;
   527 	  tracking_t *env;
   533 	  tracking_t *env;
   528 	  const char *filename;
   534 	  const char *filename;
   982 			       *       As a corollory, flex can never safely close the main input file, and we must ask
   988 			       *       As a corollory, flex can never safely close the main input file, and we must ask
   983 			       *       bison to close it!
   989 			       *       bison to close it!
   984 			       */
   990 			       */
   985 			  if (include_stack_ptr == 0) {
   991 			  if (include_stack_ptr == 0) {
   986 			      // fclose(yyin);           // Must not do this!!
   992 			      // fclose(yyin);           // Must not do this!!
   987 			      // free(current_tracking); // Must not do this!!
   993 			      // FreeTracking(current_tracking); // Must not do this!!
   988 			      /* yyterminate() terminates the scanner and returns a 0 to the 
   994 			      /* yyterminate() terminates the scanner and returns a 0 to the 
   989 			       * scanner's  caller, indicating "all done".
   995 			       * scanner's  caller, indicating "all done".
   990 			       *	
   996 			       *	
   991 			       * Our syntax parser (written with bison) has the token	
   997 			       * Our syntax parser (written with bison) has the token	
   992 			       * END_OF_INPUT associated to the value 0, so even though
   998 			       * END_OF_INPUT associated to the value 0, so even though
   994 			       * calling yyterminate() is equivalent to doing that. 
  1000 			       * calling yyterminate() is equivalent to doing that. 
   995 			       */ 	
  1001 			       */ 	
   996 			    yyterminate();
  1002 			    yyterminate();
   997 			  } else {
  1003 			  } else {
   998 			    fclose(yyin);
  1004 			    fclose(yyin);
   999 			    free(current_tracking);
  1005 			    FreeTracking(current_tracking);
  1000 			    --include_stack_ptr;
  1006 			    --include_stack_ptr;
  1001 			    yy_delete_buffer(YY_CURRENT_BUFFER);
  1007 			    yy_delete_buffer(YY_CURRENT_BUFFER);
  1002 			    yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
  1008 			    yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
  1003 			    current_tracking = include_stack[include_stack_ptr].env;
  1009 			    current_tracking = include_stack[include_stack_ptr].env;
  1004 			      /* removing constness of char *. This is safe actually,
  1010 			      /* removing constness of char *. This is safe actually,
  1772 
  1778 
  1773 /*************************/
  1779 /*************************/
  1774 /* Tracking Functions... */
  1780 /* Tracking Functions... */
  1775 /*************************/
  1781 /*************************/
  1776 
  1782 
  1777 #define MAX_BUFFER_LENGTH 1000
  1783 #define MAX_LINE_LENGTH 1000
  1778 
  1784 
  1779 tracking_t *GetNewTracking(FILE* in_file) {
  1785 tracking_t *GetNewTracking(FILE* in_file) {
  1780   tracking_t* new_env = new tracking_t;
  1786   tracking_t* new_env = new tracking_t;
  1781   new_env->eof = 0;
  1787   new_env->eof = 0;
  1782   new_env->lineNumber = 0;
  1788   new_env->lineNumber = 0;
  1783   new_env->currentChar = 0;
  1789   new_env->currentChar = 0;
  1784   new_env->lineLength = 0;
  1790   new_env->lineLength = 0;
  1785   new_env->currentTokenStart = 0;
  1791   new_env->currentTokenStart = 0;
  1786   new_env->buffer = (char*)malloc(MAX_BUFFER_LENGTH);
  1792   new_env->buffer = (char*)malloc(MAX_LINE_LENGTH);
  1787   new_env->in_file = in_file;
  1793   new_env->in_file = in_file;
  1788   return new_env;
  1794   return new_env;
       
  1795 }
       
  1796 
       
  1797 
       
  1798 void FreeTracking(tracking_t *tracking) {
       
  1799   free(tracking->buffer);
       
  1800   delete tracking;
  1789 }
  1801 }
  1790 
  1802 
  1791 
  1803 
  1792 /* GetNextChar: reads a character from input */
  1804 /* GetNextChar: reads a character from input */
  1793 int GetNextChar(char *b, int maxBuffer) {
  1805 int GetNextChar(char *b, int maxBuffer) {
  1799   while (  current_tracking->currentChar >= current_tracking->lineLength  ) {
  1811   while (  current_tracking->currentChar >= current_tracking->lineLength  ) {
  1800     current_tracking->currentChar = 0;
  1812     current_tracking->currentChar = 0;
  1801     current_tracking->currentTokenStart = 1;
  1813     current_tracking->currentTokenStart = 1;
  1802     current_tracking->eof = false;
  1814     current_tracking->eof = false;
  1803     
  1815     
  1804     p = fgets(current_tracking->buffer, MAX_BUFFER_LENGTH, current_tracking->in_file);
  1816     p = fgets(current_tracking->buffer, MAX_LINE_LENGTH, current_tracking->in_file);
  1805     if (  p == NULL  ) {
  1817     if (  p == NULL  ) {
  1806       if (  ferror(current_tracking->in_file)  )
  1818       if (  ferror(current_tracking->in_file)  )
  1807         return 0;
  1819         return 0;
  1808       current_tracking->eof = true;
  1820       current_tracking->eof = true;
  1809       return 0;
  1821       return 0;
  1918    * if we return newlines back to the input stream. These newlines will be re-counted
  1930    * if we return newlines back to the input stream. These newlines will be re-counted
  1919    * a second time when they are processed again by flex.
  1931    * a second time when they are processed again by flex.
  1920    * We therefore determine how many newlines are in the text we are returning,
  1932    * We therefore determine how many newlines are in the text we are returning,
  1921    * and decrement the line counter acordingly...
  1933    * and decrement the line counter acordingly...
  1922    */
  1934    */
  1923   /*unsigned int i;
  1935   /*
       
  1936   unsigned int i;
  1924   
  1937   
  1925   for (i = n; i < strlen(yytext); i++)
  1938   for (i = n; i < strlen(yytext); i++)
  1926     if (yytext[i] == '\n')
  1939     if (yytext[i] == '\n')
  1927       current_tracking->lineNumber--;*/
  1940       current_tracking->lineNumber--;
  1928 
  1941   */
  1929   /* now return all the text back to the input stream... */
  1942   /* now return all the text back to the input stream... */
  1930   yyless(n);
  1943   yyless(n);
  1931 }
  1944 }
  1932 
  1945 
  1933 
  1946