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 |