⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lex.c

📁 gcc-2.95.3 Linux下最常用的C编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Implementation of Fortran lexer   Copyright (C) 1995-1998 Free Software Foundation, Inc.   Contributed by James Craig Burley.This file is part of GNU Fortran.GNU Fortran is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU Fortran is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Fortran; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA02111-1307, USA.  */#include "proj.h"#include "top.h"#include "bad.h"#include "com.h"#include "lex.h"#include "malloc.h"#include "src.h"#if FFECOM_targetCURRENT == FFECOM_targetGCC#include "flags.j"#include "input.j"#include "toplev.j"#include "tree.j"#include "output.j"  /* Must follow tree.j so TREE_CODE is defined! */#endif#ifdef DWARF_DEBUGGING_INFOvoid dwarfout_resume_previous_source_file (register unsigned);void dwarfout_start_new_source_file (register char *);void dwarfout_define (register unsigned, register char *);void dwarfout_undef (register unsigned, register char *);#endif DWARF_DEBUGGING_INFOstatic void ffelex_append_to_token_ (char c);static int ffelex_backslash_ (int c, ffewhereColumnNumber col);static void ffelex_bad_1_ (ffebad errnum, ffewhereLineNumber ln0,			   ffewhereColumnNumber cn0);static void ffelex_bad_2_ (ffebad errnum, ffewhereLineNumber ln0,			   ffewhereColumnNumber cn0, ffewhereLineNumber ln1,			   ffewhereColumnNumber cn1);static void ffelex_bad_here_ (int num, ffewhereLineNumber ln0,			      ffewhereColumnNumber cn0);static void ffelex_finish_statement_ (void);#if FFECOM_targetCURRENT == FFECOM_targetGCCstatic int ffelex_get_directive_line_ (char **text, FILE *finput);static int ffelex_hash_ (FILE *f);#endifstatic ffewhereColumnNumber ffelex_image_char_ (int c,						ffewhereColumnNumber col);static void ffelex_include_ (void);static bool ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col);static bool ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col);static void ffelex_next_line_ (void);static void ffelex_prepare_eos_ (void);static void ffelex_send_token_ (void);static ffelexHandler ffelex_swallow_tokens_ (ffelexToken t);static ffelexToken ffelex_token_new_ (void);/* Pertaining to the geometry of the input file.  *//* Initial size for card image to be allocated.  */#define FFELEX_columnINITIAL_SIZE_ 255/* The card image itself, which grows as source lines get longer.  It   has room for ffelex_card_size_ + 8 characters, and the length of the   current image is ffelex_card_length_.  (The + 8 characters are made   available for easy handling of tabs and such.)  */static char *ffelex_card_image_;static ffewhereColumnNumber ffelex_card_size_;static ffewhereColumnNumber ffelex_card_length_;/* Max width for free-form lines (ISO F90).  */#define FFELEX_FREE_MAX_COLUMNS_ 132/* True if we saw a tab on the current line, as this (currently) means   the line is therefore treated as though final_nontab_column_ were   infinite.  */static bool ffelex_saw_tab_;/* TRUE if current line is known to be erroneous, so don't bother   expanding room for it just to display it.  */static bool ffelex_bad_line_ = FALSE;/* Last column for vanilla, i.e. non-tabbed, line.  Usually 72 or 132. */static ffewhereColumnNumber ffelex_final_nontab_column_;/* Array for quickly deciding what kind of line the current card has,   based on its first character.  */static ffelexType ffelex_first_char_[256];/* Pertaining to file management.  *//* The wf argument of the most recent active ffelex_file_(fixed,free)   function.  */static ffewhereFile ffelex_current_wf_;/* TRUE if an INCLUDE statement can be processed (ffelex_set_include   can be called).  */static bool ffelex_permit_include_;/* TRUE if an INCLUDE statement is pending (ffelex_set_include has been   called).  */static bool ffelex_set_include_;/* Information on the pending INCLUDE file.  */static FILE *ffelex_include_file_;static bool ffelex_include_free_form_;static ffewhereFile ffelex_include_wherefile_;/* Current master line count.  */static ffewhereLineNumber ffelex_linecount_current_;/* Next master line count.  */static ffewhereLineNumber ffelex_linecount_next_;/* ffewhere info on the latest (currently active) line read from the   active source file.  */static ffewhereLine ffelex_current_wl_;static ffewhereColumn ffelex_current_wc_;/* Pertaining to tokens in general.  *//* Initial capacity for text in a CHARACTER/HOLLERITH/NAME/NAMES/NUMBER   token.  */#define FFELEX_columnTOKEN_SIZE_ 63#if FFELEX_columnTOKEN_SIZE_ < FFEWHERE_indexMAX#error "token size too small!"#endif/* Current token being lexed.  */static ffelexToken ffelex_token_;/* Handler for current token.  */static ffelexHandler ffelex_handler_;/* TRUE if fixed-form lexer is to generate NAMES instead of NAME tokens.  */static bool ffelex_names_;/* TRUE if both lexers are to generate NAMES instead of NAME tokens.  */static bool ffelex_names_pure_;/* TRUE if 0-9 starts a NAME token instead of NUMBER, for parsing hex   numbers.  */static bool ffelex_hexnum_;/* For ffelex_swallow_tokens().  */static ffelexHandler ffelex_eos_handler_;/* Number of tokens sent since last EOS or beginning of input file   (include INCLUDEd files).  */static unsigned long int ffelex_number_of_tokens_;/* Number of labels sent (as NUMBER tokens) since last reset of   ffelex_number_of_tokens_ to 0, should be 0 or 1 in most cases.   (Fixed-form source only.)  */static unsigned long int ffelex_label_tokens_;/* Metering for token management, to catch token-memory leaks.  */static long int ffelex_total_tokens_ = 0;static long int ffelex_old_total_tokens_ = 1;static long int ffelex_token_nextid_ = 0;/* Pertaining to lexing CHARACTER and HOLLERITH tokens.  *//* >0 if a Hollerith constant of that length might be in mid-lex, used   when the next character seen is 'H' or 'h' to enter HOLLERITH lexing   mode (see ffelex_raw_mode_).  */static long int ffelex_expecting_hollerith_;/* -3: Backslash (escape) sequence being lexed in CHARACTER.   -2: Possible closing apostrophe/quote seen in CHARACTER.   -1: Lexing CHARACTER.    0: Not lexing CHARACTER or HOLLERITH.   >0: Lexing HOLLERITH, value is # chars remaining to expect.  */static long int ffelex_raw_mode_;/* When lexing CHARACTER, open quote/apostrophe (either ' or ").  */static char ffelex_raw_char_;/* TRUE when backslash processing had to use most recent character   to finish its state engine, but that character is not part of   the backslash sequence, so must be reconsidered as a "normal"   character in CHARACTER/HOLLERITH lexing.  */static bool ffelex_backslash_reconsider_ = FALSE;/* Characters preread before lexing happened (might include EOF).  */static int *ffelex_kludge_chars_ = NULL;/* Doing the kludge processing, so not initialized yet.  */static bool ffelex_kludge_flag_ = FALSE;/* The beginning of a (possible) CHARACTER/HOLLERITH token.  */static ffewhereLine ffelex_raw_where_line_;static ffewhereColumn ffelex_raw_where_col_;/* Call this to append another character to the current token.	If it isn't   currently big enough for it, it will be enlarged.  The current token   must be a CHARACTER, HOLLERITH, NAME, NAMES, or NUMBER.  */static voidffelex_append_to_token_ (char c){  if (ffelex_token_->text == NULL)    {      ffelex_token_->text	= malloc_new_ksr (malloc_pool_image (), "FFELEX token text",			  FFELEX_columnTOKEN_SIZE_ + 1);      ffelex_token_->size = FFELEX_columnTOKEN_SIZE_;      ffelex_token_->length = 0;    }  else if (ffelex_token_->length >= ffelex_token_->size)    {      ffelex_token_->text	= malloc_resize_ksr (malloc_pool_image (),			     ffelex_token_->text,			     (ffelex_token_->size << 1) + 1,			     ffelex_token_->size + 1);      ffelex_token_->size <<= 1;      assert (ffelex_token_->length < ffelex_token_->size);    }#ifdef MAP_CHARACTERSorry, MAP_CHARACTER is not going to work as expected in GNU Fortran,please contact fortran@gnu.org if you wish to fund work toport g77 to non-ASCII machines.#endif  ffelex_token_->text[ffelex_token_->length++] = c;}/* Do backslash (escape) processing for a CHARACTER/HOLLERITH token   being lexed.  */static intffelex_backslash_ (int c, ffewhereColumnNumber col){  static int state = 0;  static unsigned int count;  static int code;  static unsigned int firstdig = 0;  static int nonnull;  static ffewhereLineNumber line;  static ffewhereColumnNumber column;  /* See gcc/c-lex.c readescape() for a straightforward version     of this state engine for handling backslashes in character/     hollerith constants.  */#define wide_flag 0#define warn_traditional 0#define flag_traditional 0  switch (state)    {    case 0:      if ((c == '\\')	  && (ffelex_raw_mode_ != 0)	  && ffe_is_backslash ())	{	  state = 1;	  column = col + 1;	  line = ffelex_linecount_current_;	  return EOF;	}      return c;    case 1:      state = 0;		/* Assume simple case. */      switch (c)	{	case 'x':	  if (warn_traditional)	    {	      ffebad_start_msg_lex ("The meaning of `\\x' (at %0) varies with -traditional",				    FFEBAD_severityWARNING);	      ffelex_bad_here_ (0, line, column);	      ffebad_finish ();	    }	  if (flag_traditional)	    return c;	  code = 0;	  count = 0;	  nonnull = 0;	  state = 2;	  return EOF;	case '0':  case '1':  case '2':  case '3':  case '4':	case '5':  case '6':  case '7':	  code = c - '0';	  count = 1;	  state = 3;	  return EOF;	case '\\': case '\'': case '"':	  return c;#if 0	/* Inappropriate for Fortran. */	case '\n':	  ffelex_next_line_ ();	  *ignore_ptr = 1;	  return 0;#endif	case 'n':	  return TARGET_NEWLINE;	case 't':	  return TARGET_TAB;	case 'r':	  return TARGET_CR;	case 'f':	  return TARGET_FF;	case 'b':	  return TARGET_BS;	case 'a':	  if (warn_traditional)	    {	      ffebad_start_msg_lex ("The meaning of `\\a' (at %0) varies with -traditional",				    FFEBAD_severityWARNING);	      ffelex_bad_here_ (0, line, column);	      ffebad_finish ();	    }	  if (flag_traditional)	    return c;	  return TARGET_BELL;	case 'v':#if 0 /* Vertical tab is present in common usage compilers.  */	  if (flag_traditional)	    return c;#endif	  return TARGET_VT;	case 'e':	case 'E':	case '(':	case '{':	case '[':	case '%':	  if (pedantic)	    {	      char m[2];	      m[0] = c;	      m[1] = '\0';	      ffebad_start_msg_lex ("Non-ANSI-C-standard escape sequence `\\%A' at %0",				    FFEBAD_severityPEDANTIC);	      ffelex_bad_here_ (0, line, column);	      ffebad_string (m);	      ffebad_finish ();	    }	  return (c == 'E' || c == 'e') ? 033 : c;	case '?':	  return c;	default:	  if (c >= 040 && c < 0177)	    {	      char m[2];	      m[0] = c;	      m[1] = '\0';	      ffebad_start_msg_lex ("Unknown escape sequence `\\%A' at %0",				    FFEBAD_severityPEDANTIC);	      ffelex_bad_here_ (0, line, column);	      ffebad_string (m);	      ffebad_finish ();	    }	  else if (c == EOF)	    {	      ffebad_start_msg_lex ("Unterminated escape sequence `\\' at %0",				    FFEBAD_severityPEDANTIC);	      ffelex_bad_here_ (0, line, column);	      ffebad_finish ();	    }	  else	    {	      char m[20];	      sprintf (&m[0], "%x", c);	      ffebad_start_msg_lex ("Unknown escape sequence `\\' followed by char code 0x%A at %0",				    FFEBAD_severityPEDANTIC);	      ffelex_bad_here_ (0, line, column);	      ffebad_string (m);	      ffebad_finish ();	    }	}      return c;    case 2:      if ((c >= 'a' && c <= 'f')	  || (c >= 'A' && c <= 'F')	  || (c >= '0' && c <= '9'))	{	  code *= 16;	  if (c >= 'a' && c <= 'f')	    code += c - 'a' + 10;	  if (c >= 'A' && c <= 'F')	    code += c - 'A' + 10;	  if (c >= '0' && c <= '9')	    code += c - '0';	  if (code != 0 || count != 0)	    {	      if (count == 0)		firstdig = code;	      count++;	    }	  nonnull = 1;	  return EOF;	}      state = 0;      if (! nonnull)	{	  ffebad_start_msg_lex ("\\x used at %0 with no following hex digits",				FFEBAD_severityFATAL);	  ffelex_bad_here_ (0, line, column);	  ffebad_finish ();	}      else if (count == 0)	/* Digits are all 0's.  Ok.  */	;      else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)	       || (count > 1		   && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))		       <= (int) firstdig)))	{	  ffebad_start_msg_lex ("Hex escape at %0 out of range",				FFEBAD_severityPEDANTIC);	  ffelex_bad_here_ (0, line, column);	  ffebad_finish ();	}      break;    case 3:      if ((c <= '7') && (c >= '0') && (count++ < 3))	{	  code = (code * 8) + (c - '0');	  return EOF;	}      state = 0;      break;    default:      assert ("bad backslash state" == NULL);      abort ();    }  /* Come here when code has a built character, and c is the next     character that might (or might not) be the next one in the constant.  */  /* Don't bother doing this check for each character going into     CHARACTER or HOLLERITH constants, just the escaped-value ones.     gcc apparently checks every single character, which seems     like it'd be kinda slow and not worth doing anyway.  */  if (!wide_flag      && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT      && code >= (1 << TYPE_PRECISION (char_type_node)))    {      ffebad_start_msg_lex ("Escape sequence at %0 out of range for character",			    FFEBAD_severityFATAL);      ffelex_bad_here_ (0, line, column);      ffebad_finish ();    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -