stage1_2/iec.flex
changeset 136 32bd7ef40897
parent 131 f55ef301e14c
child 151 3b898fb11e73
equal deleted inserted replaced
135:0f3f6714b938 136:32bd7ef40897
   153  * track of the locations, in order to give
   153  * track of the locations, in order to give
   154  * more meaningful error messages!
   154  * more meaningful error messages!
   155  */
   155  */
   156 extern YYLTYPE yylloc;
   156 extern YYLTYPE yylloc;
   157 
   157 
       
   158 #define YY_INPUT(buf,result,max_size)  {\
       
   159     result = GetNextChar(buf, max_size);\
       
   160     if (  result <= 0  )\
       
   161       result = YY_NULL;\
       
   162     }
       
   163 
   158 /* Macro that is executed for every action.
   164 /* Macro that is executed for every action.
   159  * We use it to pass the location of the token
   165  * We use it to pass the location of the token
   160  * back to the bison parser...
   166  * back to the bison parser...
   161  */
   167  */
   162 #define YY_USER_ACTION { 					\
   168 #define YY_USER_ACTION {\
   163 	yylloc.first_line = yylloc.last_line = yylineno;	\
   169 	  yylloc.first_line = current_tracking->lineNumber;\
   164 	yylloc.first_column = yylloc.last_column = 0;		\
   170   	yylloc.first_column = current_tracking->currentTokenStart;\
       
   171   	yylloc.last_line = current_tracking->lineNumber;\
       
   172   	yylloc.last_column = current_tracking->currentChar - 1;\
       
   173   	current_tracking->currentTokenStart = current_tracking->currentChar;\
   165 	}
   174 	}
   166 
   175 
   167 
   176 
   168 /* Since this lexical parser we defined only works in ASCII based
   177 /* Since this lexical parser we defined only works in ASCII based
   169  * systems, we might as well make sure it is being compiled on
   178  * systems, we might as well make sure it is being compiled on
   402 %{
   411 %{
   403 #define MAX_INCLUDE_DEPTH 16
   412 #define MAX_INCLUDE_DEPTH 16
   404 
   413 
   405 typedef struct {
   414 typedef struct {
   406 	  YY_BUFFER_STATE buffer_state;
   415 	  YY_BUFFER_STATE buffer_state;
   407 	  int lineno;
   416 	  tracking_t* env;
   408 	  const char *filename;
   417 	  const char *filename;
   409 	} include_stack_t;
   418 	} include_stack_t;
   410 
   419 
       
   420 tracking_t* current_tracking;
   411 include_stack_t include_stack[MAX_INCLUDE_DEPTH];
   421 include_stack_t include_stack[MAX_INCLUDE_DEPTH];
   412 int include_stack_ptr = 0;
   422 int include_stack_ptr = 0;
   413 
   423 
   414 const char *INCLUDE_DIRECTORIES[] = {
   424 const char *INCLUDE_DIRECTORIES[] = {
   415 	DEFAULT_LIBDIR,
   425 	DEFAULT_LIBDIR,
   522 letter		[A-Za-z]
   532 letter		[A-Za-z]
   523 digit		[0-9]
   533 digit		[0-9]
   524 octal_digit	[0-7]
   534 octal_digit	[0-7]
   525 hex_digit	{digit}|[A-F]
   535 hex_digit	{digit}|[A-F]
   526 identifier	({letter}|(_({letter}|{digit})))((_?({letter}|{digit}))*)
   536 identifier	({letter}|(_({letter}|{digit})))((_?({letter}|{digit}))*)
   527 
   537 invalid_identifier ({letter}|{digit}|_)*
   528 
   538 
   529 /*******************/
   539 /*******************/
   530 /* B.1.2 Constants */
   540 /* B.1.2 Constants */
   531 /*******************/
   541 /*******************/
   532 
   542 
   707 
   717 
   708 	if (get_pop_state()) {
   718 	if (get_pop_state()) {
   709 	  yy_pop_state();
   719 	  yy_pop_state();
   710 	  rst_pop_state();
   720 	  rst_pop_state();
   711 	}
   721 	}
   712 
       
   713 
   722 
   714 	/***************************/
   723 	/***************************/
   715 	/* Handle the pragmas!     */
   724 	/* Handle the pragmas!     */
   716 	/***************************/
   725 	/***************************/
   717 
   726 
   743 
   752 
   744 			  if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
   753 			  if (include_stack_ptr >= MAX_INCLUDE_DEPTH) {
   745 			    fprintf(stderr, "Includes nested too deeply\n");
   754 			    fprintf(stderr, "Includes nested too deeply\n");
   746 			    exit( 1 );
   755 			    exit( 1 );
   747 			  }
   756 			  }
   748 
   757         include_stack[include_stack_ptr].buffer_state = YY_CURRENT_BUFFER;
   749 			  (include_stack[include_stack_ptr]).buffer_state = YY_CURRENT_BUFFER;
   758         include_stack[include_stack_ptr].env = current_tracking;
   750 			  (include_stack[include_stack_ptr]).lineno = yylineno;
   759         include_stack[include_stack_ptr].filename = current_filename;
   751 			  (include_stack[include_stack_ptr]).filename = current_filename;
   760 			  
   752 			  include_stack_ptr++;
       
   753 			  yylineno = 1;
       
   754 			  current_filename = strdup(yytext);
       
   755 
       
   756 			  for (i = 0, yyin = NULL; (INCLUDE_DIRECTORIES[i] != NULL) && (yyin == NULL); i++) {
   761 			  for (i = 0, yyin = NULL; (INCLUDE_DIRECTORIES[i] != NULL) && (yyin == NULL); i++) {
   757 			    char *full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", yytext);
   762 			    char *full_name = strdup3(INCLUDE_DIRECTORIES[i], "/", yytext);
   758 			    if (full_name == NULL) {
   763 			    if (full_name == NULL) {
   759 			      fprintf(stderr, "Out of memory!\n");
   764 			      fprintf(stderr, "Out of memory!\n");
   760 			      exit( 1 );
   765 			      exit( 1 );
   766 			  if (!yyin) {
   771 			  if (!yyin) {
   767 			    fprintf(stderr, "Error opening included file %s\n", yytext);
   772 			    fprintf(stderr, "Error opening included file %s\n", yytext);
   768 			    exit( 1 );
   773 			    exit( 1 );
   769 			  }
   774 			  }
   770 
   775 
       
   776 			  current_filename = strdup(yytext);
       
   777 			  current_tracking = GetNewTracking(yyin);
       
   778 			  include_stack_ptr++;
       
   779 
   771 			  /* switch input buffer to new file... */
   780 			  /* switch input buffer to new file... */
   772 			  yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
   781 			  yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
   773 			  /* switch to whatever state was active before the include file */
   782 			  /* switch to whatever state was active before the include file */
   774 			  yy_pop_state();
   783 			  yy_pop_state();
   775 			  /* now process the new file... */
   784 			  /* now process the new file... */
   782 			       *       If we have finished parsing the main file, then we
   791 			       *       If we have finished parsing the main file, then we
   783 			       *       must leave include_stack_ptr at 0, in case the 
   792 			       *       must leave include_stack_ptr at 0, in case the 
   784 			       *       parser is called once again with a new file.
   793 			       *       parser is called once again with a new file.
   785 			       *       (In fact, we currently do just that!)
   794 			       *       (In fact, we currently do just that!)
   786 			       */
   795 			       */
       
   796 			  free(current_tracking);
   787 			  if (include_stack_ptr == 0) {
   797 			  if (include_stack_ptr == 0) {
   788 			      /* yyterminate() terminates the scanner and returns a 0 to the 
   798 			      /* yyterminate() terminates the scanner and returns a 0 to the 
   789 			       * scanner's  caller, indicating "all done".
   799 			       * scanner's  caller, indicating "all done".
   790 			       *	
   800 			       *	
   791 			       * Our syntax parser (written with bison) has the token	
   801 			       * Our syntax parser (written with bison) has the token	
   794 			       * calling yyterminate() is equivalent to doing that. 
   804 			       * calling yyterminate() is equivalent to doing that. 
   795 			       */ 	
   805 			       */ 	
   796 			    yyterminate();
   806 			    yyterminate();
   797 			  }      
   807 			  }      
   798  else {
   808  else {
   799 			    --include_stack_ptr;	
   809 			    --include_stack_ptr;
   800 			    yy_delete_buffer(YY_CURRENT_BUFFER);
   810 			    yy_delete_buffer(YY_CURRENT_BUFFER);
   801 			    yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
   811 			    yy_switch_to_buffer((include_stack[include_stack_ptr]).buffer_state);
   802 			    yylineno = include_stack[include_stack_ptr].lineno;
   812 			    current_tracking = include_stack[include_stack_ptr].env;
   803 			      /* removing constness of char *. This is safe actually,
   813 			      /* removing constness of char *. This is safe actually,
   804 			       * since the only real const char * that is stored on the stack is
   814 			       * since the only real const char * that is stored on the stack is
   805 			       * the first one (i.e. the one that gets stored in include_stack[0],
   815 			       * the first one (i.e. the one that gets stored in include_stack[0],
   806 			       * which is never free'd!
   816 			       * which is never free'd!
   807 			       */
   817 			       */
  1472 
  1482 
  1473 	/* do the single character tokens...
  1483 	/* do the single character tokens...
  1474 	 *
  1484 	 *
  1475 	 *  e.g.:  ':'  '('  ')'  '+'  '*'  ...
  1485 	 *  e.g.:  ':'  '('  ')'  '+'  '*'  ...
  1476 	 */
  1486 	 */
       
  1487 {invalid_identifier} return INVALID_IDENTIFIER;
  1477 .	{return yytext[0];}
  1488 .	{return yytext[0];}
  1478 
  1489 
  1479 
  1490 
  1480 %%
  1491 %%
  1481 
  1492 
  1489   int i;
  1500   int i;
  1490 
  1501 
  1491   if ((include_stack_ptr - 1) >= 0)
  1502   if ((include_stack_ptr - 1) >= 0)
  1492     fprintf (stderr, "in file "); 
  1503     fprintf (stderr, "in file "); 
  1493   for (i = include_stack_ptr - 1; i >= 0; i--)
  1504   for (i = include_stack_ptr - 1; i >= 0; i--)
  1494     fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].lineno);
  1505     fprintf (stderr, "included from file %s:%d\n", include_stack[i].filename, include_stack[i].env->lineNumber);
  1495 }
  1506 }
  1496 
  1507 
  1497 
  1508 
  1498 /* return all the text in the current token back to the input stream, except the first n chars. */
  1509 /* return all the text in the current token back to the input stream, except the first n chars. */
  1499 void unput_text(unsigned int n) {
  1510 void unput_text(unsigned int n) {
  1501    * if we return newlines back to the input stream. These newlines will be re-counted
  1512    * if we return newlines back to the input stream. These newlines will be re-counted
  1502    * a second time when they are processed again by flex.
  1513    * a second time when they are processed again by flex.
  1503    * We therefore determine how many newlines are in the text we are returning,
  1514    * We therefore determine how many newlines are in the text we are returning,
  1504    * and decrement the line counter acordingly...
  1515    * and decrement the line counter acordingly...
  1505    */
  1516    */
  1506   unsigned int i;
  1517   /*unsigned int i;
  1507   unsigned int line_number = 0;
  1518   
  1508   int before_yylineno = yylineno;
       
  1509 
       
  1510   for (i = n; i < strlen(yytext); i++)
  1519   for (i = n; i < strlen(yytext); i++)
  1511     if (yytext[i] == '\n')
  1520     if (yytext[i] == '\n')
  1512       line_number++;
  1521       current_tracking->lineNumber--;*/
  1513 
  1522 
  1514   /* now return all the text back to the input stream... */
  1523   /* now return all the text back to the input stream... */
  1515   yyless(n);
  1524   yyless(n);
  1516   
       
  1517   if (line_number > 0 && before_yylineno == yylineno)
       
  1518     yylineno = yylineno - line_number;
       
  1519 }
  1525 }
  1520 
  1526 
  1521 
  1527 
  1522 /* Called by flex when it reaches the end-of-file */
  1528 /* Called by flex when it reaches the end-of-file */
  1523 int yywrap(void)
  1529 int yywrap(void)
  1562 
  1568 
  1563 int main(int argc, char **argv) {
  1569 int main(int argc, char **argv) {
  1564 
  1570 
  1565   FILE *in_file;
  1571   FILE *in_file;
  1566   int res;
  1572   int res;
  1567 
  1573 	
  1568   if (argc == 1) {
  1574   if (argc == 1) {
  1569     /* Work as an interactive (command line) parser... */
  1575     /* Work as an interactive (command line) parser... */
  1570     while((res=yylex()))
  1576     while((res=yylex()))
  1571       fprintf(stderr, "(line %d)token: %d\n", yylineno, res);
  1577       fprintf(stderr, "(line %d)token: %d\n", yylineno, res);
  1572   } else {
  1578   } else {
  1584     while(1) {
  1590     while(1) {
  1585       res=yylex();
  1591       res=yylex();
  1586       fprintf(stderr, "(line %d)token: %d (%s)\n", yylineno, res, yylval.ID);
  1592       fprintf(stderr, "(line %d)token: %d (%s)\n", yylineno, res, yylval.ID);
  1587     }
  1593     }
  1588   }
  1594   }
  1589 
  1595 	
  1590   return 0;
  1596 	return 0;
  1591 
  1597 
  1592 }
  1598 }
  1593 #endif
  1599 #endif